update copyright date
[external/binutils.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2    Copyright 1989, 91-97, 1998 Free Software Foundation, Inc.
3    Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
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.
11
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.
16
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.  */
20
21 #include <ansidecl.h>
22 #include "sysdep.h"
23 #include "dis-asm.h"
24 #include "opcode/mips.h"
25
26 /* FIXME: These are needed to figure out if this is a mips16 symbol or
27    not.  It would be better to think of a cleaner way to do this.  */
28 #include "elf-bfd.h"
29 #include "elf/mips.h"
30
31 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
32 static void print_mips16_insn_arg
33   PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
34            struct disassemble_info *));
35
36 /* Mips instructions are never longer than this many bytes.  */
37 #define MAXLEN 4
38
39 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
40                                     struct disassemble_info *));
41 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
42                                      struct disassemble_info *));
43
44 \f
45 /* FIXME: This should be shared with gdb somehow.  */
46 #define REGISTER_NAMES  \
47     {   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3", \
48         "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7", \
49         "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7", \
50         "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra", \
51         "sr",   "lo",   "hi",   "bad",  "cause","pc",    \
52         "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7", \
53         "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15", \
54         "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",\
55         "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",\
56         "fsr",  "fir",  "fp",   "inx",  "rand", "tlblo","ctxt", "tlbhi",\
57         "epc",  "prid"\
58     }
59
60 static CONST char * CONST reg_names[] = REGISTER_NAMES;
61
62 /* The mips16 register names.  */
63 static const char * const mips16_reg_names[] =
64 {
65   "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
66 };
67 \f
68 /* subroutine */
69 static void
70 print_insn_arg (d, l, pc, info)
71      const char *d;
72      register unsigned long int l;
73      bfd_vma pc;
74      struct disassemble_info *info;
75 {
76   int delta;
77
78   switch (*d)
79     {
80     case ',':
81     case '(':
82     case ')':
83       /* start-sanitize-vr5400 */
84     case '[':
85     case ']':
86       /* end-sanitize-vr5400 */
87       (*info->fprintf_func) (info->stream, "%c", *d);
88       break;
89
90     case 's':
91     case 'b':
92     case 'r':
93     case 'v':
94       (*info->fprintf_func) (info->stream, "$%s",
95                              reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
96       break;
97
98     case 't':
99     case 'w':
100       (*info->fprintf_func) (info->stream, "$%s",
101                              reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
102       break;
103
104     case 'i':
105     case 'u':
106       (*info->fprintf_func) (info->stream, "0x%x",
107                         (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
108       break;
109
110     case 'j': /* same as i, but sign-extended */
111     case 'o':
112       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
113       if (delta & 0x8000)
114         delta |= ~0xffff;
115       (*info->fprintf_func) (info->stream, "%d",
116                              delta);
117       break;
118
119     case 'h':
120       (*info->fprintf_func) (info->stream, "0x%x",
121                              (unsigned int) ((l >> OP_SH_PREFX)
122                                              & OP_MASK_PREFX));
123       break;
124
125     case 'k':
126       (*info->fprintf_func) (info->stream, "0x%x",
127                              (unsigned int) ((l >> OP_SH_CACHE)
128                                              & OP_MASK_CACHE));
129       break;
130
131     case 'a':
132       (*info->print_address_func)
133         (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
134          info);
135       break;
136
137     case 'p':
138       /* sign extend the displacement */
139       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
140       if (delta & 0x8000)
141         delta |= ~0xffff;
142       (*info->print_address_func)
143         ((delta << 2) + pc + 4,
144          info);
145       break;
146
147     case 'd':
148       (*info->fprintf_func) (info->stream, "$%s",
149                              reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
150       break;
151
152     case 'z':
153       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
154       break;
155
156     case '<':
157       (*info->fprintf_func) (info->stream, "0x%x",
158                              (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
159       break;
160
161     case 'c':
162       (*info->fprintf_func) (info->stream, "0x%x",
163                              (l >> OP_SH_CODE) & OP_MASK_CODE);
164       break;
165
166     case 'C':
167       (*info->fprintf_func) (info->stream, "0x%x",
168                              (l >> OP_SH_COPZ) & OP_MASK_COPZ);
169       break;
170
171     case 'B':
172       (*info->fprintf_func) (info->stream, "0x%x",
173                              (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
174       break;
175
176     case 'S':
177     case 'V':
178       (*info->fprintf_func) (info->stream, "$f%d",
179                              (l >> OP_SH_FS) & OP_MASK_FS);
180       break;
181
182     case 'T':
183     case 'W':
184       (*info->fprintf_func) (info->stream, "$f%d",
185                              (l >> OP_SH_FT) & OP_MASK_FT);
186       break;
187
188     case 'D':
189       (*info->fprintf_func) (info->stream, "$f%d",
190                              (l >> OP_SH_FD) & OP_MASK_FD);
191       break;
192
193     case 'R':
194       (*info->fprintf_func) (info->stream, "$f%d",
195                              (l >> OP_SH_FR) & OP_MASK_FR);
196       break;
197
198     case 'E':
199       (*info->fprintf_func) (info->stream, "$%d",
200                              (l >> OP_SH_RT) & OP_MASK_RT);
201       break;
202
203     case 'G':
204       (*info->fprintf_func) (info->stream, "$%d",
205                              (l >> OP_SH_RD) & OP_MASK_RD);
206       break;
207
208     case 'N':
209       (*info->fprintf_func) (info->stream, "$fcc%d",
210                              (l >> OP_SH_BCC) & OP_MASK_BCC);
211       break;
212
213     case 'M':
214       (*info->fprintf_func) (info->stream, "$fcc%d",
215                              (l >> OP_SH_CCC) & OP_MASK_CCC);
216       break;
217
218     case 'P':
219       (*info->fprintf_func) (info->stream, "$%d",
220                              (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
221       break;
222
223       /* start-sanitize-vr5400 */
224     case 'e':
225       (*info->fprintf_func) (info->stream, "%d",
226                              (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
227       break;
228
229     case '%':
230       (*info->fprintf_func) (info->stream, "%d",
231                              (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
232       break;
233       /* end-sanitize-vr5400 */
234
235     default:
236       (*info->fprintf_func) (info->stream,
237                              "# internal error, undefined modifier(%c)", *d);
238       break;
239     }
240 }
241 \f
242 /* Print the mips instruction at address MEMADDR in debugged memory,
243    on using INFO.  Returns length of the instruction, in bytes, which is
244    always 4.  BIGENDIAN must be 1 if this is big-endian code, 0 if
245    this is little-endian code.  */
246
247 static int
248 _print_insn_mips (memaddr, word, info)
249      bfd_vma memaddr;
250      unsigned long int word;
251      struct disassemble_info *info;
252 {
253   register const struct mips_opcode *op;
254   int target_processor, mips_isa;
255   static boolean init = 0;
256   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
257
258   /* Build a hash table to shorten the search time.  */
259   if (! init)
260     {
261       unsigned int i;
262
263       for (i = 0; i <= OP_MASK_OP; i++)
264         {
265           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
266             {
267               if (op->pinfo == INSN_MACRO)
268                 continue;
269               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
270                 {
271                   mips_hash[i] = op;
272                   break;
273                 }
274             }
275         }
276
277       init = 1;
278     }
279
280   switch (info->mach)
281     {
282       /* start-sanitize-tx19 */
283       case bfd_mach_mips1900:
284         target_processor = 1900;
285         mips_isa = 1;
286         break;
287       /* end-sanitize-tx19 */
288       case bfd_mach_mips3000:
289         target_processor = 3000;
290         mips_isa = 1;
291         break;
292       case bfd_mach_mips3900:
293         target_processor = 3900;
294         mips_isa = 1;
295         break;
296       case bfd_mach_mips4000:
297         target_processor = 4000;
298         mips_isa = 3;
299         break;
300       case bfd_mach_mips4010:
301         target_processor = 4010;
302         mips_isa = 2;
303         break;
304       case bfd_mach_mips4100:
305         target_processor = 4100;
306         mips_isa = 3;
307         break;
308       case bfd_mach_mips4300:
309         target_processor = 4300;
310         mips_isa = 3;
311         break;
312       case bfd_mach_mips4400:
313         target_processor = 4400;
314         mips_isa = 3;
315         break;
316       case bfd_mach_mips4600:
317         target_processor = 4600;
318         mips_isa = 3;
319         break;
320       case bfd_mach_mips4650:
321         target_processor = 4650;
322         mips_isa = 3;
323         break;
324       /* start-sanitize-tx49 */
325       case bfd_mach_mips4900:
326         target_processor = 4900;
327         mips_isa = 3;
328         break;
329       /* end-sanitize-tx49 */
330       case bfd_mach_mips5000:
331         target_processor = 5000;
332         mips_isa = 4;
333         break;
334       /* start-sanitize-vr5400 */
335       case bfd_mach_mips5400:
336         target_processor = 5400;
337         mips_isa = 3;
338         break;
339       /* end-sanitize-vr5400 */
340       /* start-sanitize-r5900 */
341       case bfd_mach_mips5900:
342         target_processor = 5900;
343         mips_isa = 3;
344         break;
345       /* end-sanitize-r5900 */
346       case bfd_mach_mips6000:
347         target_processor = 6000;
348         mips_isa = 2;
349         break;
350       case bfd_mach_mips8000:
351         target_processor = 8000;
352         mips_isa = 4;
353         break;
354       case bfd_mach_mips10000:
355         target_processor = 10000;
356         mips_isa = 4;
357         break;
358       case bfd_mach_mips16:
359         target_processor = 16;
360         mips_isa = 3;
361         break;
362       default:
363         target_processor = 3000;
364         mips_isa = 3;
365         break;
366
367     }
368
369   info->bytes_per_chunk = 4;
370   info->display_endian = info->endian;
371
372   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
373   if (op != NULL)
374     {
375       for (; op < &mips_opcodes[NUMOPCODES]; op++)
376         {
377           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
378             {
379               register const char *d;
380               int insn_isa;
381
382               if ((op->membership & INSN_ISA) == INSN_ISA1)
383                 insn_isa = 1;
384               else if ((op->membership & INSN_ISA) == INSN_ISA2)
385                 insn_isa = 2;
386               else if ((op->membership & INSN_ISA) == INSN_ISA3)
387                 insn_isa = 3;
388               else if ((op->membership & INSN_ISA) == INSN_ISA4)
389                 insn_isa = 4;
390               else
391                 insn_isa = 15;
392
393               if (insn_isa > mips_isa
394                   && (target_processor == 4650
395                       && op->membership & INSN_4650) == 0
396                   && (target_processor == 4010
397                       && op->membership & INSN_4010) == 0
398                   && (target_processor == 4100
399                       && op->membership & INSN_4100) == 0
400                   /* start-sanitize-vr5400 */
401                   && (target_processor == 5400
402                       && op->membership & INSN_5400) == 0
403                   /* end-santiize-vr5400 */
404                   /* start-sanitize-r5900 */
405                   && (target_processor == 5900
406                       && op->membership & INSN_5900) == 0
407                   /* end-sanitize-r5900 */
408                   /* start-sanitize-tx49 */
409                   && (target_processor == 4900
410                       && op->membership & INSN_4900) == 0
411                   /* end-sanitize-tx49 */
412                   && (target_processor == 3900
413                       && op->membership & INSN_3900) == 0)
414                 continue;
415
416               (*info->fprintf_func) (info->stream, "%s", op->name);
417
418               d = op->args;
419               if (d != NULL && *d != '\0')
420                 {
421                   (*info->fprintf_func) (info->stream, "\t");
422                   for (; *d != '\0'; d++)
423                     print_insn_arg (d, word, memaddr, info);
424                 }
425
426               return 4;
427             }
428         }
429     }
430
431   /* Handle undefined instructions.  */
432   (*info->fprintf_func) (info->stream, "0x%x", word);
433   return 4;
434 }
435
436 int
437 print_insn_big_mips (memaddr, info)
438      bfd_vma memaddr;
439      struct disassemble_info *info;
440 {
441   bfd_byte buffer[4];
442   int status;
443
444   if (info->mach == 16
445       || (info->flavour == bfd_target_elf_flavour
446           && info->symbol != NULL
447           && (((elf_symbol_type *) info->symbol)->internal_elf_sym.st_other
448               == STO_MIPS16)))
449     return print_insn_mips16 (memaddr, info);
450
451   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
452   if (status == 0)
453     return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
454                              info);
455   else
456     {
457       (*info->memory_error_func) (status, memaddr, info);
458       return -1;
459     }
460 }
461
462 int
463 print_insn_little_mips (memaddr, info)
464      bfd_vma memaddr;
465      struct disassemble_info *info;
466 {
467   bfd_byte buffer[4];
468   int status;
469
470   /* start-sanitize-sky */
471 #ifdef ARCH_dvp
472   if (bfd_mach_dvp_p (info->mach)
473       || (info->flavour == bfd_target_elf_flavour
474           && info->symbol != NULL
475           && MIPS_STO_DVP_P (((elf_symbol_type *) info->symbol)->internal_elf_sym.st_other)))
476     return print_insn_dvp (memaddr, info);
477 #endif
478   /* end-sanitize-sky */
479
480   if (info->mach == 16
481       || (info->flavour == bfd_target_elf_flavour
482           && info->symbol != NULL
483           && (((elf_symbol_type *) info->symbol)->internal_elf_sym.st_other
484               == STO_MIPS16)))
485     return print_insn_mips16 (memaddr, info);
486
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
492     {
493       (*info->memory_error_func) (status, memaddr, info);
494       return -1;
495     }
496 }
497 \f
498 /* Disassemble mips16 instructions.  */
499
500 static int
501 print_insn_mips16 (memaddr, info)
502      bfd_vma memaddr;
503      struct disassemble_info *info;
504 {
505   int status;
506   bfd_byte buffer[2];
507   int length;
508   int insn;
509   boolean use_extend;
510   int extend;
511   const struct mips_opcode *op, *opend;
512
513   info->bytes_per_chunk = 2;
514   info->display_endian = info->endian;
515
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;
522
523   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
524   if (status != 0)
525     {
526       (*info->memory_error_func) (status, memaddr, info);
527       return -1;
528     }
529
530   length = 2;
531
532   if (info->endian == BFD_ENDIAN_BIG)
533     insn = bfd_getb16 (buffer);
534   else
535     insn = bfd_getl16 (buffer);
536
537   /* Handle the extend opcode specially.  */
538   use_extend = false;
539   if ((insn & 0xf800) == 0xf000)
540     {
541       use_extend = true;
542       extend = insn & 0x7ff;
543
544       memaddr += 2;
545
546       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
547       if (status != 0)
548         {
549           (*info->fprintf_func) (info->stream, "extend 0x%x",
550                                  (unsigned int) extend);
551           (*info->memory_error_func) (status, memaddr, info);
552           return -1;
553         }
554
555       if (info->endian == BFD_ENDIAN_BIG)
556         insn = bfd_getb16 (buffer);
557       else
558         insn = bfd_getl16 (buffer);
559
560       /* Check for an extend opcode followed by an extend opcode.  */
561       if ((insn & 0xf800) == 0xf000)
562         {
563           (*info->fprintf_func) (info->stream, "extend 0x%x",
564                                  (unsigned int) extend);
565           info->insn_type = dis_noninsn;
566           return length;
567         }
568
569       length += 2;
570     }
571
572   /* FIXME: Should probably use a hash table on the major opcode here.  */
573
574   opend = mips16_opcodes + bfd_mips16_num_opcodes;
575   for (op = mips16_opcodes; op < opend; op++)
576     {
577       if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
578         {
579           const char *s;
580
581           if (strchr (op->args, 'a') != NULL)
582             {
583               if (use_extend)
584                 {
585                   (*info->fprintf_func) (info->stream, "extend 0x%x",
586                                          (unsigned int) extend);
587                   info->insn_type = dis_noninsn;
588                   return length - 2;
589                 }
590
591               use_extend = false;
592
593               memaddr += 2;
594
595               status = (*info->read_memory_func) (memaddr, buffer, 2,
596                                                   info);
597               if (status == 0)
598                 {
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;
605                 }
606             }
607
608           (*info->fprintf_func) (info->stream, "%s", op->name);
609           if (op->args[0] != '\0')
610             (*info->fprintf_func) (info->stream, "\t");
611
612           for (s = op->args; *s != '\0'; s++)
613             {
614               if (*s == ','
615                   && s[1] == 'w'
616                   && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
617                       == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
618                 {
619                   /* Skip the register and the comma.  */
620                   ++s;
621                   continue;
622                 }
623               if (*s == ','
624                   && s[1] == 'v'
625                   && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
626                       == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
627                 {
628                   /* Skip the register and the comma.  */
629                   ++s;
630                   continue;
631                 }
632               print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
633                                      info);
634             }
635
636           if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
637             {
638               info->branch_delay_insns = 1;
639               if (info->insn_type != dis_jsr)
640                 info->insn_type = dis_branch;
641             }
642
643           return length;
644         }
645     }
646
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;
651
652   return length;
653 }
654
655 /* Disassemble an operand for a mips16 instruction.  */
656
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;
666 {
667   switch (type)
668     {
669     case ',':
670     case '(':
671     case ')':
672       (*info->fprintf_func) (info->stream, "%c", type);
673       break;
674
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;
681
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;
688
689     case 'z':
690       (*info->fprintf_func) (info->stream, "$%s",
691                              mips16_reg_names[((l >> MIPS16OP_SH_RZ)
692                                                & MIPS16OP_MASK_RZ)]);
693       break;
694
695     case 'Z':
696       (*info->fprintf_func) (info->stream, "$%s",
697                              mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
698                                                & MIPS16OP_MASK_MOVE32Z)]);
699       break;
700
701     case '0':
702       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
703       break;
704
705     case 'S':
706       (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
707       break;
708
709     case 'P':
710       (*info->fprintf_func) (info->stream, "$pc");
711       break;
712
713     case 'R':
714       (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
715       break;
716
717     case 'X':
718       (*info->fprintf_func) (info->stream, "$%s",
719                              reg_names[((l >> MIPS16OP_SH_REGR32)
720                                         & MIPS16OP_MASK_REGR32)]);
721       break;
722
723     case 'Y':
724       (*info->fprintf_func) (info->stream, "$%s",
725                              reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
726       break;
727
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':
750       {
751         int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
752
753         shift = 0;
754         signedp = 0;
755         extbits = 16;
756         pcrel = 0;
757         extu = 0;
758         branch = 0;
759         switch (type)
760           {
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)
810               {
811                 info->insn_type = dis_dref;
812                 info->data_size = 4;
813               }
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 ();
908           }
909
910         if (! use_extend)
911           {
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;
918           }
919         else
920           {
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;
930           }
931
932         if (! pcrel)
933           (*info->fprintf_func) (info->stream, "%d", immed);
934         else
935           {
936             bfd_vma baseaddr;
937             bfd_vma val;
938
939             if (branch)
940               {
941                 immed *= 2;
942                 baseaddr = memaddr + 2;
943               }
944             else if (use_extend)
945               baseaddr = memaddr - 2;
946             else
947               {
948                 int status;
949                 bfd_byte buffer[2];
950
951                 baseaddr = memaddr;
952
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
969                   {
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;
978                   }
979               }
980             val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
981             (*info->print_address_func) (val, info);
982             info->target = val;
983           }
984       }
985       break;
986
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;
996
997     case 'l':
998     case 'L':
999       {
1000         int need_comma, amask, smask;
1001
1002         need_comma = 0;
1003
1004         l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1005
1006         amask = (l >> 3) & 7;
1007
1008         if (amask > 0 && amask < 5)
1009           {
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;
1015           }
1016
1017         smask = (l >> 1) & 3;
1018         if (smask == 3)
1019           {
1020             (*info->fprintf_func) (info->stream, "%s??",
1021                                    need_comma ? "," : "");
1022             need_comma = 1;
1023           }
1024         else if (smask > 0)
1025           {
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;
1033           }
1034
1035         if (l & 1)
1036           {
1037             (*info->fprintf_func) (info->stream, "%s$%s",
1038                                    need_comma ? "," : "",
1039                                    reg_names[31]);
1040             need_comma = 1;
1041           }
1042
1043         if (amask == 5 || amask == 6)
1044           {
1045             (*info->fprintf_func) (info->stream, "%s$f0",
1046                                    need_comma ? "," : "");
1047             if (amask == 6)
1048               (*info->fprintf_func) (info->stream, "-$f1");
1049           }
1050       }
1051       break;
1052
1053     default:
1054       abort ();
1055     }
1056 }