2000-10-31 Philip Blundell <philb@gnu.org>
[binutils.git] / opcodes / mips-dis.c
blob4c76cde4aae60a8c0647d27975aec45f77b8a5b9
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 'm':
181 (*info->fprintf_func) (info->stream, "0x%x",
182 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
183 break;
185 case 'C':
186 (*info->fprintf_func) (info->stream, "0x%x",
187 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
188 break;
190 case 'B':
191 (*info->fprintf_func) (info->stream, "0x%x",
192 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
193 break;
195 case 'S':
196 case 'V':
197 (*info->fprintf_func) (info->stream, "$f%d",
198 (l >> OP_SH_FS) & OP_MASK_FS);
199 break;
202 case 'T':
203 case 'W':
204 (*info->fprintf_func) (info->stream, "$f%d",
205 (l >> OP_SH_FT) & OP_MASK_FT);
206 break;
208 case 'D':
209 (*info->fprintf_func) (info->stream, "$f%d",
210 (l >> OP_SH_FD) & OP_MASK_FD);
211 break;
213 case 'R':
214 (*info->fprintf_func) (info->stream, "$f%d",
215 (l >> OP_SH_FR) & OP_MASK_FR);
216 break;
218 case 'E':
219 (*info->fprintf_func) (info->stream, "$%d",
220 (l >> OP_SH_RT) & OP_MASK_RT);
221 break;
223 case 'G':
224 (*info->fprintf_func) (info->stream, "$%d",
225 (l >> OP_SH_RD) & OP_MASK_RD);
226 break;
228 case 'N':
229 (*info->fprintf_func) (info->stream, "$fcc%d",
230 (l >> OP_SH_BCC) & OP_MASK_BCC);
231 break;
233 case 'M':
234 (*info->fprintf_func) (info->stream, "$fcc%d",
235 (l >> OP_SH_CCC) & OP_MASK_CCC);
236 break;
238 case 'P':
239 (*info->fprintf_func) (info->stream, "%d",
240 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
241 break;
243 case 'H':
244 (*info->fprintf_func) (info->stream, "%d",
245 (l >> OP_SH_SEL) & OP_MASK_SEL);
246 break;
248 default:
249 /* xgettext:c-format */
250 (*info->fprintf_func) (info->stream,
251 _("# internal error, undefined modifier(%c)"),
252 *d);
253 break;
257 #if SYMTAB_AVAILABLE
259 /* Figure out the MIPS ISA and CPU based on the machine number.
260 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
262 static void
263 set_mips_isa_type (mach, isa, cputype)
264 int mach;
265 int *isa;
266 int *cputype;
268 int target_processor = 0;
269 int mips_isa = 0;
271 /* Use standard MIPS register names by default. */
272 reg_names = std_reg_names;
274 switch (mach)
276 case bfd_mach_mips3000:
277 target_processor = CPU_R3000;
278 mips_isa = 1;
279 break;
280 case bfd_mach_mips3900:
281 target_processor = CPU_R3900;
282 mips_isa = 1;
283 break;
284 case bfd_mach_mips4000:
285 target_processor = CPU_R4000;
286 mips_isa = 3;
287 break;
288 case bfd_mach_mips4010:
289 target_processor = CPU_R4010;
290 mips_isa = 2;
291 break;
292 case bfd_mach_mips4100:
293 target_processor = CPU_VR4100;
294 mips_isa = 3;
295 break;
296 case bfd_mach_mips4111:
297 target_processor = CPU_VR4100; /* FIXME: Shouldn't this be CPU_R4111 ??? */
298 mips_isa = 3;
299 break;
300 case bfd_mach_mips4300:
301 target_processor = CPU_R4300;
302 mips_isa = 3;
303 break;
304 case bfd_mach_mips4400:
305 target_processor = CPU_R4400;
306 mips_isa = 3;
307 break;
308 case bfd_mach_mips4600:
309 target_processor = CPU_R4600;
310 mips_isa = 3;
311 break;
312 case bfd_mach_mips4650:
313 target_processor = CPU_R4650;
314 mips_isa = 3;
315 break;
316 case bfd_mach_mips4K:
317 target_processor = CPU_4K;
318 mips_isa = 2;
319 break;
320 case bfd_mach_mips5000:
321 target_processor = CPU_R5000;
322 mips_isa = 4;
323 break;
324 case bfd_mach_mips6000:
325 target_processor = CPU_R6000;
326 mips_isa = 2;
327 break;
328 case bfd_mach_mips8000:
329 target_processor = CPU_R8000;
330 mips_isa = 4;
331 break;
332 case bfd_mach_mips10000:
333 target_processor = CPU_R10000;
334 mips_isa = 4;
335 break;
336 case bfd_mach_mips16:
337 target_processor = CPU_MIPS16;
338 mips_isa = 3;
339 break;
340 default:
341 target_processor = CPU_R3000;
342 mips_isa = 3;
343 break;
346 *isa = mips_isa;
347 *cputype = target_processor;
350 #endif /* SYMTAB_AVAILABLE */
352 /* Print the mips instruction at address MEMADDR in debugged memory,
353 on using INFO. Returns length of the instruction, in bytes, which is
354 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
355 this is little-endian code. */
357 static int
358 _print_insn_mips (memaddr, word, info)
359 bfd_vma memaddr;
360 unsigned long int word;
361 struct disassemble_info *info;
363 register const struct mips_opcode *op;
364 int target_processor, mips_isa;
365 static boolean init = 0;
366 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
368 /* Build a hash table to shorten the search time. */
369 if (! init)
371 unsigned int i;
373 for (i = 0; i <= OP_MASK_OP; i++)
375 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
377 if (op->pinfo == INSN_MACRO)
378 continue;
379 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
381 mips_hash[i] = op;
382 break;
387 init = 1;
390 #if ! SYMTAB_AVAILABLE
391 /* This is running out on a target machine, not in a host tool.
392 FIXME: Where does mips_target_info come from? */
393 target_processor = mips_target_info.processor;
394 mips_isa = mips_target_info.isa;
395 #else
396 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
397 #endif
399 info->bytes_per_chunk = 4;
400 info->display_endian = info->endian;
402 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
403 if (op != NULL)
405 for (; op < &mips_opcodes[NUMOPCODES]; op++)
407 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
409 register const char *d;
411 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
412 continue;
414 (*info->fprintf_func) (info->stream, "%s", op->name);
416 d = op->args;
417 if (d != NULL && *d != '\0')
419 (*info->fprintf_func) (info->stream, "\t");
420 for (; *d != '\0'; d++)
421 print_insn_arg (d, word, memaddr, info);
424 return 4;
429 /* Handle undefined instructions. */
430 (*info->fprintf_func) (info->stream, "0x%x", word);
431 return 4;
435 /* In an environment where we do not know the symbol type of the
436 instruction we are forced to assume that the low order bit of the
437 instructions' address may mark it as a mips16 instruction. If we
438 are single stepping, or the pc is within the disassembled function,
439 this works. Otherwise, we need a clue. Sometimes. */
442 print_insn_big_mips (memaddr, info)
443 bfd_vma memaddr;
444 struct disassemble_info *info;
446 bfd_byte buffer[4];
447 int status;
449 #if 1
450 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
451 /* Only a few tools will work this way. */
452 if (memaddr & 0x01)
453 return print_insn_mips16 (memaddr, info);
454 #endif
456 #if SYMTAB_AVAILABLE
457 if (info->mach == 16
458 || (info->flavour == bfd_target_elf_flavour
459 && info->symbols != NULL
460 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
461 == STO_MIPS16)))
462 return print_insn_mips16 (memaddr, info);
463 #endif
465 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
466 if (status == 0)
467 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
468 info);
469 else
471 (*info->memory_error_func) (status, memaddr, info);
472 return -1;
477 print_insn_little_mips (memaddr, info)
478 bfd_vma memaddr;
479 struct disassemble_info *info;
481 bfd_byte buffer[4];
482 int status;
485 #if 1
486 if (memaddr & 0x01)
487 return print_insn_mips16 (memaddr, info);
488 #endif
490 #if SYMTAB_AVAILABLE
491 if (info->mach == 16
492 || (info->flavour == bfd_target_elf_flavour
493 && info->symbols != NULL
494 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
495 == STO_MIPS16)))
496 return print_insn_mips16 (memaddr, info);
497 #endif
499 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
500 if (status == 0)
501 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
502 info);
503 else
505 (*info->memory_error_func) (status, memaddr, info);
506 return -1;
510 /* Disassemble mips16 instructions. */
512 static int
513 print_insn_mips16 (memaddr, info)
514 bfd_vma memaddr;
515 struct disassemble_info *info;
517 int status;
518 bfd_byte buffer[2];
519 int length;
520 int insn;
521 boolean use_extend;
522 int extend = 0;
523 const struct mips_opcode *op, *opend;
525 info->bytes_per_chunk = 2;
526 info->display_endian = info->endian;
528 info->insn_info_valid = 1;
529 info->branch_delay_insns = 0;
530 info->data_size = 0;
531 info->insn_type = dis_nonbranch;
532 info->target = 0;
533 info->target2 = 0;
535 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
536 if (status != 0)
538 (*info->memory_error_func) (status, memaddr, info);
539 return -1;
542 length = 2;
544 if (info->endian == BFD_ENDIAN_BIG)
545 insn = bfd_getb16 (buffer);
546 else
547 insn = bfd_getl16 (buffer);
549 /* Handle the extend opcode specially. */
550 use_extend = false;
551 if ((insn & 0xf800) == 0xf000)
553 use_extend = true;
554 extend = insn & 0x7ff;
556 memaddr += 2;
558 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
559 if (status != 0)
561 (*info->fprintf_func) (info->stream, "extend 0x%x",
562 (unsigned int) extend);
563 (*info->memory_error_func) (status, memaddr, info);
564 return -1;
567 if (info->endian == BFD_ENDIAN_BIG)
568 insn = bfd_getb16 (buffer);
569 else
570 insn = bfd_getl16 (buffer);
572 /* Check for an extend opcode followed by an extend opcode. */
573 if ((insn & 0xf800) == 0xf000)
575 (*info->fprintf_func) (info->stream, "extend 0x%x",
576 (unsigned int) extend);
577 info->insn_type = dis_noninsn;
578 return length;
581 length += 2;
584 /* FIXME: Should probably use a hash table on the major opcode here. */
586 opend = mips16_opcodes + bfd_mips16_num_opcodes;
587 for (op = mips16_opcodes; op < opend; op++)
589 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
591 const char *s;
593 if (strchr (op->args, 'a') != NULL)
595 if (use_extend)
597 (*info->fprintf_func) (info->stream, "extend 0x%x",
598 (unsigned int) extend);
599 info->insn_type = dis_noninsn;
600 return length - 2;
603 use_extend = false;
605 memaddr += 2;
607 status = (*info->read_memory_func) (memaddr, buffer, 2,
608 info);
609 if (status == 0)
611 use_extend = true;
612 if (info->endian == BFD_ENDIAN_BIG)
613 extend = bfd_getb16 (buffer);
614 else
615 extend = bfd_getl16 (buffer);
616 length += 2;
620 (*info->fprintf_func) (info->stream, "%s", op->name);
621 if (op->args[0] != '\0')
622 (*info->fprintf_func) (info->stream, "\t");
624 for (s = op->args; *s != '\0'; s++)
626 if (*s == ','
627 && s[1] == 'w'
628 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
629 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
631 /* Skip the register and the comma. */
632 ++s;
633 continue;
635 if (*s == ','
636 && s[1] == 'v'
637 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
638 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
640 /* Skip the register and the comma. */
641 ++s;
642 continue;
644 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
645 info);
648 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
650 info->branch_delay_insns = 1;
651 if (info->insn_type != dis_jsr)
652 info->insn_type = dis_branch;
655 return length;
659 if (use_extend)
660 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
661 (*info->fprintf_func) (info->stream, "0x%x", insn);
662 info->insn_type = dis_noninsn;
664 return length;
667 /* Disassemble an operand for a mips16 instruction. */
669 static void
670 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
671 int type;
672 const struct mips_opcode *op;
673 int l;
674 boolean use_extend;
675 int extend;
676 bfd_vma memaddr;
677 struct disassemble_info *info;
679 switch (type)
681 case ',':
682 case '(':
683 case ')':
684 (*info->fprintf_func) (info->stream, "%c", type);
685 break;
687 case 'y':
688 case 'w':
689 (*info->fprintf_func) (info->stream, "$%s",
690 mips16_reg_names[((l >> MIPS16OP_SH_RY)
691 & MIPS16OP_MASK_RY)]);
692 break;
694 case 'x':
695 case 'v':
696 (*info->fprintf_func) (info->stream, "$%s",
697 mips16_reg_names[((l >> MIPS16OP_SH_RX)
698 & MIPS16OP_MASK_RX)]);
699 break;
701 case 'z':
702 (*info->fprintf_func) (info->stream, "$%s",
703 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
704 & MIPS16OP_MASK_RZ)]);
705 break;
707 case 'Z':
708 (*info->fprintf_func) (info->stream, "$%s",
709 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
710 & MIPS16OP_MASK_MOVE32Z)]);
711 break;
713 case '0':
714 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
715 break;
717 case 'S':
718 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
719 break;
721 case 'P':
722 (*info->fprintf_func) (info->stream, "$pc");
723 break;
725 case 'R':
726 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
727 break;
729 case 'X':
730 (*info->fprintf_func) (info->stream, "$%s",
731 reg_names[((l >> MIPS16OP_SH_REGR32)
732 & MIPS16OP_MASK_REGR32)]);
733 break;
735 case 'Y':
736 (*info->fprintf_func) (info->stream, "$%s",
737 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
738 break;
740 case '<':
741 case '>':
742 case '[':
743 case ']':
744 case '4':
745 case '5':
746 case 'H':
747 case 'W':
748 case 'D':
749 case 'j':
750 case '6':
751 case '8':
752 case 'V':
753 case 'C':
754 case 'U':
755 case 'k':
756 case 'K':
757 case 'p':
758 case 'q':
759 case 'A':
760 case 'B':
761 case 'E':
763 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
765 shift = 0;
766 signedp = 0;
767 extbits = 16;
768 pcrel = 0;
769 extu = 0;
770 branch = 0;
771 switch (type)
773 case '<':
774 nbits = 3;
775 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
776 extbits = 5;
777 extu = 1;
778 break;
779 case '>':
780 nbits = 3;
781 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
782 extbits = 5;
783 extu = 1;
784 break;
785 case '[':
786 nbits = 3;
787 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
788 extbits = 6;
789 extu = 1;
790 break;
791 case ']':
792 nbits = 3;
793 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
794 extbits = 6;
795 extu = 1;
796 break;
797 case '4':
798 nbits = 4;
799 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
800 signedp = 1;
801 extbits = 15;
802 break;
803 case '5':
804 nbits = 5;
805 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
806 info->insn_type = dis_dref;
807 info->data_size = 1;
808 break;
809 case 'H':
810 nbits = 5;
811 shift = 1;
812 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
813 info->insn_type = dis_dref;
814 info->data_size = 2;
815 break;
816 case 'W':
817 nbits = 5;
818 shift = 2;
819 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
820 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
821 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
823 info->insn_type = dis_dref;
824 info->data_size = 4;
826 break;
827 case 'D':
828 nbits = 5;
829 shift = 3;
830 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
831 info->insn_type = dis_dref;
832 info->data_size = 8;
833 break;
834 case 'j':
835 nbits = 5;
836 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
837 signedp = 1;
838 break;
839 case '6':
840 nbits = 6;
841 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
842 break;
843 case '8':
844 nbits = 8;
845 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
846 break;
847 case 'V':
848 nbits = 8;
849 shift = 2;
850 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
851 /* FIXME: This might be lw, or it might be addiu to $sp or
852 $pc. We assume it's load. */
853 info->insn_type = dis_dref;
854 info->data_size = 4;
855 break;
856 case 'C':
857 nbits = 8;
858 shift = 3;
859 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
860 info->insn_type = dis_dref;
861 info->data_size = 8;
862 break;
863 case 'U':
864 nbits = 8;
865 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
866 extu = 1;
867 break;
868 case 'k':
869 nbits = 8;
870 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
871 signedp = 1;
872 break;
873 case 'K':
874 nbits = 8;
875 shift = 3;
876 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
877 signedp = 1;
878 break;
879 case 'p':
880 nbits = 8;
881 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
882 signedp = 1;
883 pcrel = 1;
884 branch = 1;
885 info->insn_type = dis_condbranch;
886 break;
887 case 'q':
888 nbits = 11;
889 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
890 signedp = 1;
891 pcrel = 1;
892 branch = 1;
893 info->insn_type = dis_branch;
894 break;
895 case 'A':
896 nbits = 8;
897 shift = 2;
898 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
899 pcrel = 1;
900 /* FIXME: This can be lw or la. We assume it is lw. */
901 info->insn_type = dis_dref;
902 info->data_size = 4;
903 break;
904 case 'B':
905 nbits = 5;
906 shift = 3;
907 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
908 pcrel = 1;
909 info->insn_type = dis_dref;
910 info->data_size = 8;
911 break;
912 case 'E':
913 nbits = 5;
914 shift = 2;
915 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
916 pcrel = 1;
917 break;
918 default:
919 abort ();
922 if (! use_extend)
924 if (signedp && immed >= (1 << (nbits - 1)))
925 immed -= 1 << nbits;
926 immed <<= shift;
927 if ((type == '<' || type == '>' || type == '[' || type == ']')
928 && immed == 0)
929 immed = 8;
931 else
933 if (extbits == 16)
934 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
935 else if (extbits == 15)
936 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
937 else
938 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
939 immed &= (1 << extbits) - 1;
940 if (! extu && immed >= (1 << (extbits - 1)))
941 immed -= 1 << extbits;
944 if (! pcrel)
945 (*info->fprintf_func) (info->stream, "%d", immed);
946 else
948 bfd_vma baseaddr;
949 bfd_vma val;
951 if (branch)
953 immed *= 2;
954 baseaddr = memaddr + 2;
956 else if (use_extend)
957 baseaddr = memaddr - 2;
958 else
960 int status;
961 bfd_byte buffer[2];
963 baseaddr = memaddr;
965 /* If this instruction is in the delay slot of a jr
966 instruction, the base address is the address of the
967 jr instruction. If it is in the delay slot of jalr
968 instruction, the base address is the address of the
969 jalr instruction. This test is unreliable: we have
970 no way of knowing whether the previous word is
971 instruction or data. */
972 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
973 info);
974 if (status == 0
975 && (((info->endian == BFD_ENDIAN_BIG
976 ? bfd_getb16 (buffer)
977 : bfd_getl16 (buffer))
978 & 0xf800) == 0x1800))
979 baseaddr = memaddr - 4;
980 else
982 status = (*info->read_memory_func) (memaddr - 2, buffer,
983 2, info);
984 if (status == 0
985 && (((info->endian == BFD_ENDIAN_BIG
986 ? bfd_getb16 (buffer)
987 : bfd_getl16 (buffer))
988 & 0xf81f) == 0xe800))
989 baseaddr = memaddr - 2;
992 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
993 (*info->print_address_func) (val, info);
994 info->target = val;
997 break;
999 case 'a':
1000 if (! use_extend)
1001 extend = 0;
1002 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1003 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1004 info->insn_type = dis_jsr;
1005 info->target = (memaddr & 0xf0000000) | l;
1006 info->branch_delay_insns = 1;
1007 break;
1009 case 'l':
1010 case 'L':
1012 int need_comma, amask, smask;
1014 need_comma = 0;
1016 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1018 amask = (l >> 3) & 7;
1020 if (amask > 0 && amask < 5)
1022 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1023 if (amask > 1)
1024 (*info->fprintf_func) (info->stream, "-$%s",
1025 reg_names[amask + 3]);
1026 need_comma = 1;
1029 smask = (l >> 1) & 3;
1030 if (smask == 3)
1032 (*info->fprintf_func) (info->stream, "%s??",
1033 need_comma ? "," : "");
1034 need_comma = 1;
1036 else if (smask > 0)
1038 (*info->fprintf_func) (info->stream, "%s$%s",
1039 need_comma ? "," : "",
1040 reg_names[16]);
1041 if (smask > 1)
1042 (*info->fprintf_func) (info->stream, "-$%s",
1043 reg_names[smask + 15]);
1044 need_comma = 1;
1047 if (l & 1)
1049 (*info->fprintf_func) (info->stream, "%s$%s",
1050 need_comma ? "," : "",
1051 reg_names[31]);
1052 need_comma = 1;
1055 if (amask == 5 || amask == 6)
1057 (*info->fprintf_func) (info->stream, "%s$f0",
1058 need_comma ? "," : "");
1059 if (amask == 6)
1060 (*info->fprintf_func) (info->stream, "-$f1");
1063 break;
1065 default:
1066 abort ();