2005-05-24 Paolo Bonzini <bonzini@gnu.org>
[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
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:
6b6e92f4 243 arch_mask = m68000|m68881|m68851;
252b5132
RH
244 break;
245 case bfd_mach_m68008:
6b6e92f4 246 arch_mask = m68008|m68881|m68851;
252b5132
RH
247 break;
248 case bfd_mach_m68010:
6b6e92f4 249 arch_mask = m68010|m68881|m68851;
252b5132
RH
250 break;
251 case bfd_mach_m68020:
6b6e92f4 252 arch_mask = m68020|m68881|m68851;
252b5132
RH
253 break;
254 case bfd_mach_m68030:
6b6e92f4 255 arch_mask = m68030|m68881|m68851;
252b5132
RH
256 break;
257 case bfd_mach_m68040:
6b6e92f4 258 arch_mask = m68040|m68881|m68851;
252b5132
RH
259 break;
260 case bfd_mach_m68060:
6b6e92f4 261 arch_mask = m68060|m68881|m68851;
252b5132 262 break;
9d29e1b3 263 case bfd_mach_mcf5200:
6b6e92f4 264 arch_mask = mcfisa_a;
9d29e1b3 265 break;
6b6e92f4 266 case bfd_mach_mcf521x:
3e602632 267 case bfd_mach_mcf528x:
6b6e92f4 268 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp|mcfemac;
3e602632 269 break;
9d29e1b3 270 case bfd_mach_mcf5206e:
6b6e92f4
NC
271 arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
272 break;
273 case bfd_mach_mcf5249:
274 arch_mask = mcfisa_a|mcfhwdiv|mcfemac;
9d29e1b3
NC
275 break;
276 case bfd_mach_mcf5307:
6b6e92f4 277 arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
9d29e1b3
NC
278 break;
279 case bfd_mach_mcf5407:
6b6e92f4 280 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac;
fd99574b 281 break;
6b6e92f4
NC
282 case bfd_mach_mcf547x:
283 case bfd_mach_mcf548x:
fd99574b 284 case bfd_mach_mcfv4e:
6b6e92f4 285 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac;
9d29e1b3 286 break;
252b5132
RH
287 }
288
252b5132
RH
289 bestmask = 0;
290 FETCH_DATA (info, buffer + 2);
291 major_opcode = (buffer[0] >> 4) & 15;
292 for (i = 0; i < numopcodes[major_opcode]; i++)
293 {
294 const struct m68k_opcode *opc = opcodes[major_opcode][i];
295 unsigned long opcode = opc->opcode;
296 unsigned long match = opc->match;
297
298 if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
299 && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
300 /* Only fetch the next two bytes if we need to. */
301 && (((0xffff & match) == 0)
302 ||
303 (FETCH_DATA (info, buffer + 4)
304 && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
305 && ((0xff & buffer[3] & match) == (0xff & opcode)))
306 )
307 && (opc->arch & arch_mask) != 0)
308 {
309 /* Don't use for printout the variants of divul and divsl
310 that have the same register number in two places.
311 The more general variants will match instead. */
312 for (d = opc->args; *d; d += 2)
313 if (d[1] == 'D')
314 break;
315
316 /* Don't use for printout the variants of most floating
317 point coprocessor instructions which use the same
318 register number in two places, as above. */
319 if (*d == '\0')
320 for (d = opc->args; *d; d += 2)
321 if (d[1] == 't')
322 break;
323
324 /* Don't match fmovel with more than one register; wait for
325 fmoveml. */
326 if (*d == '\0')
327 {
328 for (d = opc->args; *d; d += 2)
329 {
330 if (d[0] == 's' && d[1] == '8')
331 {
332 int val;
333
334 val = fetch_arg (buffer, d[1], 3, info);
335 if ((val & (val - 1)) != 0)
336 break;
337 }
338 }
339 }
340
341 if (*d == '\0' && match > bestmask)
342 {
343 best = opc;
344 bestmask = match;
345 }
346 }
347 }
348
9d29e1b3 349 if (best == NULL)
252b5132
RH
350 goto invalid;
351
352 /* Point at first word of argument data,
353 and at descriptor for first argument. */
354 p = buffer + 2;
3e602632 355
252b5132
RH
356 /* Figure out how long the fixed-size portion of the instruction is.
357 The only place this is stored in the opcode table is
358 in the arguments--look for arguments which specify fields in the 2nd
359 or 3rd words of the instruction. */
360 for (d = best->args; *d; d += 2)
361 {
362 /* I don't think it is necessary to be checking d[0] here; I suspect
363 all this could be moved to the case statement below. */
364 if (d[0] == '#')
365 {
366 if (d[1] == 'l' && p - buffer < 6)
367 p = buffer + 6;
ec22bdda 368 else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8')
252b5132
RH
369 p = buffer + 4;
370 }
371 if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
372 p = buffer + 4;
373 switch (d[1])
374 {
375 case '1':
376 case '2':
377 case '3':
378 case '7':
379 case '8':
380 case '9':
381 case 'i':
382 if (p - buffer < 4)
383 p = buffer + 4;
384 break;
385 case '4':
386 case '5':
387 case '6':
388 if (p - buffer < 6)
389 p = buffer + 6;
390 break;
391 default:
392 break;
393 }
394 }
395
396 /* pflusha is an exceptions. It takes no arguments but is two words
397 long. Recognize it by looking at the lower 16 bits of the mask. */
398 if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
399 p = buffer + 4;
400
401 /* lpstop is another exception. It takes a one word argument but is
402 three words long. */
403 if (p - buffer < 6
404 && (best->match & 0xffff) == 0xffff
405 && best->args[0] == '#'
406 && best->args[1] == 'w')
407 {
408 /* Copy the one word argument into the usual location for a one
409 word argument, to simplify printing it. We can get away with
410 this because we know exactly what the second word is, and we
411 aren't going to print anything based on it. */
412 p = buffer + 6;
413 FETCH_DATA (info, p);
414 buffer[2] = buffer[4];
415 buffer[3] = buffer[5];
416 }
417
418 FETCH_DATA (info, p);
3e602632 419
252b5132
RH
420 d = best->args;
421
3e602632 422 /* We scan the operands twice. The first time we don't print anything,
252b5132
RH
423 but look for errors. */
424
425 save_p = p;
426 info->print_address_func = dummy_print_address;
ec22bdda
KH
427 info->fprintf_func = (fprintf_ftype) dummy_printer;
428 for (; *d; d += 2)
252b5132
RH
429 {
430 int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
431 if (eaten >= 0)
432 p += eaten;
433 else if (eaten == -1)
434 goto invalid;
435 else
436 {
ec22bdda
KH
437 (*info->fprintf_func) (info->stream,
438 /* xgettext:c-format */
439 _("<internal error in opcode table: %s %s>\n"),
440 best->name,
441 best->args);
252b5132
RH
442 goto invalid;
443 }
444
445 }
446 p = save_p;
447 info->fprintf_func = save_printer;
448 info->print_address_func = save_print_address;
449
450 d = best->args;
451
452 (*info->fprintf_func) (info->stream, "%s", best->name);
453
454 if (*d)
455 (*info->fprintf_func) (info->stream, " ");
456
457 while (*d)
458 {
459 p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
460 d += 2;
461 if (*d && *(d - 2) != 'I' && *d != 'k')
462 (*info->fprintf_func) (info->stream, ",");
463 }
464 return p - buffer;
465
466 invalid:
467 /* Handle undefined instructions. */
468 info->fprintf_func = save_printer;
469 info->print_address_func = save_print_address;
470 (*info->fprintf_func) (info->stream, "0%o",
471 (buffer[0] << 8) + buffer[1]);
472 return 2;
473}
474
475/* Returns number of bytes "eaten" by the operand, or
476 return -1 if an invalid operand was found, or -2 if
477 an opcode tabe error was found. */
478
479static int
480print_insn_arg (d, buffer, p0, addr, info)
481 const char *d;
482 unsigned char *buffer;
483 unsigned char *p0;
484 bfd_vma addr; /* PC for this arg to be relative to */
485 disassemble_info *info;
486{
487 register int val = 0;
488 register int place = d[1];
489 register unsigned char *p = p0;
490 int regno;
56da5fed 491 register const char *regname;
252b5132
RH
492 register unsigned char *p1;
493 double flval;
494 int flt_p;
495 bfd_signed_vma disp;
496 unsigned int uval;
497
498 switch (*d)
499 {
500 case 'c': /* cache identifier */
501 {
502 static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
503 val = fetch_arg (buffer, place, 2, info);
504 (*info->fprintf_func) (info->stream, cacheFieldName[val]);
505 break;
506 }
507
508 case 'a': /* address register indirect only. Cf. case '+'. */
509 {
510 (*info->fprintf_func)
511 (info->stream,
512 "%s@",
ec22bdda 513 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
252b5132
RH
514 break;
515 }
516
517 case '_': /* 32-bit absolute address for move16. */
518 {
519 uval = NEXTULONG (p);
520 (*info->print_address_func) (uval, info);
521 break;
522 }
523
524 case 'C':
525 (*info->fprintf_func) (info->stream, "%%ccr");
526 break;
527
528 case 'S':
529 (*info->fprintf_func) (info->stream, "%%sr");
530 break;
531
532 case 'U':
533 (*info->fprintf_func) (info->stream, "%%usp");
534 break;
535
461d5ddd
ILT
536 case 'E':
537 (*info->fprintf_func) (info->stream, "%%acc");
538 break;
539
540 case 'G':
541 (*info->fprintf_func) (info->stream, "%%macsr");
542 break;
543
544 case 'H':
545 (*info->fprintf_func) (info->stream, "%%mask");
546 break;
547
252b5132
RH
548 case 'J':
549 {
3e602632
NC
550 /* FIXME: There's a problem here, different m68k processors call the
551 same address different names. This table can't get it right
552 because it doesn't know which processor it's disassembling for. */
252b5132
RH
553 static const struct { char *name; int value; } names[]
554 = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
555 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
556 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
557 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
558 {"%msp", 0x803}, {"%isp", 0x804},
3e602632 559 {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these. */
252b5132
RH
560
561 /* Should we be calling this psr like we do in case 'Y'? */
562 {"%mmusr",0x805},
563
564 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
565
566 val = fetch_arg (buffer, place, 12, info);
567 for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
568 if (names[regno].value == val)
569 {
570 (*info->fprintf_func) (info->stream, "%s", names[regno].name);
571 break;
572 }
573 if (regno < 0)
574 (*info->fprintf_func) (info->stream, "%d", val);
575 }
576 break;
577
578 case 'Q':
579 val = fetch_arg (buffer, place, 3, info);
580 /* 0 means 8, except for the bkpt instruction... */
581 if (val == 0 && d[1] != 's')
582 val = 8;
583 (*info->fprintf_func) (info->stream, "#%d", val);
584 break;
585
3e602632
NC
586 case 'x':
587 val = fetch_arg (buffer, place, 3, info);
588 /* 0 means -1. */
589 if (val == 0)
590 val = -1;
591 (*info->fprintf_func) (info->stream, "#%d", val);
592 break;
593
252b5132 594 case 'M':
461d5ddd
ILT
595 if (place == 'h')
596 {
597 static char *const scalefactor_name[] = { "<<", ">>" };
598 val = fetch_arg (buffer, place, 1, info);
599 (*info->fprintf_func) (info->stream, scalefactor_name[val]);
600 }
601 else
602 {
603 val = fetch_arg (buffer, place, 8, info);
604 if (val & 0x80)
605 val = val - 0x100;
606 (*info->fprintf_func) (info->stream, "#%d", val);
607 }
252b5132
RH
608 break;
609
610 case 'T':
611 val = fetch_arg (buffer, place, 4, info);
612 (*info->fprintf_func) (info->stream, "#%d", val);
613 break;
614
615 case 'D':
616 (*info->fprintf_func) (info->stream, "%s",
617 reg_names[fetch_arg (buffer, place, 3, info)]);
618 break;
619
620 case 'A':
621 (*info->fprintf_func)
622 (info->stream, "%s",
623 reg_names[fetch_arg (buffer, place, 3, info) + 010]);
624 break;
625
626 case 'R':
627 (*info->fprintf_func)
628 (info->stream, "%s",
629 reg_names[fetch_arg (buffer, place, 4, info)]);
630 break;
631
632 case 'r':
633 regno = fetch_arg (buffer, place, 4, info);
634 if (regno > 7)
635 (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
636 else
637 (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
638 break;
639
640 case 'F':
641 (*info->fprintf_func)
642 (info->stream, "%%fp%d",
643 fetch_arg (buffer, place, 3, info));
644 break;
645
646 case 'O':
647 val = fetch_arg (buffer, place, 6, info);
648 if (val & 0x20)
ec22bdda 649 (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
252b5132
RH
650 else
651 (*info->fprintf_func) (info->stream, "%d", val);
652 break;
653
654 case '+':
655 (*info->fprintf_func)
656 (info->stream, "%s@+",
657 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
658 break;
659
660 case '-':
661 (*info->fprintf_func)
662 (info->stream, "%s@-",
663 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
664 break;
665
666 case 'k':
667 if (place == 'k')
668 (*info->fprintf_func)
669 (info->stream, "{%s}",
670 reg_names[fetch_arg (buffer, place, 3, info)]);
671 else if (place == 'C')
672 {
673 val = fetch_arg (buffer, place, 7, info);
ec22bdda 674 if (val > 63) /* This is a signed constant. */
252b5132
RH
675 val -= 128;
676 (*info->fprintf_func) (info->stream, "{#%d}", val);
677 }
678 else
679 return -2;
680 break;
681
682 case '#':
683 case '^':
684 p1 = buffer + (*d == '#' ? 2 : 4);
685 if (place == 's')
686 val = fetch_arg (buffer, place, 4, info);
687 else if (place == 'C')
688 val = fetch_arg (buffer, place, 7, info);
689 else if (place == '8')
690 val = fetch_arg (buffer, place, 3, info);
691 else if (place == '3')
692 val = fetch_arg (buffer, place, 8, info);
693 else if (place == 'b')
694 val = NEXTBYTE (p1);
695 else if (place == 'w' || place == 'W')
696 val = NEXTWORD (p1);
697 else if (place == 'l')
698 val = NEXTLONG (p1);
699 else
700 return -2;
701 (*info->fprintf_func) (info->stream, "#%d", val);
702 break;
703
704 case 'B':
705 if (place == 'b')
706 disp = NEXTBYTE (p);
707 else if (place == 'B')
ec22bdda 708 disp = COERCE_SIGNED_CHAR (buffer[1]);
252b5132
RH
709 else if (place == 'w' || place == 'W')
710 disp = NEXTWORD (p);
711 else if (place == 'l' || place == 'L' || place == 'C')
712 disp = NEXTLONG (p);
713 else if (place == 'g')
714 {
715 disp = NEXTBYTE (buffer);
716 if (disp == 0)
717 disp = NEXTWORD (p);
718 else if (disp == -1)
719 disp = NEXTLONG (p);
720 }
721 else if (place == 'c')
722 {
723 if (buffer[1] & 0x40) /* If bit six is one, long offset */
724 disp = NEXTLONG (p);
725 else
726 disp = NEXTWORD (p);
727 }
728 else
729 return -2;
730
731 (*info->print_address_func) (addr + disp, info);
732 break;
733
734 case 'd':
735 val = NEXTWORD (p);
736 (*info->fprintf_func)
737 (info->stream, "%s@(%d)",
738 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
739 break;
740
741 case 's':
742 (*info->fprintf_func) (info->stream, "%s",
743 fpcr_names[fetch_arg (buffer, place, 3, info)]);
744 break;
745
fd99574b
NC
746 case 'e':
747 val = fetch_arg(buffer, place, 2, info);
748 (*info->fprintf_func) (info->stream, "%%acc%d", val);
749 break;
750
751 case 'g':
752 val = fetch_arg(buffer, place, 2, info);
753 (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
754 break;
755
756 case 'i':
757 val = fetch_arg(buffer, place, 2, info);
758 if (val == 1)
759 (*info->fprintf_func) (info->stream, "<<");
760 else if (val == 3)
761 (*info->fprintf_func) (info->stream, ">>");
762 break;
763
252b5132
RH
764 case 'I':
765 /* Get coprocessor ID... */
766 val = fetch_arg (buffer, 'd', 3, info);
3e602632 767
252b5132
RH
768 if (val != 1) /* Unusual coprocessor ID? */
769 (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
770 break;
771
fd99574b 772 case '4':
252b5132
RH
773 case '*':
774 case '~':
775 case '%':
776 case ';':
777 case '@':
778 case '!':
779 case '$':
780 case '?':
781 case '/':
782 case '&':
783 case '|':
784 case '<':
785 case '>':
786 case 'm':
787 case 'n':
788 case 'o':
789 case 'p':
790 case 'q':
791 case 'v':
3e602632
NC
792 case 'b':
793 case 'w':
794 case 'y':
795 case 'z':
252b5132
RH
796 if (place == 'd')
797 {
798 val = fetch_arg (buffer, 'x', 6, info);
799 val = ((val & 7) << 3) + ((val >> 3) & 7);
800 }
801 else
802 val = fetch_arg (buffer, 's', 6, info);
803
804 /* Get register number assuming address register. */
805 regno = (val & 7) + 8;
806 regname = reg_names[regno];
807 switch (val >> 3)
808 {
809 case 0:
810 (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
811 break;
812
813 case 1:
814 (*info->fprintf_func) (info->stream, "%s", regname);
815 break;
816
817 case 2:
818 (*info->fprintf_func) (info->stream, "%s@", regname);
819 break;
820
821 case 3:
822 (*info->fprintf_func) (info->stream, "%s@+", regname);
823 break;
824
825 case 4:
826 (*info->fprintf_func) (info->stream, "%s@-", regname);
827 break;
828
829 case 5:
830 val = NEXTWORD (p);
831 (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
832 break;
833
834 case 6:
835 p = print_indexed (regno, p, addr, info);
836 break;
837
838 case 7:
839 switch (val & 7)
840 {
841 case 0:
842 val = NEXTWORD (p);
843 (*info->print_address_func) (val, info);
844 break;
845
846 case 1:
847 uval = NEXTULONG (p);
848 (*info->print_address_func) (uval, info);
849 break;
850
851 case 2:
852 val = NEXTWORD (p);
853 (*info->fprintf_func) (info->stream, "%%pc@(");
854 (*info->print_address_func) (addr + val, info);
855 (*info->fprintf_func) (info->stream, ")");
856 break;
857
858 case 3:
859 p = print_indexed (-1, p, addr, info);
860 break;
861
862 case 4:
863 flt_p = 1; /* Assume it's a float... */
ec22bdda 864 switch (place)
252b5132
RH
865 {
866 case 'b':
867 val = NEXTBYTE (p);
868 flt_p = 0;
869 break;
870
871 case 'w':
872 val = NEXTWORD (p);
873 flt_p = 0;
874 break;
875
876 case 'l':
877 val = NEXTLONG (p);
878 flt_p = 0;
879 break;
880
881 case 'f':
ec22bdda 882 NEXTSINGLE (flval, p);
252b5132
RH
883 break;
884
885 case 'F':
ec22bdda 886 NEXTDOUBLE (flval, p);
252b5132
RH
887 break;
888
889 case 'x':
ec22bdda 890 NEXTEXTEND (flval, p);
252b5132
RH
891 break;
892
893 case 'p':
ec22bdda 894 flval = NEXTPACKED (p);
252b5132
RH
895 break;
896
897 default:
898 return -1;
899 }
ec22bdda 900 if (flt_p) /* Print a float? */
252b5132
RH
901 (*info->fprintf_func) (info->stream, "#%g", flval);
902 else
903 (*info->fprintf_func) (info->stream, "#%d", val);
904 break;
905
906 default:
907 return -1;
908 }
909 }
fd99574b
NC
910
911 /* If place is '/', then this is the case of the mask bit for
912 mac/emac loads. Now that the arg has been printed, grab the
913 mask bit and if set, add a '&' to the arg. */
914 if (place == '/')
915 {
916 val = fetch_arg (buffer, place, 1, info);
917 if (val)
918 (*info->fprintf_func) (info->stream, "&");
919 }
252b5132
RH
920 break;
921
922 case 'L':
923 case 'l':
924 if (place == 'w')
925 {
926 char doneany;
927 p1 = buffer + 2;
928 val = NEXTWORD (p1);
929 /* Move the pointer ahead if this point is farther ahead
930 than the last. */
931 p = p1 > p ? p1 : p;
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 < 16; ++regno)
941 if (val & (0x8000 >> regno))
942 newval |= 1 << regno;
943 val = newval;
944 }
945 val &= 0xffff;
946 doneany = 0;
947 for (regno = 0; regno < 16; ++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, "%s", reg_names[regno]);
955 first_regno = regno;
956 while (val & (1 << (regno + 1)))
957 ++regno;
958 if (regno > first_regno)
959 (*info->fprintf_func) (info->stream, "-%s",
960 reg_names[regno]);
961 }
962 }
963 else if (place == '3')
964 {
965 /* `fmovem' insn. */
966 char doneany;
967 val = fetch_arg (buffer, place, 8, info);
968 if (val == 0)
969 {
970 (*info->fprintf_func) (info->stream, "#0");
971 break;
972 }
973 if (*d == 'l')
974 {
975 register int newval = 0;
976 for (regno = 0; regno < 8; ++regno)
977 if (val & (0x80 >> regno))
978 newval |= 1 << regno;
979 val = newval;
980 }
981 val &= 0xff;
982 doneany = 0;
983 for (regno = 0; regno < 8; ++regno)
984 if (val & (1 << regno))
985 {
986 int first_regno;
987 if (doneany)
988 (*info->fprintf_func) (info->stream, "/");
989 doneany = 1;
990 (*info->fprintf_func) (info->stream, "%%fp%d", regno);
991 first_regno = regno;
992 while (val & (1 << (regno + 1)))
993 ++regno;
994 if (regno > first_regno)
995 (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
996 }
997 }
998 else if (place == '8')
999 {
1000 /* fmoveml for FP status registers */
1001 (*info->fprintf_func) (info->stream, "%s",
1002 fpcr_names[fetch_arg (buffer, place, 3,
1003 info)]);
1004 }
1005 else
1006 return -2;
1007 break;
1008
1009 case 'X':
1010 place = '8';
1011 case 'Y':
1012 case 'Z':
1013 case 'W':
1014 case '0':
1015 case '1':
1016 case '2':
1017 case '3':
1018 {
1019 int val = fetch_arg (buffer, place, 5, info);
1020 char *name = 0;
1021 switch (val)
1022 {
1023 case 2: name = "%tt0"; break;
1024 case 3: name = "%tt1"; break;
1025 case 0x10: name = "%tc"; break;
1026 case 0x11: name = "%drp"; break;
1027 case 0x12: name = "%srp"; break;
1028 case 0x13: name = "%crp"; break;
1029 case 0x14: name = "%cal"; break;
1030 case 0x15: name = "%val"; break;
1031 case 0x16: name = "%scc"; break;
1032 case 0x17: name = "%ac"; break;
1033 case 0x18: name = "%psr"; break;
1034 case 0x19: name = "%pcsr"; break;
1035 case 0x1c:
1036 case 0x1d:
1037 {
1038 int break_reg = ((buffer[3] >> 2) & 7);
1039 (*info->fprintf_func)
1040 (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
1041 break_reg);
1042 }
1043 break;
1044 default:
1045 (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
1046 }
1047 if (name)
1048 (*info->fprintf_func) (info->stream, "%s", name);
1049 }
1050 break;
1051
1052 case 'f':
1053 {
1054 int fc = fetch_arg (buffer, place, 5, info);
1055 if (fc == 1)
1056 (*info->fprintf_func) (info->stream, "%%dfc");
1057 else if (fc == 0)
1058 (*info->fprintf_func) (info->stream, "%%sfc");
1059 else
1060 /* xgettext:c-format */
1061 (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
1062 }
1063 break;
1064
1065 case 'V':
1066 (*info->fprintf_func) (info->stream, "%%val");
1067 break;
1068
1069 case 't':
1070 {
1071 int level = fetch_arg (buffer, place, 3, info);
1072 (*info->fprintf_func) (info->stream, "%d", level);
1073 }
1074 break;
1075
461d5ddd
ILT
1076 case 'u':
1077 {
1078 short is_upper = 0;
1079 int reg = fetch_arg (buffer, place, 5, info);
3e602632 1080
461d5ddd
ILT
1081 if (reg & 0x10)
1082 {
1083 is_upper = 1;
1084 reg &= 0xf;
1085 }
1086 (*info->fprintf_func) (info->stream, "%s%s",
1087 reg_names[reg],
1088 is_upper ? "u" : "l");
1089 }
1090 break;
3e602632 1091
252b5132
RH
1092 default:
1093 return -2;
1094 }
1095
1096 return p - p0;
1097}
1098
1099/* Fetch BITS bits from a position in the instruction specified by CODE.
1100 CODE is a "place to put an argument", or 'x' for a destination
1101 that is a general address (mode and register).
1102 BUFFER contains the instruction. */
1103
1104static int
1105fetch_arg (buffer, code, bits, info)
1106 unsigned char *buffer;
1107 int code;
1108 int bits;
1109 disassemble_info *info;
1110{
1111 register int val = 0;
1112 switch (code)
1113 {
fd99574b
NC
1114 case '/': /* MAC/EMAC mask bit. */
1115 val = buffer[3] >> 5;
1116 break;
1117
1118 case 'G': /* EMAC ACC load. */
1119 val = ((buffer[3] >> 3) & 0x2) | ((~buffer[2] >> 7) & 0x1);
1120 break;
1121
1122 case 'H': /* EMAC ACC !load. */
1123 val = ((buffer[3] >> 3) & 0x2) | ((buffer[2] >> 7) & 0x1);
1124 break;
1125
1126 case ']': /* EMAC ACCEXT bit. */
1127 val = buffer[0] >> 2;
1128 break;
1129
1130 case 'I': /* MAC/EMAC scale factor. */
1131 val = buffer[0] >> 1;
1132 break;
1133
1134 case 'F': /* EMAC ACCx. */
1135 val = buffer[0] >> 1;
1136 break;
1137
1138 case 'f':
1139 val = buffer[0];
1140 break;
1141
252b5132
RH
1142 case 's':
1143 val = buffer[1];
1144 break;
1145
1146 case 'd': /* Destination, for register or quick. */
1147 val = (buffer[0] << 8) + buffer[1];
1148 val >>= 9;
1149 break;
1150
1151 case 'x': /* Destination, for general arg */
1152 val = (buffer[0] << 8) + buffer[1];
1153 val >>= 6;
1154 break;
1155
1156 case 'k':
1157 FETCH_DATA (info, buffer + 3);
1158 val = (buffer[3] >> 4);
1159 break;
1160
1161 case 'C':
1162 FETCH_DATA (info, buffer + 3);
1163 val = buffer[3];
1164 break;
1165
1166 case '1':
1167 FETCH_DATA (info, buffer + 3);
1168 val = (buffer[2] << 8) + buffer[3];
1169 val >>= 12;
1170 break;
1171
1172 case '2':
1173 FETCH_DATA (info, buffer + 3);
1174 val = (buffer[2] << 8) + buffer[3];
1175 val >>= 6;
1176 break;
1177
1178 case '3':
1179 case 'j':
1180 FETCH_DATA (info, buffer + 3);
1181 val = (buffer[2] << 8) + buffer[3];
1182 break;
1183
1184 case '4':
1185 FETCH_DATA (info, buffer + 5);
1186 val = (buffer[4] << 8) + buffer[5];
1187 val >>= 12;
1188 break;
1189
1190 case '5':
1191 FETCH_DATA (info, buffer + 5);
1192 val = (buffer[4] << 8) + buffer[5];
1193 val >>= 6;
1194 break;
1195
1196 case '6':
1197 FETCH_DATA (info, buffer + 5);
1198 val = (buffer[4] << 8) + buffer[5];
1199 break;
1200
1201 case '7':
1202 FETCH_DATA (info, buffer + 3);
1203 val = (buffer[2] << 8) + buffer[3];
1204 val >>= 7;
1205 break;
3e602632 1206
252b5132
RH
1207 case '8':
1208 FETCH_DATA (info, buffer + 3);
1209 val = (buffer[2] << 8) + buffer[3];
1210 val >>= 10;
1211 break;
1212
1213 case '9':
1214 FETCH_DATA (info, buffer + 3);
1215 val = (buffer[2] << 8) + buffer[3];
1216 val >>= 5;
1217 break;
1218
1219 case 'e':
1220 val = (buffer[1] >> 6);
1221 break;
1222
3e602632 1223 case 'm':
461d5ddd
ILT
1224 val = (buffer[1] & 0x40 ? 0x8 : 0)
1225 | ((buffer[0] >> 1) & 0x7)
1226 | (buffer[3] & 0x80 ? 0x10 : 0);
1227 break;
1228
3e602632 1229 case 'n':
461d5ddd
ILT
1230 val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
1231 break;
1232
1233 case 'o':
1234 val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
1235 break;
1236
1237 case 'M':
1238 val = buffer[1] | (buffer[3] & 0x40 ? 0x10 : 0);
1239 break;
1240
1241 case 'N':
1242 val = buffer[3] | (buffer[3] & 0x40 ? 0x10 : 0);
1243 break;
1244
1245 case 'h':
1246 val = buffer[2] >> 2;
1247 break;
1248
252b5132
RH
1249 default:
1250 abort ();
1251 }
1252
1253 switch (bits)
1254 {
461d5ddd
ILT
1255 case 1:
1256 return val & 1;
252b5132
RH
1257 case 2:
1258 return val & 3;
1259 case 3:
1260 return val & 7;
1261 case 4:
1262 return val & 017;
1263 case 5:
1264 return val & 037;
1265 case 6:
1266 return val & 077;
1267 case 7:
1268 return val & 0177;
1269 case 8:
1270 return val & 0377;
1271 case 12:
1272 return val & 07777;
1273 default:
1274 abort ();
1275 }
1276}
1277
1278/* Print an indexed argument. The base register is BASEREG (-1 for pc).
1279 P points to extension word, in buffer.
1280 ADDR is the nominal core address of that extension word. */
1281
1282static unsigned char *
1283print_indexed (basereg, p, addr, info)
1284 int basereg;
1285 unsigned char *p;
1286 bfd_vma addr;
1287 disassemble_info *info;
1288{
1289 register int word;
ec22bdda 1290 static char *const scales[] = { "", ":2", ":4", ":8" };
252b5132
RH
1291 bfd_vma base_disp;
1292 bfd_vma outer_disp;
1293 char buf[40];
1294 char vmabuf[50];
1295
1296 word = NEXTWORD (p);
1297
1298 /* Generate the text for the index register.
1299 Where this will be output is not yet determined. */
1300 sprintf (buf, "%s:%c%s",
1301 reg_names[(word >> 12) & 0xf],
1302 (word & 0x800) ? 'l' : 'w',
1303 scales[(word >> 9) & 3]);
1304
1305 /* Handle the 68000 style of indexing. */
1306
1307 if ((word & 0x100) == 0)
1308 {
1309 base_disp = word & 0xff;
1310 if ((base_disp & 0x80) != 0)
1311 base_disp -= 0x100;
1312 if (basereg == -1)
1313 base_disp += addr;
1314 print_base (basereg, base_disp, info);
1315 (*info->fprintf_func) (info->stream, ",%s)", buf);
1316 return p;
1317 }
1318
1319 /* Handle the generalized kind. */
1320 /* First, compute the displacement to add to the base register. */
1321
1322 if (word & 0200)
1323 {
1324 if (basereg == -1)
1325 basereg = -3;
1326 else
1327 basereg = -2;
1328 }
1329 if (word & 0100)
1330 buf[0] = '\0';
1331 base_disp = 0;
1332 switch ((word >> 4) & 3)
1333 {
1334 case 2:
1335 base_disp = NEXTWORD (p);
1336 break;
1337 case 3:
1338 base_disp = NEXTLONG (p);
1339 }
1340 if (basereg == -1)
1341 base_disp += addr;
1342
1343 /* Handle single-level case (not indirect) */
1344
1345 if ((word & 7) == 0)
1346 {
1347 print_base (basereg, base_disp, info);
1348 if (buf[0] != '\0')
1349 (*info->fprintf_func) (info->stream, ",%s", buf);
1350 (*info->fprintf_func) (info->stream, ")");
1351 return p;
1352 }
1353
1354 /* Two level. Compute displacement to add after indirection. */
1355
1356 outer_disp = 0;
1357 switch (word & 3)
1358 {
1359 case 2:
1360 outer_disp = NEXTWORD (p);
1361 break;
1362 case 3:
1363 outer_disp = NEXTLONG (p);
1364 }
1365
1366 print_base (basereg, base_disp, info);
1367 if ((word & 4) == 0 && buf[0] != '\0')
1368 {
1369 (*info->fprintf_func) (info->stream, ",%s", buf);
1370 buf[0] = '\0';
1371 }
1372 sprintf_vma (vmabuf, outer_disp);
1373 (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
1374 if (buf[0] != '\0')
1375 (*info->fprintf_func) (info->stream, ",%s", buf);
1376 (*info->fprintf_func) (info->stream, ")");
1377
1378 return p;
1379}
1380
1381/* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1382 REGNO = -1 for pc, -2 for none (suppressed). */
1383
1384static void
1385print_base (regno, disp, info)
1386 int regno;
1387 bfd_vma disp;
1388 disassemble_info *info;
1389{
1390 if (regno == -1)
1391 {
1392 (*info->fprintf_func) (info->stream, "%%pc@(");
1393 (*info->print_address_func) (disp, info);
1394 }
1395 else
1396 {
1397 char buf[50];
1398
1399 if (regno == -2)
1400 (*info->fprintf_func) (info->stream, "@(");
1401 else if (regno == -3)
1402 (*info->fprintf_func) (info->stream, "%%zpc@(");
1403 else
1404 (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
1405
1406 sprintf_vma (buf, disp);
1407 (*info->fprintf_func) (info->stream, "%s", buf);
1408 }
1409}
This page took 0.342105 seconds and 4 git commands to generate.