Add ARM v5t, v5te and XScale support
[external/binutils.git] / opcodes / mips-dis.c
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).
5
6 This file is part of GDB, GAS, and the GNU binutils.
7
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.
12
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.
17
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.  */
21
22 #include "sysdep.h"
23 #include "dis-asm.h"
24 #include "opcode/mips.h"
25 #include "opintl.h"
26
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. */
31
32 #if !defined(EMBEDDED_ENV)
33 #define SYMTAB_AVAILABLE 1
34 #include "elf-bfd.h"
35 #include "elf/mips.h"
36 #endif
37
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 *));
42
43 /* Mips instructions are never longer than this many bytes.  */
44 #define MAXLEN 4
45
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 *));
50
51 \f
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"\
65     }
66
67 static CONST char * CONST std_reg_names[] = STD_REGISTER_NAMES;
68
69 /* The mips16 register names.  */
70 static const char * const mips16_reg_names[] =
71 {
72   "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
73 };
74
75 /* Scalar register names. set_mips_isa_type() decides which register name
76    table to use.  */
77 static CONST char * CONST *reg_names = NULL;
78 \f
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;
86 {
87   int delta;
88
89   switch (*d)
90     {
91     case ',':
92     case '(':
93     case ')':
94       (*info->fprintf_func) (info->stream, "%c", *d);
95       break;
96
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;
104
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;
110
111     case 'i':
112     case 'u':
113       (*info->fprintf_func) (info->stream, "0x%x",
114                         (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
115       break;
116
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;
125
126     case 'h':
127       (*info->fprintf_func) (info->stream, "0x%x",
128                              (unsigned int) ((l >> OP_SH_PREFX)
129                                              & OP_MASK_PREFX));
130       break;
131
132     case 'k':
133       (*info->fprintf_func) (info->stream, "0x%x",
134                              (unsigned int) ((l >> OP_SH_CACHE)
135                                              & OP_MASK_CACHE));
136       break;
137
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;
144
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;
154
155     case 'd':
156       (*info->fprintf_func) (info->stream, "$%s",
157                              reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
158       break;
159
160     case 'z':
161       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
162       break;
163
164     case '<':
165       (*info->fprintf_func) (info->stream, "0x%x",
166                              (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
167       break;
168
169     case 'c':
170       (*info->fprintf_func) (info->stream, "0x%x",
171                              (l >> OP_SH_CODE) & OP_MASK_CODE);
172       break;
173
174
175     case 'q':
176       (*info->fprintf_func) (info->stream, "0x%x",
177                              (l >> OP_SH_CODE2) & OP_MASK_CODE2);
178       break;
179
180     case 'm':
181       (*info->fprintf_func) (info->stream, "0x%x",
182                              (l >> OP_SH_CODE20) & OP_MASK_CODE20);
183       break;
184
185     case 'C':
186       (*info->fprintf_func) (info->stream, "0x%x",
187                              (l >> OP_SH_COPZ) & OP_MASK_COPZ);
188       break;
189
190     case 'B':
191       (*info->fprintf_func) (info->stream, "0x%x",
192                              (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
193       break;
194
195     case 'S':
196     case 'V':
197       (*info->fprintf_func) (info->stream, "$f%d",
198                              (l >> OP_SH_FS) & OP_MASK_FS);
199       break;
200
201
202     case 'T':
203     case 'W':
204       (*info->fprintf_func) (info->stream, "$f%d",
205                              (l >> OP_SH_FT) & OP_MASK_FT);
206       break;
207
208     case 'D':
209       (*info->fprintf_func) (info->stream, "$f%d",
210                              (l >> OP_SH_FD) & OP_MASK_FD);
211       break;
212
213     case 'R':
214       (*info->fprintf_func) (info->stream, "$f%d",
215                              (l >> OP_SH_FR) & OP_MASK_FR);
216       break;
217
218     case 'E':
219       (*info->fprintf_func) (info->stream, "$%d",
220                              (l >> OP_SH_RT) & OP_MASK_RT);
221       break;
222
223     case 'G':
224       (*info->fprintf_func) (info->stream, "$%d",
225                              (l >> OP_SH_RD) & OP_MASK_RD);
226       break;
227
228     case 'N':
229       (*info->fprintf_func) (info->stream, "$fcc%d",
230                              (l >> OP_SH_BCC) & OP_MASK_BCC);
231       break;
232
233     case 'M':
234       (*info->fprintf_func) (info->stream, "$fcc%d",
235                              (l >> OP_SH_CCC) & OP_MASK_CCC);
236       break;
237
238     case 'P':
239       (*info->fprintf_func) (info->stream, "%d",
240                              (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
241       break;
242
243     case 'H':
244       (*info->fprintf_func) (info->stream, "%d", 
245                              (l >> OP_SH_SEL) & OP_MASK_SEL);
246       break;
247
248     default:
249       /* xgettext:c-format */
250       (*info->fprintf_func) (info->stream,
251                              _("# internal error, undefined modifier(%c)"),
252                              *d);
253       break;
254     }
255 }
256 \f
257 #if SYMTAB_AVAILABLE
258
259 /* Figure out the MIPS ISA and CPU based on the machine number.
260    FIXME: What does this have to do with SYMTAB_AVAILABLE?  */
261
262 static void
263 set_mips_isa_type (mach, isa, cputype)
264      int mach;
265      int *isa;
266      int *cputype;
267 {
268   int target_processor = 0;
269   int mips_isa = 0;
270
271   /* Use standard MIPS register names by default.  */
272   reg_names = std_reg_names;
273
274   switch (mach)
275     {
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;
344     }
345
346   *isa = mips_isa;
347   *cputype = target_processor;
348 }
349
350 #endif /* SYMTAB_AVAILABLE */
351
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.  */
356
357 static int
358 _print_insn_mips (memaddr, word, info)
359      bfd_vma memaddr;
360      unsigned long int word;
361      struct disassemble_info *info;
362 {
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];
367
368   /* Build a hash table to shorten the search time.  */
369   if (! init)
370     {
371       unsigned int i;
372
373       for (i = 0; i <= OP_MASK_OP; i++)
374         {
375           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
376             {
377               if (op->pinfo == INSN_MACRO)
378                 continue;
379               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
380                 {
381                   mips_hash[i] = op;
382                   break;
383                 }
384             }
385         }
386
387       init = 1;
388     }
389
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  
398
399   info->bytes_per_chunk = 4;
400   info->display_endian = info->endian;
401
402   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
403   if (op != NULL)
404     {
405       for (; op < &mips_opcodes[NUMOPCODES]; op++)
406         {
407           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
408             {
409               register const char *d;
410
411               if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
412                 continue;
413
414               (*info->fprintf_func) (info->stream, "%s", op->name);
415
416               d = op->args;
417               if (d != NULL && *d != '\0')
418                 {
419                     (*info->fprintf_func) (info->stream, "\t");
420                   for (; *d != '\0'; d++)
421                       print_insn_arg (d, word, memaddr, info);
422                 }
423
424               return 4;
425             }
426         }
427     }
428
429   /* Handle undefined instructions.  */
430   (*info->fprintf_func) (info->stream, "0x%x", word);
431   return 4;
432 }
433
434
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.  */
440
441 int
442 print_insn_big_mips (memaddr, info)
443      bfd_vma memaddr;
444      struct disassemble_info *info;
445 {
446   bfd_byte buffer[4];
447   int status;
448
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  
455
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  
464
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
470     {
471       (*info->memory_error_func) (status, memaddr, info);
472       return -1;
473     }
474 }
475
476 int
477 print_insn_little_mips (memaddr, info)
478      bfd_vma memaddr;
479      struct disassemble_info *info;
480 {
481   bfd_byte buffer[4];
482   int status;
483
484
485 #if 1
486   if (memaddr & 0x01)
487     return print_insn_mips16 (memaddr, info);
488 #endif  
489
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  
498
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
504     {
505       (*info->memory_error_func) (status, memaddr, info);
506       return -1;
507     }
508 }
509 \f
510 /* Disassemble mips16 instructions.  */
511
512 static int
513 print_insn_mips16 (memaddr, info)
514      bfd_vma memaddr;
515      struct disassemble_info *info;
516 {
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;
524
525   info->bytes_per_chunk = 2;
526   info->display_endian = info->endian;
527
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;
534
535   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
536   if (status != 0)
537     {
538       (*info->memory_error_func) (status, memaddr, info);
539       return -1;
540     }
541
542   length = 2;
543
544   if (info->endian == BFD_ENDIAN_BIG)
545     insn = bfd_getb16 (buffer);
546   else
547     insn = bfd_getl16 (buffer);
548
549   /* Handle the extend opcode specially.  */
550   use_extend = false;
551   if ((insn & 0xf800) == 0xf000)
552     {
553       use_extend = true;
554       extend = insn & 0x7ff;
555
556       memaddr += 2;
557
558       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
559       if (status != 0)
560         {
561           (*info->fprintf_func) (info->stream, "extend 0x%x",
562                                  (unsigned int) extend);
563           (*info->memory_error_func) (status, memaddr, info);
564           return -1;
565         }
566
567       if (info->endian == BFD_ENDIAN_BIG)
568         insn = bfd_getb16 (buffer);
569       else
570         insn = bfd_getl16 (buffer);
571
572       /* Check for an extend opcode followed by an extend opcode.  */
573       if ((insn & 0xf800) == 0xf000)
574         {
575           (*info->fprintf_func) (info->stream, "extend 0x%x",
576                                  (unsigned int) extend);
577           info->insn_type = dis_noninsn;
578           return length;
579         }
580
581       length += 2;
582     }
583
584   /* FIXME: Should probably use a hash table on the major opcode here.  */
585
586   opend = mips16_opcodes + bfd_mips16_num_opcodes;
587   for (op = mips16_opcodes; op < opend; op++)
588     {
589       if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
590         {
591           const char *s;
592
593           if (strchr (op->args, 'a') != NULL)
594             {
595               if (use_extend)
596                 {
597                   (*info->fprintf_func) (info->stream, "extend 0x%x",
598                                          (unsigned int) extend);
599                   info->insn_type = dis_noninsn;
600                   return length - 2;
601                 }
602
603               use_extend = false;
604
605               memaddr += 2;
606
607               status = (*info->read_memory_func) (memaddr, buffer, 2,
608                                                   info);
609               if (status == 0)
610                 {
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;
617                 }
618             }
619
620           (*info->fprintf_func) (info->stream, "%s", op->name);
621           if (op->args[0] != '\0')
622             (*info->fprintf_func) (info->stream, "\t");
623
624           for (s = op->args; *s != '\0'; s++)
625             {
626               if (*s == ','
627                   && s[1] == 'w'
628                   && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
629                       == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
630                 {
631                   /* Skip the register and the comma.  */
632                   ++s;
633                   continue;
634                 }
635               if (*s == ','
636                   && s[1] == 'v'
637                   && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
638                       == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
639                 {
640                   /* Skip the register and the comma.  */
641                   ++s;
642                   continue;
643                 }
644               print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
645                                      info);
646             }
647
648           if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
649             {
650               info->branch_delay_insns = 1;
651               if (info->insn_type != dis_jsr)
652                 info->insn_type = dis_branch;
653             }
654
655           return length;
656         }
657     }
658
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;
663
664   return length;
665 }
666
667 /* Disassemble an operand for a mips16 instruction.  */
668
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;
678 {
679   switch (type)
680     {
681     case ',':
682     case '(':
683     case ')':
684       (*info->fprintf_func) (info->stream, "%c", type);
685       break;
686
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;
693
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;
700
701     case 'z':
702       (*info->fprintf_func) (info->stream, "$%s",
703                              mips16_reg_names[((l >> MIPS16OP_SH_RZ)
704                                                & MIPS16OP_MASK_RZ)]);
705       break;
706
707     case 'Z':
708       (*info->fprintf_func) (info->stream, "$%s",
709                              mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
710                                                & MIPS16OP_MASK_MOVE32Z)]);
711       break;
712
713     case '0':
714       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
715       break;
716
717     case 'S':
718       (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
719       break;
720
721     case 'P':
722       (*info->fprintf_func) (info->stream, "$pc");
723       break;
724
725     case 'R':
726       (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
727       break;
728
729     case 'X':
730       (*info->fprintf_func) (info->stream, "$%s",
731                              reg_names[((l >> MIPS16OP_SH_REGR32)
732                                         & MIPS16OP_MASK_REGR32)]);
733       break;
734
735     case 'Y':
736       (*info->fprintf_func) (info->stream, "$%s",
737                              reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
738       break;
739
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':
762       {
763         int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
764
765         shift = 0;
766         signedp = 0;
767         extbits = 16;
768         pcrel = 0;
769         extu = 0;
770         branch = 0;
771         switch (type)
772           {
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)
822               {
823                 info->insn_type = dis_dref;
824                 info->data_size = 4;
825               }
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 ();
920           }
921
922         if (! use_extend)
923           {
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;
930           }
931         else
932           {
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;
942           }
943
944         if (! pcrel)
945           (*info->fprintf_func) (info->stream, "%d", immed);
946         else
947           {
948             bfd_vma baseaddr;
949             bfd_vma val;
950
951             if (branch)
952               {
953                 immed *= 2;
954                 baseaddr = memaddr + 2;
955               }
956             else if (use_extend)
957               baseaddr = memaddr - 2;
958             else
959               {
960                 int status;
961                 bfd_byte buffer[2];
962
963                 baseaddr = memaddr;
964
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
981                   {
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;
990                   }
991               }
992             val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
993             (*info->print_address_func) (val, info);
994             info->target = val;
995           }
996       }
997       break;
998
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;
1008
1009     case 'l':
1010     case 'L':
1011       {
1012         int need_comma, amask, smask;
1013
1014         need_comma = 0;
1015
1016         l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1017
1018         amask = (l >> 3) & 7;
1019
1020         if (amask > 0 && amask < 5)
1021           {
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;
1027           }
1028
1029         smask = (l >> 1) & 3;
1030         if (smask == 3)
1031           {
1032             (*info->fprintf_func) (info->stream, "%s??",
1033                                    need_comma ? "," : "");
1034             need_comma = 1;
1035           }
1036         else if (smask > 0)
1037           {
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;
1045           }
1046
1047         if (l & 1)
1048           {
1049             (*info->fprintf_func) (info->stream, "%s$%s",
1050                                    need_comma ? "," : "",
1051                                    reg_names[31]);
1052             need_comma = 1;
1053           }
1054
1055         if (amask == 5 || amask == 6)
1056           {
1057             (*info->fprintf_func) (info->stream, "%s$f0",
1058                                    need_comma ? "," : "");
1059             if (amask == 6)
1060               (*info->fprintf_func) (info->stream, "-$f1");
1061           }
1062       }
1063       break;
1064
1065     default:
1066       abort ();
1067     }
1068 }