This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / opcodes / mips-dis.c
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).
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 #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 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 reg_names[] = 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 \f
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;
82 {
83   int delta;
84
85   switch (*d)
86     {
87     case ',':
88     case '(':
89     case ')':
90       (*info->fprintf_func) (info->stream, "%c", *d);
91       break;
92
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;
100
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;
106
107     case 'i':
108     case 'u':
109       (*info->fprintf_func) (info->stream, "0x%x",
110                         (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
111       break;
112
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;
121
122     case 'h':
123       (*info->fprintf_func) (info->stream, "0x%x",
124                              (unsigned int) ((l >> OP_SH_PREFX)
125                                              & OP_MASK_PREFX));
126       break;
127
128     case 'k':
129       (*info->fprintf_func) (info->stream, "0x%x",
130                              (unsigned int) ((l >> OP_SH_CACHE)
131                                              & OP_MASK_CACHE));
132       break;
133
134     case 'a':
135       (*info->print_address_func)
136         (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
137          info);
138       break;
139
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;
149
150     case 'd':
151       (*info->fprintf_func) (info->stream, "$%s",
152                              reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
153       break;
154
155     case 'z':
156       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
157       break;
158
159     case '<':
160       (*info->fprintf_func) (info->stream, "0x%x",
161                              (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
162       break;
163
164     case 'c':
165       (*info->fprintf_func) (info->stream, "0x%x",
166                              (l >> OP_SH_CODE) & OP_MASK_CODE);
167       break;
168
169
170     case 'q':
171       (*info->fprintf_func) (info->stream, "0x%x",
172                              (l >> OP_SH_CODE2) & OP_MASK_CODE2);
173       break;
174
175     case 'C':
176       (*info->fprintf_func) (info->stream, "0x%x",
177                              (l >> OP_SH_COPZ) & OP_MASK_COPZ);
178       break;
179
180     case 'B':
181       (*info->fprintf_func) (info->stream, "0x%x",
182                              (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
183       break;
184
185     case 'S':
186     case 'V':
187       (*info->fprintf_func) (info->stream, "$f%d",
188                              (l >> OP_SH_FS) & OP_MASK_FS);
189       break;
190
191
192     case 'T':
193     case 'W':
194       (*info->fprintf_func) (info->stream, "$f%d",
195                              (l >> OP_SH_FT) & OP_MASK_FT);
196       break;
197
198     case 'D':
199       (*info->fprintf_func) (info->stream, "$f%d",
200                              (l >> OP_SH_FD) & OP_MASK_FD);
201       break;
202
203     case 'R':
204       (*info->fprintf_func) (info->stream, "$f%d",
205                              (l >> OP_SH_FR) & OP_MASK_FR);
206       break;
207
208     case 'E':
209       (*info->fprintf_func) (info->stream, "$%d",
210                              (l >> OP_SH_RT) & OP_MASK_RT);
211       break;
212
213     case 'G':
214       (*info->fprintf_func) (info->stream, "$%d",
215                              (l >> OP_SH_RD) & OP_MASK_RD);
216       break;
217
218     case 'N':
219       (*info->fprintf_func) (info->stream, "$fcc%d",
220                              (l >> OP_SH_BCC) & OP_MASK_BCC);
221       break;
222
223     case 'M':
224       (*info->fprintf_func) (info->stream, "$fcc%d",
225                              (l >> OP_SH_CCC) & OP_MASK_CCC);
226       break;
227
228     case 'P':
229       (*info->fprintf_func) (info->stream, "%d",
230                              (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
231       break;
232
233
234     default:
235       /* xgettext:c-format */
236       (*info->fprintf_func) (info->stream,
237                              _("# internal error, undefined modifier(%c)"),
238                              *d);
239       break;
240     }
241 }
242 \f
243 #if SYMTAB_AVAILABLE
244
245 /* Figure out the MIPS ISA and CPU based on the machine number.
246    FIXME: What does this have to do with SYMTAB_AVAILABLE?  */
247
248 static void
249 set_mips_isa_type (mach, isa, cputype)
250      int mach;
251      int *isa;
252      int *cputype;
253 {
254   int target_processor = 0;
255   int mips_isa = 0;
256
257   switch (mach)
258     {
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;
323
324     }
325
326   *isa = mips_isa;
327   *cputype = target_processor;
328 }
329
330 #endif /* SYMTAB_AVAILABLE */
331
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.  */
336
337 static int
338 _print_insn_mips (memaddr, word, info)
339      bfd_vma memaddr;
340      unsigned long int word;
341      struct disassemble_info *info;
342 {
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];
347
348   /* Build a hash table to shorten the search time.  */
349   if (! init)
350     {
351       unsigned int i;
352
353       for (i = 0; i <= OP_MASK_OP; i++)
354         {
355           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
356             {
357               if (op->pinfo == INSN_MACRO)
358                 continue;
359               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
360                 {
361                   mips_hash[i] = op;
362                   break;
363                 }
364             }
365         }
366
367       init = 1;
368     }
369
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  
378
379   info->bytes_per_chunk = 4;
380   info->display_endian = info->endian;
381
382   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
383   if (op != NULL)
384     {
385       for (; op < &mips_opcodes[NUMOPCODES]; op++)
386         {
387           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
388             {
389               register const char *d;
390               int insn_isa;
391
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;
402
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;
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 }