2000-08-03 H.J. Lu (hjl@gnu.org)
[binutils.git] / opcodes / mips-dis.c
blobfa33821f32c587fc832dd6627977c8cf20df08b3
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (c) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
4 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6 This file is part of GDB, GAS, and the GNU binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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 STD_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 std_reg_names[] = STD_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 /* Scalar register names. set_mips_isa_type() decides which register name
76 table to use. */
77 static CONST char * CONST *reg_names = NULL;
79 /* subroutine */
80 static void
81 print_insn_arg (d, l, pc, info)
82 const char *d;
83 register unsigned long int l;
84 bfd_vma pc;
85 struct disassemble_info *info;
87 int delta;
89 switch (*d)
91 case ',':
92 case '(':
93 case ')':
94 (*info->fprintf_func) (info->stream, "%c", *d);
95 break;
97 case 's':
98 case 'b':
99 case 'r':
100 case 'v':
101 (*info->fprintf_func) (info->stream, "$%s",
102 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
103 break;
105 case 't':
106 case 'w':
107 (*info->fprintf_func) (info->stream, "$%s",
108 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
109 break;
111 case 'i':
112 case 'u':
113 (*info->fprintf_func) (info->stream, "0x%x",
114 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
115 break;
117 case 'j': /* same as i, but sign-extended */
118 case 'o':
119 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
120 if (delta & 0x8000)
121 delta |= ~0xffff;
122 (*info->fprintf_func) (info->stream, "%d",
123 delta);
124 break;
126 case 'h':
127 (*info->fprintf_func) (info->stream, "0x%x",
128 (unsigned int) ((l >> OP_SH_PREFX)
129 & OP_MASK_PREFX));
130 break;
132 case 'k':
133 (*info->fprintf_func) (info->stream, "0x%x",
134 (unsigned int) ((l >> OP_SH_CACHE)
135 & OP_MASK_CACHE));
136 break;
138 case 'a':
139 (*info->print_address_func)
140 (((pc & ~ (bfd_vma) 0x0fffffff)
141 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
142 info);
143 break;
145 case 'p':
146 /* sign extend the displacement */
147 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
148 if (delta & 0x8000)
149 delta |= ~0xffff;
150 (*info->print_address_func)
151 ((delta << 2) + pc + 4,
152 info);
153 break;
155 case 'd':
156 (*info->fprintf_func) (info->stream, "$%s",
157 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
158 break;
160 case 'z':
161 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
162 break;
164 case '<':
165 (*info->fprintf_func) (info->stream, "0x%x",
166 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
167 break;
169 case 'c':
170 (*info->fprintf_func) (info->stream, "0x%x",
171 (l >> OP_SH_CODE) & OP_MASK_CODE);
172 break;
175 case 'q':
176 (*info->fprintf_func) (info->stream, "0x%x",
177 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
178 break;
180 case 'C':
181 (*info->fprintf_func) (info->stream, "0x%x",
182 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
183 break;
185 case 'B':
186 (*info->fprintf_func) (info->stream, "0x%x",
187 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
188 break;
190 case 'S':
191 case 'V':
192 (*info->fprintf_func) (info->stream, "$f%d",
193 (l >> OP_SH_FS) & OP_MASK_FS);
194 break;
197 case 'T':
198 case 'W':
199 (*info->fprintf_func) (info->stream, "$f%d",
200 (l >> OP_SH_FT) & OP_MASK_FT);
201 break;
203 case 'D':
204 (*info->fprintf_func) (info->stream, "$f%d",
205 (l >> OP_SH_FD) & OP_MASK_FD);
206 break;
208 case 'R':
209 (*info->fprintf_func) (info->stream, "$f%d",
210 (l >> OP_SH_FR) & OP_MASK_FR);
211 break;
213 case 'E':
214 (*info->fprintf_func) (info->stream, "$%d",
215 (l >> OP_SH_RT) & OP_MASK_RT);
216 break;
218 case 'G':
219 (*info->fprintf_func) (info->stream, "$%d",
220 (l >> OP_SH_RD) & OP_MASK_RD);
221 break;
223 case 'N':
224 (*info->fprintf_func) (info->stream, "$fcc%d",
225 (l >> OP_SH_BCC) & OP_MASK_BCC);
226 break;
228 case 'M':
229 (*info->fprintf_func) (info->stream, "$fcc%d",
230 (l >> OP_SH_CCC) & OP_MASK_CCC);
231 break;
233 case 'P':
234 (*info->fprintf_func) (info->stream, "%d",
235 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
236 break;
239 default:
240 /* xgettext:c-format */
241 (*info->fprintf_func) (info->stream,
242 _("# internal error, undefined modifier(%c)"),
243 *d);
244 break;
248 #if SYMTAB_AVAILABLE
250 /* Figure out the MIPS ISA and CPU based on the machine number.
251 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
253 static void
254 set_mips_isa_type (mach, isa, cputype)
255 int mach;
256 int *isa;
257 int *cputype;
259 int target_processor = 0;
260 int mips_isa = 0;
262 /* Use standard MIPS register names by default. */
263 reg_names = std_reg_names;
265 switch (mach)
267 case bfd_mach_mips3000:
268 target_processor = 3000;
269 mips_isa = 1;
270 break;
271 case bfd_mach_mips3900:
272 target_processor = 3900;
273 mips_isa = 1;
274 break;
275 case bfd_mach_mips4000:
276 target_processor = 4000;
277 mips_isa = 3;
278 break;
279 case bfd_mach_mips4010:
280 target_processor = 4010;
281 mips_isa = 2;
282 break;
283 case bfd_mach_mips4100:
284 target_processor = 4100;
285 mips_isa = 3;
286 break;
287 case bfd_mach_mips4111:
288 target_processor = 4100;
289 mips_isa = 3;
290 break;
291 case bfd_mach_mips4300:
292 target_processor = 4300;
293 mips_isa = 3;
294 break;
295 case bfd_mach_mips4400:
296 target_processor = 4400;
297 mips_isa = 3;
298 break;
299 case bfd_mach_mips4600:
300 target_processor = 4600;
301 mips_isa = 3;
302 break;
303 case bfd_mach_mips4650:
304 target_processor = 4650;
305 mips_isa = 3;
306 break;
307 case bfd_mach_mips5000:
308 target_processor = 5000;
309 mips_isa = 4;
310 break;
311 case bfd_mach_mips6000:
312 target_processor = 6000;
313 mips_isa = 2;
314 break;
315 case bfd_mach_mips8000:
316 target_processor = 8000;
317 mips_isa = 4;
318 break;
319 case bfd_mach_mips10000:
320 target_processor = 10000;
321 mips_isa = 4;
322 break;
323 case bfd_mach_mips16:
324 target_processor = 16;
325 mips_isa = 3;
326 break;
327 default:
328 target_processor = 3000;
329 mips_isa = 3;
330 break;
334 *isa = mips_isa;
335 *cputype = target_processor;
338 #endif /* SYMTAB_AVAILABLE */
340 /* Print the mips instruction at address MEMADDR in debugged memory,
341 on using INFO. Returns length of the instruction, in bytes, which is
342 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
343 this is little-endian code. */
345 static int
346 _print_insn_mips (memaddr, word, info)
347 bfd_vma memaddr;
348 unsigned long int word;
349 struct disassemble_info *info;
351 register const struct mips_opcode *op;
352 int target_processor, mips_isa;
353 static boolean init = 0;
354 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
356 /* Build a hash table to shorten the search time. */
357 if (! init)
359 unsigned int i;
361 for (i = 0; i <= OP_MASK_OP; i++)
363 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
365 if (op->pinfo == INSN_MACRO)
366 continue;
367 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
369 mips_hash[i] = op;
370 break;
375 init = 1;
378 #if ! SYMTAB_AVAILABLE
379 /* This is running out on a target machine, not in a host tool.
380 FIXME: Where does mips_target_info come from? */
381 target_processor = mips_target_info.processor;
382 mips_isa = mips_target_info.isa;
383 #else
384 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
385 #endif
387 info->bytes_per_chunk = 4;
388 info->display_endian = info->endian;
390 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
391 if (op != NULL)
393 for (; op < &mips_opcodes[NUMOPCODES]; op++)
395 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
397 register const char *d;
399 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
400 continue;
402 (*info->fprintf_func) (info->stream, "%s", op->name);
404 d = op->args;
405 if (d != NULL && *d != '\0')
407 (*info->fprintf_func) (info->stream, "\t");
408 for (; *d != '\0'; d++)
409 print_insn_arg (d, word, memaddr, info);
412 return 4;
417 /* Handle undefined instructions. */
418 (*info->fprintf_func) (info->stream, "0x%x", word);
419 return 4;
423 /* In an environment where we do not know the symbol type of the
424 instruction we are forced to assume that the low order bit of the
425 instructions' address may mark it as a mips16 instruction. If we
426 are single stepping, or the pc is within the disassembled function,
427 this works. Otherwise, we need a clue. Sometimes. */
430 print_insn_big_mips (memaddr, info)
431 bfd_vma memaddr;
432 struct disassemble_info *info;
434 bfd_byte buffer[4];
435 int status;
437 #if 1
438 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
439 /* Only a few tools will work this way. */
440 if (memaddr & 0x01)
441 return print_insn_mips16 (memaddr, info);
442 #endif
444 #if SYMTAB_AVAILABLE
445 if (info->mach == 16
446 || (info->flavour == bfd_target_elf_flavour
447 && info->symbols != NULL
448 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
449 == STO_MIPS16)))
450 return print_insn_mips16 (memaddr, info);
451 #endif
453 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
454 if (status == 0)
455 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
456 info);
457 else
459 (*info->memory_error_func) (status, memaddr, info);
460 return -1;
465 print_insn_little_mips (memaddr, info)
466 bfd_vma memaddr;
467 struct disassemble_info *info;
469 bfd_byte buffer[4];
470 int status;
473 #if 1
474 if (memaddr & 0x01)
475 return print_insn_mips16 (memaddr, info);
476 #endif
478 #if SYMTAB_AVAILABLE
479 if (info->mach == 16
480 || (info->flavour == bfd_target_elf_flavour
481 && info->symbols != NULL
482 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
483 == STO_MIPS16)))
484 return print_insn_mips16 (memaddr, info);
485 #endif
487 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
488 if (status == 0)
489 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
490 info);
491 else
493 (*info->memory_error_func) (status, memaddr, info);
494 return -1;
498 /* Disassemble mips16 instructions. */
500 static int
501 print_insn_mips16 (memaddr, info)
502 bfd_vma memaddr;
503 struct disassemble_info *info;
505 int status;
506 bfd_byte buffer[2];
507 int length;
508 int insn;
509 boolean use_extend;
510 int extend = 0;
511 const struct mips_opcode *op, *opend;
513 info->bytes_per_chunk = 2;
514 info->display_endian = info->endian;
516 info->insn_info_valid = 1;
517 info->branch_delay_insns = 0;
518 info->data_size = 0;
519 info->insn_type = dis_nonbranch;
520 info->target = 0;
521 info->target2 = 0;
523 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
524 if (status != 0)
526 (*info->memory_error_func) (status, memaddr, info);
527 return -1;
530 length = 2;
532 if (info->endian == BFD_ENDIAN_BIG)
533 insn = bfd_getb16 (buffer);
534 else
535 insn = bfd_getl16 (buffer);
537 /* Handle the extend opcode specially. */
538 use_extend = false;
539 if ((insn & 0xf800) == 0xf000)
541 use_extend = true;
542 extend = insn & 0x7ff;
544 memaddr += 2;
546 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
547 if (status != 0)
549 (*info->fprintf_func) (info->stream, "extend 0x%x",
550 (unsigned int) extend);
551 (*info->memory_error_func) (status, memaddr, info);
552 return -1;
555 if (info->endian == BFD_ENDIAN_BIG)
556 insn = bfd_getb16 (buffer);
557 else
558 insn = bfd_getl16 (buffer);
560 /* Check for an extend opcode followed by an extend opcode. */
561 if ((insn & 0xf800) == 0xf000)
563 (*info->fprintf_func) (info->stream, "extend 0x%x",
564 (unsigned int) extend);
565 info->insn_type = dis_noninsn;
566 return length;
569 length += 2;
572 /* FIXME: Should probably use a hash table on the major opcode here. */
574 opend = mips16_opcodes + bfd_mips16_num_opcodes;
575 for (op = mips16_opcodes; op < opend; op++)
577 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
579 const char *s;
581 if (strchr (op->args, 'a') != NULL)
583 if (use_extend)
585 (*info->fprintf_func) (info->stream, "extend 0x%x",
586 (unsigned int) extend);
587 info->insn_type = dis_noninsn;
588 return length - 2;
591 use_extend = false;
593 memaddr += 2;
595 status = (*info->read_memory_func) (memaddr, buffer, 2,
596 info);
597 if (status == 0)
599 use_extend = true;
600 if (info->endian == BFD_ENDIAN_BIG)
601 extend = bfd_getb16 (buffer);
602 else
603 extend = bfd_getl16 (buffer);
604 length += 2;
608 (*info->fprintf_func) (info->stream, "%s", op->name);
609 if (op->args[0] != '\0')
610 (*info->fprintf_func) (info->stream, "\t");
612 for (s = op->args; *s != '\0'; s++)
614 if (*s == ','
615 && s[1] == 'w'
616 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
617 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
619 /* Skip the register and the comma. */
620 ++s;
621 continue;
623 if (*s == ','
624 && s[1] == 'v'
625 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
626 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
628 /* Skip the register and the comma. */
629 ++s;
630 continue;
632 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
633 info);
636 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
638 info->branch_delay_insns = 1;
639 if (info->insn_type != dis_jsr)
640 info->insn_type = dis_branch;
643 return length;
647 if (use_extend)
648 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
649 (*info->fprintf_func) (info->stream, "0x%x", insn);
650 info->insn_type = dis_noninsn;
652 return length;
655 /* Disassemble an operand for a mips16 instruction. */
657 static void
658 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
659 int type;
660 const struct mips_opcode *op;
661 int l;
662 boolean use_extend;
663 int extend;
664 bfd_vma memaddr;
665 struct disassemble_info *info;
667 switch (type)
669 case ',':
670 case '(':
671 case ')':
672 (*info->fprintf_func) (info->stream, "%c", type);
673 break;
675 case 'y':
676 case 'w':
677 (*info->fprintf_func) (info->stream, "$%s",
678 mips16_reg_names[((l >> MIPS16OP_SH_RY)
679 & MIPS16OP_MASK_RY)]);
680 break;
682 case 'x':
683 case 'v':
684 (*info->fprintf_func) (info->stream, "$%s",
685 mips16_reg_names[((l >> MIPS16OP_SH_RX)
686 & MIPS16OP_MASK_RX)]);
687 break;
689 case 'z':
690 (*info->fprintf_func) (info->stream, "$%s",
691 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
692 & MIPS16OP_MASK_RZ)]);
693 break;
695 case 'Z':
696 (*info->fprintf_func) (info->stream, "$%s",
697 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
698 & MIPS16OP_MASK_MOVE32Z)]);
699 break;
701 case '0':
702 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
703 break;
705 case 'S':
706 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
707 break;
709 case 'P':
710 (*info->fprintf_func) (info->stream, "$pc");
711 break;
713 case 'R':
714 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
715 break;
717 case 'X':
718 (*info->fprintf_func) (info->stream, "$%s",
719 reg_names[((l >> MIPS16OP_SH_REGR32)
720 & MIPS16OP_MASK_REGR32)]);
721 break;
723 case 'Y':
724 (*info->fprintf_func) (info->stream, "$%s",
725 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
726 break;
728 case '<':
729 case '>':
730 case '[':
731 case ']':
732 case '4':
733 case '5':
734 case 'H':
735 case 'W':
736 case 'D':
737 case 'j':
738 case '6':
739 case '8':
740 case 'V':
741 case 'C':
742 case 'U':
743 case 'k':
744 case 'K':
745 case 'p':
746 case 'q':
747 case 'A':
748 case 'B':
749 case 'E':
751 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
753 shift = 0;
754 signedp = 0;
755 extbits = 16;
756 pcrel = 0;
757 extu = 0;
758 branch = 0;
759 switch (type)
761 case '<':
762 nbits = 3;
763 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
764 extbits = 5;
765 extu = 1;
766 break;
767 case '>':
768 nbits = 3;
769 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
770 extbits = 5;
771 extu = 1;
772 break;
773 case '[':
774 nbits = 3;
775 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
776 extbits = 6;
777 extu = 1;
778 break;
779 case ']':
780 nbits = 3;
781 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
782 extbits = 6;
783 extu = 1;
784 break;
785 case '4':
786 nbits = 4;
787 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
788 signedp = 1;
789 extbits = 15;
790 break;
791 case '5':
792 nbits = 5;
793 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
794 info->insn_type = dis_dref;
795 info->data_size = 1;
796 break;
797 case 'H':
798 nbits = 5;
799 shift = 1;
800 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
801 info->insn_type = dis_dref;
802 info->data_size = 2;
803 break;
804 case 'W':
805 nbits = 5;
806 shift = 2;
807 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
808 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
809 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
811 info->insn_type = dis_dref;
812 info->data_size = 4;
814 break;
815 case 'D':
816 nbits = 5;
817 shift = 3;
818 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
819 info->insn_type = dis_dref;
820 info->data_size = 8;
821 break;
822 case 'j':
823 nbits = 5;
824 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
825 signedp = 1;
826 break;
827 case '6':
828 nbits = 6;
829 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
830 break;
831 case '8':
832 nbits = 8;
833 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
834 break;
835 case 'V':
836 nbits = 8;
837 shift = 2;
838 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
839 /* FIXME: This might be lw, or it might be addiu to $sp or
840 $pc. We assume it's load. */
841 info->insn_type = dis_dref;
842 info->data_size = 4;
843 break;
844 case 'C':
845 nbits = 8;
846 shift = 3;
847 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
848 info->insn_type = dis_dref;
849 info->data_size = 8;
850 break;
851 case 'U':
852 nbits = 8;
853 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
854 extu = 1;
855 break;
856 case 'k':
857 nbits = 8;
858 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
859 signedp = 1;
860 break;
861 case 'K':
862 nbits = 8;
863 shift = 3;
864 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
865 signedp = 1;
866 break;
867 case 'p':
868 nbits = 8;
869 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
870 signedp = 1;
871 pcrel = 1;
872 branch = 1;
873 info->insn_type = dis_condbranch;
874 break;
875 case 'q':
876 nbits = 11;
877 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
878 signedp = 1;
879 pcrel = 1;
880 branch = 1;
881 info->insn_type = dis_branch;
882 break;
883 case 'A':
884 nbits = 8;
885 shift = 2;
886 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
887 pcrel = 1;
888 /* FIXME: This can be lw or la. We assume it is lw. */
889 info->insn_type = dis_dref;
890 info->data_size = 4;
891 break;
892 case 'B':
893 nbits = 5;
894 shift = 3;
895 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
896 pcrel = 1;
897 info->insn_type = dis_dref;
898 info->data_size = 8;
899 break;
900 case 'E':
901 nbits = 5;
902 shift = 2;
903 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
904 pcrel = 1;
905 break;
906 default:
907 abort ();
910 if (! use_extend)
912 if (signedp && immed >= (1 << (nbits - 1)))
913 immed -= 1 << nbits;
914 immed <<= shift;
915 if ((type == '<' || type == '>' || type == '[' || type == ']')
916 && immed == 0)
917 immed = 8;
919 else
921 if (extbits == 16)
922 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
923 else if (extbits == 15)
924 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
925 else
926 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
927 immed &= (1 << extbits) - 1;
928 if (! extu && immed >= (1 << (extbits - 1)))
929 immed -= 1 << extbits;
932 if (! pcrel)
933 (*info->fprintf_func) (info->stream, "%d", immed);
934 else
936 bfd_vma baseaddr;
937 bfd_vma val;
939 if (branch)
941 immed *= 2;
942 baseaddr = memaddr + 2;
944 else if (use_extend)
945 baseaddr = memaddr - 2;
946 else
948 int status;
949 bfd_byte buffer[2];
951 baseaddr = memaddr;
953 /* If this instruction is in the delay slot of a jr
954 instruction, the base address is the address of the
955 jr instruction. If it is in the delay slot of jalr
956 instruction, the base address is the address of the
957 jalr instruction. This test is unreliable: we have
958 no way of knowing whether the previous word is
959 instruction or data. */
960 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
961 info);
962 if (status == 0
963 && (((info->endian == BFD_ENDIAN_BIG
964 ? bfd_getb16 (buffer)
965 : bfd_getl16 (buffer))
966 & 0xf800) == 0x1800))
967 baseaddr = memaddr - 4;
968 else
970 status = (*info->read_memory_func) (memaddr - 2, buffer,
971 2, info);
972 if (status == 0
973 && (((info->endian == BFD_ENDIAN_BIG
974 ? bfd_getb16 (buffer)
975 : bfd_getl16 (buffer))
976 & 0xf81f) == 0xe800))
977 baseaddr = memaddr - 2;
980 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
981 (*info->print_address_func) (val, info);
982 info->target = val;
985 break;
987 case 'a':
988 if (! use_extend)
989 extend = 0;
990 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
991 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
992 info->insn_type = dis_jsr;
993 info->target = (memaddr & 0xf0000000) | l;
994 info->branch_delay_insns = 1;
995 break;
997 case 'l':
998 case 'L':
1000 int need_comma, amask, smask;
1002 need_comma = 0;
1004 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1006 amask = (l >> 3) & 7;
1008 if (amask > 0 && amask < 5)
1010 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1011 if (amask > 1)
1012 (*info->fprintf_func) (info->stream, "-$%s",
1013 reg_names[amask + 3]);
1014 need_comma = 1;
1017 smask = (l >> 1) & 3;
1018 if (smask == 3)
1020 (*info->fprintf_func) (info->stream, "%s??",
1021 need_comma ? "," : "");
1022 need_comma = 1;
1024 else if (smask > 0)
1026 (*info->fprintf_func) (info->stream, "%s$%s",
1027 need_comma ? "," : "",
1028 reg_names[16]);
1029 if (smask > 1)
1030 (*info->fprintf_func) (info->stream, "-$%s",
1031 reg_names[smask + 15]);
1032 need_comma = 1;
1035 if (l & 1)
1037 (*info->fprintf_func) (info->stream, "%s$%s",
1038 need_comma ? "," : "",
1039 reg_names[31]);
1040 need_comma = 1;
1043 if (amask == 5 || amask == 6)
1045 (*info->fprintf_func) (info->stream, "%s$f0",
1046 need_comma ? "," : "");
1047 if (amask == 6)
1048 (*info->fprintf_func) (info->stream, "-$f1");
1051 break;
1053 default:
1054 abort ();