Initial revision
[binutils.git] / opcodes / mips-dis.c
blob1e3577cec32dc90a500e7101f485cf4eb9ee81f0
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 (*info->fprintf_func) (info->stream, "%c", *d);
91 break;
93 case 's':
94 case 'b':
95 case 'r':
96 case 'v':
97 (*info->fprintf_func) (info->stream, "$%s",
98 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
99 break;
101 case 't':
102 case 'w':
103 (*info->fprintf_func) (info->stream, "$%s",
104 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
105 break;
107 case 'i':
108 case 'u':
109 (*info->fprintf_func) (info->stream, "0x%x",
110 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
111 break;
113 case 'j': /* same as i, but sign-extended */
114 case 'o':
115 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
116 if (delta & 0x8000)
117 delta |= ~0xffff;
118 (*info->fprintf_func) (info->stream, "%d",
119 delta);
120 break;
122 case 'h':
123 (*info->fprintf_func) (info->stream, "0x%x",
124 (unsigned int) ((l >> OP_SH_PREFX)
125 & OP_MASK_PREFX));
126 break;
128 case 'k':
129 (*info->fprintf_func) (info->stream, "0x%x",
130 (unsigned int) ((l >> OP_SH_CACHE)
131 & OP_MASK_CACHE));
132 break;
134 case 'a':
135 (*info->print_address_func)
136 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
137 info);
138 break;
140 case 'p':
141 /* sign extend the displacement */
142 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
143 if (delta & 0x8000)
144 delta |= ~0xffff;
145 (*info->print_address_func)
146 ((delta << 2) + pc + 4,
147 info);
148 break;
150 case 'd':
151 (*info->fprintf_func) (info->stream, "$%s",
152 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
153 break;
155 case 'z':
156 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
157 break;
159 case '<':
160 (*info->fprintf_func) (info->stream, "0x%x",
161 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
162 break;
164 case 'c':
165 (*info->fprintf_func) (info->stream, "0x%x",
166 (l >> OP_SH_CODE) & OP_MASK_CODE);
167 break;
170 case 'q':
171 (*info->fprintf_func) (info->stream, "0x%x",
172 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
173 break;
175 case 'C':
176 (*info->fprintf_func) (info->stream, "0x%x",
177 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
178 break;
180 case 'B':
181 (*info->fprintf_func) (info->stream, "0x%x",
182 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
183 break;
185 case 'S':
186 case 'V':
187 (*info->fprintf_func) (info->stream, "$f%d",
188 (l >> OP_SH_FS) & OP_MASK_FS);
189 break;
192 case 'T':
193 case 'W':
194 (*info->fprintf_func) (info->stream, "$f%d",
195 (l >> OP_SH_FT) & OP_MASK_FT);
196 break;
198 case 'D':
199 (*info->fprintf_func) (info->stream, "$f%d",
200 (l >> OP_SH_FD) & OP_MASK_FD);
201 break;
203 case 'R':
204 (*info->fprintf_func) (info->stream, "$f%d",
205 (l >> OP_SH_FR) & OP_MASK_FR);
206 break;
208 case 'E':
209 (*info->fprintf_func) (info->stream, "$%d",
210 (l >> OP_SH_RT) & OP_MASK_RT);
211 break;
213 case 'G':
214 (*info->fprintf_func) (info->stream, "$%d",
215 (l >> OP_SH_RD) & OP_MASK_RD);
216 break;
218 case 'N':
219 (*info->fprintf_func) (info->stream, "$fcc%d",
220 (l >> OP_SH_BCC) & OP_MASK_BCC);
221 break;
223 case 'M':
224 (*info->fprintf_func) (info->stream, "$fcc%d",
225 (l >> OP_SH_CCC) & OP_MASK_CCC);
226 break;
228 case 'P':
229 (*info->fprintf_func) (info->stream, "%d",
230 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
231 break;
234 default:
235 /* xgettext:c-format */
236 (*info->fprintf_func) (info->stream,
237 _("# internal error, undefined modifier(%c)"),
238 *d);
239 break;
243 #if SYMTAB_AVAILABLE
245 /* Figure out the MIPS ISA and CPU based on the machine number.
246 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
248 static void
249 set_mips_isa_type (mach, isa, cputype)
250 int mach;
251 int *isa;
252 int *cputype;
254 int target_processor = 0;
255 int mips_isa = 0;
257 switch (mach)
259 case bfd_mach_mips3000:
260 target_processor = 3000;
261 mips_isa = 1;
262 break;
263 case bfd_mach_mips3900:
264 target_processor = 3900;
265 mips_isa = 1;
266 break;
267 case bfd_mach_mips4000:
268 target_processor = 4000;
269 mips_isa = 3;
270 break;
271 case bfd_mach_mips4010:
272 target_processor = 4010;
273 mips_isa = 2;
274 break;
275 case bfd_mach_mips4100:
276 target_processor = 4100;
277 mips_isa = 3;
278 break;
279 case bfd_mach_mips4111:
280 target_processor = 4100;
281 mips_isa = 3;
282 break;
283 case bfd_mach_mips4300:
284 target_processor = 4300;
285 mips_isa = 3;
286 break;
287 case bfd_mach_mips4400:
288 target_processor = 4400;
289 mips_isa = 3;
290 break;
291 case bfd_mach_mips4600:
292 target_processor = 4600;
293 mips_isa = 3;
294 break;
295 case bfd_mach_mips4650:
296 target_processor = 4650;
297 mips_isa = 3;
298 break;
299 case bfd_mach_mips5000:
300 target_processor = 5000;
301 mips_isa = 4;
302 break;
303 case bfd_mach_mips6000:
304 target_processor = 6000;
305 mips_isa = 2;
306 break;
307 case bfd_mach_mips8000:
308 target_processor = 8000;
309 mips_isa = 4;
310 break;
311 case bfd_mach_mips10000:
312 target_processor = 10000;
313 mips_isa = 4;
314 break;
315 case bfd_mach_mips16:
316 target_processor = 16;
317 mips_isa = 3;
318 break;
319 default:
320 target_processor = 3000;
321 mips_isa = 3;
322 break;
326 *isa = mips_isa;
327 *cputype = target_processor;
330 #endif /* SYMTAB_AVAILABLE */
332 /* Print the mips instruction at address MEMADDR in debugged memory,
333 on using INFO. Returns length of the instruction, in bytes, which is
334 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
335 this is little-endian code. */
337 static int
338 _print_insn_mips (memaddr, word, info)
339 bfd_vma memaddr;
340 unsigned long int word;
341 struct disassemble_info *info;
343 register const struct mips_opcode *op;
344 int target_processor, mips_isa;
345 static boolean init = 0;
346 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
348 /* Build a hash table to shorten the search time. */
349 if (! init)
351 unsigned int i;
353 for (i = 0; i <= OP_MASK_OP; i++)
355 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
357 if (op->pinfo == INSN_MACRO)
358 continue;
359 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
361 mips_hash[i] = op;
362 break;
367 init = 1;
370 #if ! SYMTAB_AVAILABLE
371 /* This is running out on a target machine, not in a host tool.
372 FIXME: Where does mips_target_info come from? */
373 target_processor = mips_target_info.processor;
374 mips_isa = mips_target_info.isa;
375 #else
376 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
377 #endif
379 info->bytes_per_chunk = 4;
380 info->display_endian = info->endian;
382 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
383 if (op != NULL)
385 for (; op < &mips_opcodes[NUMOPCODES]; op++)
387 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
389 register const char *d;
390 int insn_isa;
392 if ((op->membership & INSN_ISA) == INSN_ISA1)
393 insn_isa = 1;
394 else if ((op->membership & INSN_ISA) == INSN_ISA2)
395 insn_isa = 2;
396 else if ((op->membership & INSN_ISA) == INSN_ISA3)
397 insn_isa = 3;
398 else if ((op->membership & INSN_ISA) == INSN_ISA4)
399 insn_isa = 4;
400 else
401 insn_isa = 15;
403 if (insn_isa > mips_isa
404 && (target_processor == 4650
405 && op->membership & INSN_4650) == 0
406 && (target_processor == 4010
407 && op->membership & INSN_4010) == 0
408 && (target_processor == 4100
409 && op->membership & INSN_4100) == 0
410 && (target_processor == 3900
411 && op->membership & INSN_3900) == 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 ();