* sun build fix for thinko (?)
[binutils-gdb.git] / opcodes / mips-dis.c
blob4efd91c6a6f2705dea3a44fdaaca054f75b16e9b
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (c) 1989, 91-97, 1998 Free Software Foundation, Inc.
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5 This file is part of GDB, GAS, and the GNU binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include <ansidecl.h>
22 #include "sysdep.h"
23 #include "dis-asm.h"
24 #include "opcode/mips.h"
25 #include "opintl.h"
27 /* FIXME: These are needed to figure out if the code is mips16 or
28 not. The low bit of the address is often a good indicator. No
29 symbol table is available when this code runs out in an embedded
30 system as when it is used for disassembler support in a monitor. */
32 #if !defined(EMBEDDED_ENV)
33 #define SYMTAB_AVAILABLE 1
34 #include "elf-bfd.h"
35 #include "elf/mips.h"
36 #endif
38 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
39 static void print_mips16_insn_arg
40 PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
41 struct disassemble_info *));
43 /* Mips instructions are never longer than this many bytes. */
44 #define MAXLEN 4
46 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
47 struct disassemble_info *));
48 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
49 struct disassemble_info *));
52 /* FIXME: This should be shared with gdb somehow. */
53 #define REGISTER_NAMES \
54 { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
55 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
56 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
57 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
58 "sr", "lo", "hi", "bad", "cause","pc", \
59 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
60 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
61 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
62 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
63 "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
64 "epc", "prid"\
67 static CONST char * CONST reg_names[] = REGISTER_NAMES;
69 /* The mips16 register names. */
70 static const char * const mips16_reg_names[] =
72 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
75 /* subroutine */
76 static void
77 print_insn_arg (d, l, pc, info)
78 const char *d;
79 register unsigned long int l;
80 bfd_vma pc;
81 struct disassemble_info *info;
83 int delta;
85 switch (*d)
87 case ',':
88 case '(':
89 case ')':
90 /* start-sanitize-vr5400 */
91 case '[':
92 case ']':
93 /* end-sanitize-vr5400 */
94 /* start-sanitize-r5900 */
95 case '+':
96 case '-':
97 /* end-sanitize-r5900 */
98 (*info->fprintf_func) (info->stream, "%c", *d);
99 break;
101 case 's':
102 case 'b':
103 case 'r':
104 case 'v':
105 (*info->fprintf_func) (info->stream, "$%s",
106 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
107 break;
109 case 't':
110 case 'w':
111 (*info->fprintf_func) (info->stream, "$%s",
112 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
113 break;
115 case 'i':
116 case 'u':
117 (*info->fprintf_func) (info->stream, "0x%x",
118 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
119 break;
121 case 'j': /* same as i, but sign-extended */
122 case 'o':
123 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
124 if (delta & 0x8000)
125 delta |= ~0xffff;
126 (*info->fprintf_func) (info->stream, "%d",
127 delta);
128 break;
130 case 'h':
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (unsigned int) ((l >> OP_SH_PREFX)
133 & OP_MASK_PREFX));
134 break;
136 case 'k':
137 (*info->fprintf_func) (info->stream, "0x%x",
138 (unsigned int) ((l >> OP_SH_CACHE)
139 & OP_MASK_CACHE));
140 break;
142 case 'a':
143 (*info->print_address_func)
144 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
145 info);
146 break;
148 case 'p':
149 /* sign extend the displacement */
150 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
151 if (delta & 0x8000)
152 delta |= ~0xffff;
153 (*info->print_address_func)
154 ((delta << 2) + pc + 4,
155 info);
156 break;
158 case 'd':
159 (*info->fprintf_func) (info->stream, "$%s",
160 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
161 break;
163 case 'z':
164 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
165 break;
167 case '<':
168 (*info->fprintf_func) (info->stream, "0x%x",
169 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
170 break;
172 case 'c':
173 (*info->fprintf_func) (info->stream, "0x%x",
174 (l >> OP_SH_CODE) & OP_MASK_CODE);
175 break;
178 case 'q':
179 (*info->fprintf_func) (info->stream, "0x%x",
180 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
181 break;
183 case 'C':
184 (*info->fprintf_func) (info->stream, "0x%x",
185 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
186 break;
188 case 'B':
189 (*info->fprintf_func) (info->stream, "0x%x",
190 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
191 break;
193 case 'S':
194 case 'V':
195 (*info->fprintf_func) (info->stream, "$f%d",
196 (l >> OP_SH_FS) & OP_MASK_FS);
197 break;
199 /* start-sanitize-r5900 */
200 case '0':
201 (*info->fprintf_func) (info->stream, "0x%x",
202 (l >> 6) & 0x1f);
203 break;
205 case '9':
206 (*info->fprintf_func) (info->stream, "vi27");
207 break;
209 case '1':
210 (*info->fprintf_func) (info->stream, "vf%d",
211 (l >> OP_SH_FT) & OP_MASK_FT);
212 break;
213 case '2':
214 (*info->fprintf_func) (info->stream, "vf%d",
215 (l >> OP_SH_FS) & OP_MASK_FS);
216 break;
217 case '3':
218 (*info->fprintf_func) (info->stream, "vf%d",
219 (l >> OP_SH_FD) & OP_MASK_FD);
220 break;
222 case '4':
223 (*info->fprintf_func) (info->stream, "vi%d",
224 (l >> OP_SH_FT) & OP_MASK_FT);
225 break;
226 case '5':
227 (*info->fprintf_func) (info->stream, "vi%d",
228 (l >> OP_SH_FS) & OP_MASK_FS);
229 break;
230 case '6':
231 (*info->fprintf_func) (info->stream, "vi%d",
232 (l >> OP_SH_FD) & OP_MASK_FD);
233 break;
235 case '7':
236 (*info->fprintf_func) (info->stream, "vf%d",
237 (l >> OP_SH_FT) & OP_MASK_FT);
238 switch ((l >> 23) & 0x3)
240 case 0:
241 (*info->fprintf_func) (info->stream, "x");
242 break;
243 case 1:
244 (*info->fprintf_func) (info->stream, "y");
245 break;
246 case 2:
247 (*info->fprintf_func) (info->stream, "z");
248 break;
249 case 3:
250 (*info->fprintf_func) (info->stream, "w");
251 break;
253 break;
254 case 'K':
255 break;
257 case ';':
258 (*info->fprintf_func) (info->stream, ".xyz\t");
259 break;
261 case '&':
262 (*info->fprintf_func) (info->stream, ".");
263 if (l & (1 << 21))
264 (*info->fprintf_func) (info->stream, "w");
265 if (l & (1 << 24))
266 (*info->fprintf_func) (info->stream, "x");
267 if (l & (1 << 23))
268 (*info->fprintf_func) (info->stream, "y");
269 if (l & (1 << 22))
270 (*info->fprintf_func) (info->stream, "z");
271 (*info->fprintf_func) (info->stream, "\t");
272 break;
274 case '8':
275 (*info->fprintf_func) (info->stream, "vf%d",
276 (l >> OP_SH_FS) & OP_MASK_FS);
277 switch ((l >> 21) & 0x3)
279 case 0:
280 (*info->fprintf_func) (info->stream, "x");
281 break;
282 case 1:
283 (*info->fprintf_func) (info->stream, "y");
284 break;
285 case 2:
286 (*info->fprintf_func) (info->stream, "z");
287 break;
288 case 3:
289 (*info->fprintf_func) (info->stream, "w");
290 break;
292 break;
293 case 'J':
294 (*info->fprintf_func) (info->stream, "I");
295 break;
297 case 'Q':
298 (*info->fprintf_func) (info->stream, "Q");
299 break;
301 case 'X':
302 (*info->fprintf_func) (info->stream, "R");
303 break;
305 case 'U':
306 (*info->fprintf_func) (info->stream, "ACC");
307 break;
309 case 'O':
310 delta = (l >> 6) & 0x7fff;
311 delta <<= 3;
312 (*info->print_address_func) (delta, info);
313 break;
315 /* end-sanitize-r5900 */
317 case 'T':
318 case 'W':
319 (*info->fprintf_func) (info->stream, "$f%d",
320 (l >> OP_SH_FT) & OP_MASK_FT);
321 break;
323 case 'D':
324 (*info->fprintf_func) (info->stream, "$f%d",
325 (l >> OP_SH_FD) & OP_MASK_FD);
326 break;
328 case 'R':
329 (*info->fprintf_func) (info->stream, "$f%d",
330 (l >> OP_SH_FR) & OP_MASK_FR);
331 break;
333 case 'E':
334 (*info->fprintf_func) (info->stream, "$%d",
335 (l >> OP_SH_RT) & OP_MASK_RT);
336 break;
338 case 'G':
339 (*info->fprintf_func) (info->stream, "$%d",
340 (l >> OP_SH_RD) & OP_MASK_RD);
341 break;
343 case 'N':
344 (*info->fprintf_func) (info->stream, "$fcc%d",
345 (l >> OP_SH_BCC) & OP_MASK_BCC);
346 break;
348 case 'M':
349 (*info->fprintf_func) (info->stream, "$fcc%d",
350 (l >> OP_SH_CCC) & OP_MASK_CCC);
351 break;
353 case 'P':
354 (*info->fprintf_func) (info->stream, "%d",
355 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
356 break;
358 /* start-sanitize-vr5400 */
359 case 'e':
360 (*info->fprintf_func) (info->stream, "%d",
361 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
362 break;
364 case '%':
365 (*info->fprintf_func) (info->stream, "%d",
366 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
367 break;
368 /* end-sanitize-vr5400 */
370 default:
371 /* xgettext:c-format */
372 (*info->fprintf_func) (info->stream,
373 _("# internal error, undefined modifier(%c)"),
374 *d);
375 break;
379 #if SYMTAB_AVAILABLE
381 /* Figure out the MIPS ISA and CPU based on the machine number.
382 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
384 static void
385 set_mips_isa_type (mach, isa, cputype)
386 int mach;
387 int *isa;
388 int *cputype;
390 int target_processor = 0;
391 int mips_isa = 0;
393 switch (mach)
395 /* start-sanitize-tx19 */
396 case bfd_mach_mips1900:
397 target_processor = 1900;
398 mips_isa = 1;
399 break;
400 /* end-sanitize-tx19 */
401 case bfd_mach_mips3000:
402 target_processor = 3000;
403 mips_isa = 1;
404 break;
405 case bfd_mach_mips3900:
406 target_processor = 3900;
407 mips_isa = 1;
408 break;
409 case bfd_mach_mips4000:
410 target_processor = 4000;
411 mips_isa = 3;
412 break;
413 case bfd_mach_mips4010:
414 target_processor = 4010;
415 mips_isa = 2;
416 break;
417 case bfd_mach_mips4100:
418 target_processor = 4100;
419 mips_isa = 3;
420 break;
421 case bfd_mach_mips4300:
422 target_processor = 4300;
423 mips_isa = 3;
424 break;
425 /* start-sanitize-vr4320 */
426 case bfd_mach_mips4320:
427 target_processor = 4320;
428 mips_isa = 3;
429 break;
430 /* end-sanitize-vr4320 */
431 case bfd_mach_mips4400:
432 target_processor = 4400;
433 mips_isa = 3;
434 break;
435 case bfd_mach_mips4600:
436 target_processor = 4600;
437 mips_isa = 3;
438 break;
439 case bfd_mach_mips4650:
440 target_processor = 4650;
441 mips_isa = 3;
442 break;
443 /* start-sanitize-tx49 */
444 case bfd_mach_mips4900:
445 target_processor = 4900;
446 mips_isa = 3;
447 break;
448 /* end-sanitize-tx49 */
449 case bfd_mach_mips5000:
450 target_processor = 5000;
451 mips_isa = 4;
452 break;
453 /* start-sanitize-vr5400 */
454 case bfd_mach_mips5400:
455 target_processor = 5400;
456 mips_isa = 3;
457 break;
458 /* end-sanitize-vr5400 */
459 /* start-sanitize-r5900 */
460 case bfd_mach_mips5900:
461 target_processor = 5900;
462 mips_isa = 3;
463 break;
464 /* end-sanitize-r5900 */
465 case bfd_mach_mips6000:
466 target_processor = 6000;
467 mips_isa = 2;
468 break;
469 case bfd_mach_mips8000:
470 target_processor = 8000;
471 mips_isa = 4;
472 break;
473 case bfd_mach_mips10000:
474 target_processor = 10000;
475 mips_isa = 4;
476 break;
477 case bfd_mach_mips16:
478 target_processor = 16;
479 mips_isa = 3;
480 break;
481 default:
482 target_processor = 3000;
483 mips_isa = 3;
484 break;
488 *isa = mips_isa;
489 *cputype = target_processor;
492 #endif /* SYMTAB_AVAILABLE */
494 /* Print the mips instruction at address MEMADDR in debugged memory,
495 on using INFO. Returns length of the instruction, in bytes, which is
496 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
497 this is little-endian code. */
499 static int
500 _print_insn_mips (memaddr, word, info)
501 bfd_vma memaddr;
502 unsigned long int word;
503 struct disassemble_info *info;
505 register const struct mips_opcode *op;
506 int target_processor, mips_isa;
507 static boolean init = 0;
508 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
510 /* Build a hash table to shorten the search time. */
511 if (! init)
513 unsigned int i;
515 for (i = 0; i <= OP_MASK_OP; i++)
517 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
519 if (op->pinfo == INSN_MACRO)
520 continue;
521 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
523 mips_hash[i] = op;
524 break;
529 init = 1;
532 #if ! SYMTAB_AVAILABLE
533 /* This is running out on a target machine, not in a host tool.
534 FIXME: Where does mips_target_info come from? */
535 target_processor = mips_target_info.processor;
536 mips_isa = mips_target_info.isa;
537 #else
538 set_mips_isa_type (info->mach, &target_processor, &mips_isa);
539 #endif
541 info->bytes_per_chunk = 4;
542 info->display_endian = info->endian;
544 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
545 if (op != NULL)
547 for (; op < &mips_opcodes[NUMOPCODES]; op++)
549 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
551 register const char *d;
552 int insn_isa;
554 if ((op->membership & INSN_ISA) == INSN_ISA1)
555 insn_isa = 1;
556 else if ((op->membership & INSN_ISA) == INSN_ISA2)
557 insn_isa = 2;
558 else if ((op->membership & INSN_ISA) == INSN_ISA3)
559 insn_isa = 3;
560 else if ((op->membership & INSN_ISA) == INSN_ISA4)
561 insn_isa = 4;
562 else
563 insn_isa = 15;
565 if (insn_isa > mips_isa
566 && (target_processor == 4650
567 && op->membership & INSN_4650) == 0
568 && (target_processor == 4010
569 && op->membership & INSN_4010) == 0
570 && (target_processor == 4100
571 && op->membership & INSN_4100) == 0
572 /* start-sanitize-vr4320 */
573 && (target_processor == 4320
574 && op->membership & INSN_4320) == 0
575 /* end-sanitize-vr4320 */
576 /* start-sanitize-vr5400 */
577 && (target_processor == 5400
578 && op->membership & INSN_5400) == 0
579 /* end-sanitize-vr5400 */
580 /* start-sanitize-r5900 */
581 && (target_processor == 5900
582 && op->membership & INSN_5900) == 0
583 /* end-sanitize-r5900 */
584 /* start-sanitize-tx49 */
585 && (target_processor == 4900
586 && op->membership & INSN_4900) == 0
587 /* end-sanitize-tx49 */
588 && (target_processor == 3900
589 && op->membership & INSN_3900) == 0)
590 continue;
592 (*info->fprintf_func) (info->stream, "%s", op->name);
594 d = op->args;
595 if (d != NULL && *d != '\0')
597 /* start-sanitize-r5900 */
598 /* If this is an opcode completer, then do not emit
599 a tab after the opcode. */
600 if (*d != '&' && *d != ';')
601 /* end-sanitize-r5900 */
602 (*info->fprintf_func) (info->stream, "\t");
603 for (; *d != '\0'; d++)
604 /* start-sanitize-r5900 */
605 /* If this is an escape character, go ahead and print the
606 next character in the arg string verbatim. */
607 if (*d == '#')
609 d++;
610 (*info->fprintf_func) (info->stream, "%c", *d);
612 else
613 /* end-sanitize-r5900 */
614 print_insn_arg (d, word, memaddr, info);
617 return 4;
622 /* Handle undefined instructions. */
623 (*info->fprintf_func) (info->stream, "0x%x", word);
624 return 4;
628 /* In an environment where we do not know the symbol type of the
629 instruction we are forced to assume that the low order bit of the
630 instructions' address may mark it as a mips16 instruction. If we
631 are single stepping, or the pc is within the disassembled function,
632 this works. Otherwise, we need a clue. Sometimes. */
635 print_insn_big_mips (memaddr, info)
636 bfd_vma memaddr;
637 struct disassemble_info *info;
639 bfd_byte buffer[4];
640 int status;
642 #if 1
643 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
644 /* Only a few tools will work this way. */
645 if (memaddr & 0x01)
646 return print_insn_mips16 (memaddr, info);
647 #endif
649 #if SYMTAB_AVAILABLE
650 if (info->mach == 16
651 || (info->flavour == bfd_target_elf_flavour
652 && info->symbols != NULL
653 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
654 == STO_MIPS16)))
655 return print_insn_mips16 (memaddr, info);
656 #endif
658 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
659 if (status == 0)
660 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
661 info);
662 else
664 (*info->memory_error_func) (status, memaddr, info);
665 return -1;
670 print_insn_little_mips (memaddr, info)
671 bfd_vma memaddr;
672 struct disassemble_info *info;
674 bfd_byte buffer[4];
675 int status;
677 /* start-sanitize-sky */
678 #ifdef ARCH_dvp
680 /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
681 once. Since dvp_mach_type is a function, ensure it's only called
682 once. */
683 int mach = dvp_info_mach_type (info);
685 if (bfd_mach_dvp_p (info->mach)
686 || bfd_mach_dvp_p (mach))
687 return print_insn_dvp (memaddr, info);
689 #endif
690 /* end-sanitize-sky */
692 #if 1
693 if (memaddr & 0x01)
694 return print_insn_mips16 (memaddr, info);
695 #endif
697 #if SYMTAB_AVAILABLE
698 if (info->mach == 16
699 || (info->flavour == bfd_target_elf_flavour
700 && info->symbols != NULL
701 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
702 == STO_MIPS16)))
703 return print_insn_mips16 (memaddr, info);
704 #endif
706 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
707 if (status == 0)
708 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
709 info);
710 else
712 (*info->memory_error_func) (status, memaddr, info);
713 return -1;
717 /* Disassemble mips16 instructions. */
719 static int
720 print_insn_mips16 (memaddr, info)
721 bfd_vma memaddr;
722 struct disassemble_info *info;
724 int status;
725 bfd_byte buffer[2];
726 int length;
727 int insn;
728 boolean use_extend;
729 int extend = 0;
730 const struct mips_opcode *op, *opend;
732 info->bytes_per_chunk = 2;
733 info->display_endian = info->endian;
735 info->insn_info_valid = 1;
736 info->branch_delay_insns = 0;
737 info->data_size = 0;
738 info->insn_type = dis_nonbranch;
739 info->target = 0;
740 info->target2 = 0;
742 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
743 if (status != 0)
745 (*info->memory_error_func) (status, memaddr, info);
746 return -1;
749 length = 2;
751 if (info->endian == BFD_ENDIAN_BIG)
752 insn = bfd_getb16 (buffer);
753 else
754 insn = bfd_getl16 (buffer);
756 /* Handle the extend opcode specially. */
757 use_extend = false;
758 if ((insn & 0xf800) == 0xf000)
760 use_extend = true;
761 extend = insn & 0x7ff;
763 memaddr += 2;
765 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
766 if (status != 0)
768 (*info->fprintf_func) (info->stream, "extend 0x%x",
769 (unsigned int) extend);
770 (*info->memory_error_func) (status, memaddr, info);
771 return -1;
774 if (info->endian == BFD_ENDIAN_BIG)
775 insn = bfd_getb16 (buffer);
776 else
777 insn = bfd_getl16 (buffer);
779 /* Check for an extend opcode followed by an extend opcode. */
780 if ((insn & 0xf800) == 0xf000)
782 (*info->fprintf_func) (info->stream, "extend 0x%x",
783 (unsigned int) extend);
784 info->insn_type = dis_noninsn;
785 return length;
788 length += 2;
791 /* FIXME: Should probably use a hash table on the major opcode here. */
793 opend = mips16_opcodes + bfd_mips16_num_opcodes;
794 for (op = mips16_opcodes; op < opend; op++)
796 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
798 const char *s;
800 if (strchr (op->args, 'a') != NULL)
802 if (use_extend)
804 (*info->fprintf_func) (info->stream, "extend 0x%x",
805 (unsigned int) extend);
806 info->insn_type = dis_noninsn;
807 return length - 2;
810 use_extend = false;
812 memaddr += 2;
814 status = (*info->read_memory_func) (memaddr, buffer, 2,
815 info);
816 if (status == 0)
818 use_extend = true;
819 if (info->endian == BFD_ENDIAN_BIG)
820 extend = bfd_getb16 (buffer);
821 else
822 extend = bfd_getl16 (buffer);
823 length += 2;
827 (*info->fprintf_func) (info->stream, "%s", op->name);
828 if (op->args[0] != '\0')
829 (*info->fprintf_func) (info->stream, "\t");
831 for (s = op->args; *s != '\0'; s++)
833 if (*s == ','
834 && s[1] == 'w'
835 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
836 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
838 /* Skip the register and the comma. */
839 ++s;
840 continue;
842 if (*s == ','
843 && s[1] == 'v'
844 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
845 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
847 /* Skip the register and the comma. */
848 ++s;
849 continue;
851 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
852 info);
855 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
857 info->branch_delay_insns = 1;
858 if (info->insn_type != dis_jsr)
859 info->insn_type = dis_branch;
862 return length;
866 if (use_extend)
867 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
868 (*info->fprintf_func) (info->stream, "0x%x", insn);
869 info->insn_type = dis_noninsn;
871 return length;
874 /* Disassemble an operand for a mips16 instruction. */
876 static void
877 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
878 int type;
879 const struct mips_opcode *op;
880 int l;
881 boolean use_extend;
882 int extend;
883 bfd_vma memaddr;
884 struct disassemble_info *info;
886 switch (type)
888 case ',':
889 case '(':
890 case ')':
891 (*info->fprintf_func) (info->stream, "%c", type);
892 break;
894 case 'y':
895 case 'w':
896 (*info->fprintf_func) (info->stream, "$%s",
897 mips16_reg_names[((l >> MIPS16OP_SH_RY)
898 & MIPS16OP_MASK_RY)]);
899 break;
901 case 'x':
902 case 'v':
903 (*info->fprintf_func) (info->stream, "$%s",
904 mips16_reg_names[((l >> MIPS16OP_SH_RX)
905 & MIPS16OP_MASK_RX)]);
906 break;
908 case 'z':
909 (*info->fprintf_func) (info->stream, "$%s",
910 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
911 & MIPS16OP_MASK_RZ)]);
912 break;
914 case 'Z':
915 (*info->fprintf_func) (info->stream, "$%s",
916 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
917 & MIPS16OP_MASK_MOVE32Z)]);
918 break;
920 case '0':
921 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
922 break;
924 case 'S':
925 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
926 break;
928 case 'P':
929 (*info->fprintf_func) (info->stream, "$pc");
930 break;
932 case 'R':
933 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
934 break;
936 case 'X':
937 (*info->fprintf_func) (info->stream, "$%s",
938 reg_names[((l >> MIPS16OP_SH_REGR32)
939 & MIPS16OP_MASK_REGR32)]);
940 break;
942 case 'Y':
943 (*info->fprintf_func) (info->stream, "$%s",
944 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
945 break;
947 case '<':
948 case '>':
949 case '[':
950 case ']':
951 case '4':
952 case '5':
953 case 'H':
954 case 'W':
955 case 'D':
956 case 'j':
957 case '6':
958 case '8':
959 case 'V':
960 case 'C':
961 case 'U':
962 case 'k':
963 case 'K':
964 case 'p':
965 case 'q':
966 case 'A':
967 case 'B':
968 case 'E':
970 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
972 shift = 0;
973 signedp = 0;
974 extbits = 16;
975 pcrel = 0;
976 extu = 0;
977 branch = 0;
978 switch (type)
980 case '<':
981 nbits = 3;
982 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
983 extbits = 5;
984 extu = 1;
985 break;
986 case '>':
987 nbits = 3;
988 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
989 extbits = 5;
990 extu = 1;
991 break;
992 case '[':
993 nbits = 3;
994 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
995 extbits = 6;
996 extu = 1;
997 break;
998 case ']':
999 nbits = 3;
1000 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1001 extbits = 6;
1002 extu = 1;
1003 break;
1004 case '4':
1005 nbits = 4;
1006 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1007 signedp = 1;
1008 extbits = 15;
1009 break;
1010 case '5':
1011 nbits = 5;
1012 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1013 info->insn_type = dis_dref;
1014 info->data_size = 1;
1015 break;
1016 case 'H':
1017 nbits = 5;
1018 shift = 1;
1019 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1020 info->insn_type = dis_dref;
1021 info->data_size = 2;
1022 break;
1023 case 'W':
1024 nbits = 5;
1025 shift = 2;
1026 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1027 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1028 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1030 info->insn_type = dis_dref;
1031 info->data_size = 4;
1033 break;
1034 case 'D':
1035 nbits = 5;
1036 shift = 3;
1037 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1038 info->insn_type = dis_dref;
1039 info->data_size = 8;
1040 break;
1041 case 'j':
1042 nbits = 5;
1043 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1044 signedp = 1;
1045 break;
1046 case '6':
1047 nbits = 6;
1048 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1049 break;
1050 case '8':
1051 nbits = 8;
1052 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1053 break;
1054 case 'V':
1055 nbits = 8;
1056 shift = 2;
1057 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1058 /* FIXME: This might be lw, or it might be addiu to $sp or
1059 $pc. We assume it's load. */
1060 info->insn_type = dis_dref;
1061 info->data_size = 4;
1062 break;
1063 case 'C':
1064 nbits = 8;
1065 shift = 3;
1066 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1067 info->insn_type = dis_dref;
1068 info->data_size = 8;
1069 break;
1070 case 'U':
1071 nbits = 8;
1072 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1073 extu = 1;
1074 break;
1075 case 'k':
1076 nbits = 8;
1077 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1078 signedp = 1;
1079 break;
1080 case 'K':
1081 nbits = 8;
1082 shift = 3;
1083 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1084 signedp = 1;
1085 break;
1086 case 'p':
1087 nbits = 8;
1088 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1089 signedp = 1;
1090 pcrel = 1;
1091 branch = 1;
1092 info->insn_type = dis_condbranch;
1093 break;
1094 case 'q':
1095 nbits = 11;
1096 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1097 signedp = 1;
1098 pcrel = 1;
1099 branch = 1;
1100 info->insn_type = dis_branch;
1101 break;
1102 case 'A':
1103 nbits = 8;
1104 shift = 2;
1105 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1106 pcrel = 1;
1107 /* FIXME: This can be lw or la. We assume it is lw. */
1108 info->insn_type = dis_dref;
1109 info->data_size = 4;
1110 break;
1111 case 'B':
1112 nbits = 5;
1113 shift = 3;
1114 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1115 pcrel = 1;
1116 info->insn_type = dis_dref;
1117 info->data_size = 8;
1118 break;
1119 case 'E':
1120 nbits = 5;
1121 shift = 2;
1122 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1123 pcrel = 1;
1124 break;
1125 default:
1126 abort ();
1129 if (! use_extend)
1131 if (signedp && immed >= (1 << (nbits - 1)))
1132 immed -= 1 << nbits;
1133 immed <<= shift;
1134 if ((type == '<' || type == '>' || type == '[' || type == ']')
1135 && immed == 0)
1136 immed = 8;
1138 else
1140 if (extbits == 16)
1141 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1142 else if (extbits == 15)
1143 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1144 else
1145 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1146 immed &= (1 << extbits) - 1;
1147 if (! extu && immed >= (1 << (extbits - 1)))
1148 immed -= 1 << extbits;
1151 if (! pcrel)
1152 (*info->fprintf_func) (info->stream, "%d", immed);
1153 else
1155 bfd_vma baseaddr;
1156 bfd_vma val;
1158 if (branch)
1160 immed *= 2;
1161 baseaddr = memaddr + 2;
1163 else if (use_extend)
1164 baseaddr = memaddr - 2;
1165 else
1167 int status;
1168 bfd_byte buffer[2];
1170 baseaddr = memaddr;
1172 /* If this instruction is in the delay slot of a jr
1173 instruction, the base address is the address of the
1174 jr instruction. If it is in the delay slot of jalr
1175 instruction, the base address is the address of the
1176 jalr instruction. This test is unreliable: we have
1177 no way of knowing whether the previous word is
1178 instruction or data. */
1179 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1180 info);
1181 if (status == 0
1182 && (((info->endian == BFD_ENDIAN_BIG
1183 ? bfd_getb16 (buffer)
1184 : bfd_getl16 (buffer))
1185 & 0xf800) == 0x1800))
1186 baseaddr = memaddr - 4;
1187 else
1189 status = (*info->read_memory_func) (memaddr - 2, buffer,
1190 2, info);
1191 if (status == 0
1192 && (((info->endian == BFD_ENDIAN_BIG
1193 ? bfd_getb16 (buffer)
1194 : bfd_getl16 (buffer))
1195 & 0xf81f) == 0xe800))
1196 baseaddr = memaddr - 2;
1199 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1200 (*info->print_address_func) (val, info);
1201 info->target = val;
1204 break;
1206 case 'a':
1207 if (! use_extend)
1208 extend = 0;
1209 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1210 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1211 info->insn_type = dis_jsr;
1212 info->target = (memaddr & 0xf0000000) | l;
1213 info->branch_delay_insns = 1;
1214 break;
1216 case 'l':
1217 case 'L':
1219 int need_comma, amask, smask;
1221 need_comma = 0;
1223 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1225 amask = (l >> 3) & 7;
1227 if (amask > 0 && amask < 5)
1229 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1230 if (amask > 1)
1231 (*info->fprintf_func) (info->stream, "-$%s",
1232 reg_names[amask + 3]);
1233 need_comma = 1;
1236 smask = (l >> 1) & 3;
1237 if (smask == 3)
1239 (*info->fprintf_func) (info->stream, "%s??",
1240 need_comma ? "," : "");
1241 need_comma = 1;
1243 else if (smask > 0)
1245 (*info->fprintf_func) (info->stream, "%s$%s",
1246 need_comma ? "," : "",
1247 reg_names[16]);
1248 if (smask > 1)
1249 (*info->fprintf_func) (info->stream, "-$%s",
1250 reg_names[smask + 15]);
1251 need_comma = 1;
1254 if (l & 1)
1256 (*info->fprintf_func) (info->stream, "%s$%s",
1257 need_comma ? "," : "",
1258 reg_names[31]);
1259 need_comma = 1;
1262 if (amask == 5 || amask == 6)
1264 (*info->fprintf_func) (info->stream, "%s$f0",
1265 need_comma ? "," : "");
1266 if (amask == 6)
1267 (*info->fprintf_func) (info->stream, "-$f1");
1270 break;
1272 default:
1273 abort ();