* Customer specs changed one R5900 COP2 instruction bit-pattern.
[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       /* start-sanitize-r5900 */
88     case '+':
89     case '-':
90       /* end-santiize-r5900 */
91       (*info->fprintf_func) (info->stream, "%c", *d);
92       break;
93
94     case 's':
95     case 'b':
96     case 'r':
97     case 'v':
98       (*info->fprintf_func) (info->stream, "$%s",
99                              reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
100       break;
101
102     case 't':
103     case 'w':
104       (*info->fprintf_func) (info->stream, "$%s",
105                              reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
106       break;
107
108     case 'i':
109     case 'u':
110       (*info->fprintf_func) (info->stream, "0x%x",
111                         (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
112       break;
113
114     case 'j': /* same as i, but sign-extended */
115     case 'o':
116       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
117       if (delta & 0x8000)
118         delta |= ~0xffff;
119       (*info->fprintf_func) (info->stream, "%d",
120                              delta);
121       break;
122
123     case 'h':
124       (*info->fprintf_func) (info->stream, "0x%x",
125                              (unsigned int) ((l >> OP_SH_PREFX)
126                                              & OP_MASK_PREFX));
127       break;
128
129     case 'k':
130       (*info->fprintf_func) (info->stream, "0x%x",
131                              (unsigned int) ((l >> OP_SH_CACHE)
132                                              & OP_MASK_CACHE));
133       break;
134
135     case 'a':
136       (*info->print_address_func)
137         (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
138          info);
139       break;
140
141     case 'p':
142       /* sign extend the displacement */
143       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
144       if (delta & 0x8000)
145         delta |= ~0xffff;
146       (*info->print_address_func)
147         ((delta << 2) + pc + 4,
148          info);
149       break;
150
151     case 'd':
152       (*info->fprintf_func) (info->stream, "$%s",
153                              reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
154       break;
155
156     case 'z':
157       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
158       break;
159
160     case '<':
161       (*info->fprintf_func) (info->stream, "0x%x",
162                              (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
163       break;
164
165     case 'c':
166       (*info->fprintf_func) (info->stream, "0x%x",
167                              (l >> OP_SH_CODE) & OP_MASK_CODE);
168       break;
169
170     case 'C':
171       (*info->fprintf_func) (info->stream, "0x%x",
172                              (l >> OP_SH_COPZ) & OP_MASK_COPZ);
173       break;
174
175     case 'B':
176       (*info->fprintf_func) (info->stream, "0x%x",
177                              (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
178       break;
179
180     case 'S':
181     case 'V':
182       (*info->fprintf_func) (info->stream, "$f%d",
183                              (l >> OP_SH_FS) & OP_MASK_FS);
184       break;
185
186     /* start-sanitize-r5900 */
187     case '0':
188       (*info->fprintf_func) (info->stream, "0x%x",
189                              (l >> 6) & 0x1f);
190       break;
191
192     case '9':
193       (*info->fprintf_func) (info->stream, "vi27");
194       break;
195
196     case '1':
197       (*info->fprintf_func) (info->stream, "vf%d",
198                              (l >> OP_SH_FT) & OP_MASK_FT);
199       break;
200     case '2':
201       (*info->fprintf_func) (info->stream, "vf%d",
202                              (l >> OP_SH_FS) & OP_MASK_FS);
203       break;
204     case '3':
205       (*info->fprintf_func) (info->stream, "vf%d",
206                              (l >> OP_SH_FD) & OP_MASK_FD);
207       break;
208
209     case '4':
210       (*info->fprintf_func) (info->stream, "vi%d",
211                              (l >> OP_SH_FT) & OP_MASK_FT);
212       break;
213     case '5':
214       (*info->fprintf_func) (info->stream, "vi%d",
215                              (l >> OP_SH_FS) & OP_MASK_FS);
216       break;
217     case '6':
218       (*info->fprintf_func) (info->stream, "vi%d",
219                              (l >> OP_SH_FD) & OP_MASK_FD);
220       break;
221
222     case '7':
223       (*info->fprintf_func) (info->stream, "vf%d",
224                              (l >> OP_SH_FT) & OP_MASK_FT);
225       switch ((l >> 23) & 0x3)
226         {
227           case 0:
228             (*info->fprintf_func) (info->stream, "x");
229             break;
230           case 1:
231             (*info->fprintf_func) (info->stream, "y");
232             break;
233           case 2:
234             (*info->fprintf_func) (info->stream, "z");
235             break;
236           case 3:
237             (*info->fprintf_func) (info->stream, "w");
238             break;
239         }
240       break;
241     case 'K':
242       break;
243
244     case '&':
245       (*info->fprintf_func) (info->stream, ".");
246       if (l & (1 << 21))
247         (*info->fprintf_func) (info->stream, "w");
248       if (l & (1 << 24))
249         (*info->fprintf_func) (info->stream, "x");
250       if (l & (1 << 23))
251         (*info->fprintf_func) (info->stream, "y");
252       if (l & (1 << 22))
253         (*info->fprintf_func) (info->stream, "z");
254       (*info->fprintf_func) (info->stream, "\t");
255       break;
256         
257     case '8':
258       (*info->fprintf_func) (info->stream, "vf%d",
259                              (l >> OP_SH_FS) & OP_MASK_FS);
260       switch ((l >> 21) & 0x3)
261         {
262           case 0:
263             (*info->fprintf_func) (info->stream, "x");
264             break;
265           case 1:
266             (*info->fprintf_func) (info->stream, "y");
267             break;
268           case 2:
269             (*info->fprintf_func) (info->stream, "z");
270             break;
271           case 3:
272             (*info->fprintf_func) (info->stream, "w");
273             break;
274         }
275       break;
276     case 'J':
277       (*info->fprintf_func) (info->stream, "I");
278       break;
279
280     case 'Q':
281       (*info->fprintf_func) (info->stream, "Q");
282       break;
283
284     case 'X':
285       (*info->fprintf_func) (info->stream, "R");
286       break;
287
288     case 'U':
289       (*info->fprintf_func) (info->stream, "ACC");
290       break;
291
292     case 'O':
293       delta = (l >> 6) & 0x7fff;
294       delta <<= 3;
295       (*info->print_address_func) (delta, info);
296       break;
297
298     /* end-sanitize-r5900 */
299
300     case 'T':
301     case 'W':
302       (*info->fprintf_func) (info->stream, "$f%d",
303                              (l >> OP_SH_FT) & OP_MASK_FT);
304       break;
305
306     case 'D':
307       (*info->fprintf_func) (info->stream, "$f%d",
308                              (l >> OP_SH_FD) & OP_MASK_FD);
309       break;
310
311     case 'R':
312       (*info->fprintf_func) (info->stream, "$f%d",
313                              (l >> OP_SH_FR) & OP_MASK_FR);
314       break;
315
316     case 'E':
317       (*info->fprintf_func) (info->stream, "$%d",
318                              (l >> OP_SH_RT) & OP_MASK_RT);
319       break;
320
321     case 'G':
322       (*info->fprintf_func) (info->stream, "$%d",
323                              (l >> OP_SH_RD) & OP_MASK_RD);
324       break;
325
326     case 'N':
327       (*info->fprintf_func) (info->stream, "$fcc%d",
328                              (l >> OP_SH_BCC) & OP_MASK_BCC);
329       break;
330
331     case 'M':
332       (*info->fprintf_func) (info->stream, "$fcc%d",
333                              (l >> OP_SH_CCC) & OP_MASK_CCC);
334       break;
335
336     case 'P':
337       (*info->fprintf_func) (info->stream, "%d",
338                              (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
339       break;
340
341       /* start-sanitize-vr5400 */
342     case 'e':
343       (*info->fprintf_func) (info->stream, "%d",
344                              (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
345       break;
346
347     case '%':
348       (*info->fprintf_func) (info->stream, "%d",
349                              (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
350       break;
351       /* end-sanitize-vr5400 */
352
353     default:
354       (*info->fprintf_func) (info->stream,
355                              "# internal error, undefined modifier(%c)", *d);
356       break;
357     }
358 }
359 \f
360 /* Print the mips instruction at address MEMADDR in debugged memory,
361    on using INFO.  Returns length of the instruction, in bytes, which is
362    always 4.  BIGENDIAN must be 1 if this is big-endian code, 0 if
363    this is little-endian code.  */
364
365 static int
366 _print_insn_mips (memaddr, word, info)
367      bfd_vma memaddr;
368      unsigned long int word;
369      struct disassemble_info *info;
370 {
371   register const struct mips_opcode *op;
372   int target_processor, mips_isa;
373   static boolean init = 0;
374   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
375
376   /* Build a hash table to shorten the search time.  */
377   if (! init)
378     {
379       unsigned int i;
380
381       for (i = 0; i <= OP_MASK_OP; i++)
382         {
383           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
384             {
385               if (op->pinfo == INSN_MACRO)
386                 continue;
387               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
388                 {
389                   mips_hash[i] = op;
390                   break;
391                 }
392             }
393         }
394
395       init = 1;
396     }
397
398   switch (info->mach)
399     {
400       /* start-sanitize-tx19 */
401       case bfd_mach_mips1900:
402         target_processor = 1900;
403         mips_isa = 1;
404         break;
405       /* end-sanitize-tx19 */
406       case bfd_mach_mips3000:
407         target_processor = 3000;
408         mips_isa = 1;
409         break;
410       case bfd_mach_mips3900:
411         target_processor = 3900;
412         mips_isa = 1;
413         break;
414       case bfd_mach_mips4000:
415         target_processor = 4000;
416         mips_isa = 3;
417         break;
418       case bfd_mach_mips4010:
419         target_processor = 4010;
420         mips_isa = 2;
421         break;
422       case bfd_mach_mips4100:
423         target_processor = 4100;
424         mips_isa = 3;
425         break;
426       case bfd_mach_mips4300:
427         target_processor = 4300;
428         mips_isa = 3;
429         break;
430         /* start-sanitize-vr4320 */
431       case bfd_mach_mips4320:
432         target_processor = 4320;
433         mips_isa = 3;
434         break;
435         /* end-sanitize-vr4320 */
436       case bfd_mach_mips4400:
437         target_processor = 4400;
438         mips_isa = 3;
439         break;
440       case bfd_mach_mips4600:
441         target_processor = 4600;
442         mips_isa = 3;
443         break;
444       case bfd_mach_mips4650:
445         target_processor = 4650;
446         mips_isa = 3;
447         break;
448       /* start-sanitize-tx49 */
449       case bfd_mach_mips4900:
450         target_processor = 4900;
451         mips_isa = 3;
452         break;
453       /* end-sanitize-tx49 */
454       case bfd_mach_mips5000:
455         target_processor = 5000;
456         mips_isa = 4;
457         break;
458       /* start-sanitize-vr5400 */
459       case bfd_mach_mips5400:
460         target_processor = 5400;
461         mips_isa = 3;
462         break;
463       /* end-sanitize-vr5400 */
464       /* start-sanitize-r5900 */
465       case bfd_mach_mips5900:
466         target_processor = 5900;
467         mips_isa = 3;
468         break;
469       /* end-sanitize-r5900 */
470       case bfd_mach_mips6000:
471         target_processor = 6000;
472         mips_isa = 2;
473         break;
474       case bfd_mach_mips8000:
475         target_processor = 8000;
476         mips_isa = 4;
477         break;
478       case bfd_mach_mips10000:
479         target_processor = 10000;
480         mips_isa = 4;
481         break;
482       case bfd_mach_mips16:
483         target_processor = 16;
484         mips_isa = 3;
485         break;
486       default:
487         target_processor = 3000;
488         mips_isa = 3;
489         break;
490
491     }
492
493   info->bytes_per_chunk = 4;
494   info->display_endian = info->endian;
495
496   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
497   if (op != NULL)
498     {
499       for (; op < &mips_opcodes[NUMOPCODES]; op++)
500         {
501           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
502             {
503               register const char *d;
504               int insn_isa;
505
506               if ((op->membership & INSN_ISA) == INSN_ISA1)
507                 insn_isa = 1;
508               else if ((op->membership & INSN_ISA) == INSN_ISA2)
509                 insn_isa = 2;
510               else if ((op->membership & INSN_ISA) == INSN_ISA3)
511                 insn_isa = 3;
512               else if ((op->membership & INSN_ISA) == INSN_ISA4)
513                 insn_isa = 4;
514               else
515                 insn_isa = 15;
516
517               if (insn_isa > mips_isa
518                   && (target_processor == 4650
519                       && op->membership & INSN_4650) == 0
520                   && (target_processor == 4010
521                       && op->membership & INSN_4010) == 0
522                   && (target_processor == 4100
523                       && op->membership & INSN_4100) == 0
524                   /* start-sanitize-vr4320 */
525                   && (target_processor == 4320
526                       && op->membership & INSN_4320) == 0
527                   /* end-sanitize-vr4320 */
528                   /* start-sanitize-vr5400 */
529                   && (target_processor == 5400
530                       && op->membership & INSN_5400) == 0
531                   /* end-sanitize-vr5400 */
532                   /* start-sanitize-r5900 */
533                   && (target_processor == 5900
534                       && op->membership & INSN_5900) == 0
535                   /* end-sanitize-r5900 */
536                   /* start-sanitize-tx49 */
537                   && (target_processor == 4900
538                       && op->membership & INSN_4900) == 0
539                   /* end-sanitize-tx49 */
540                   && (target_processor == 3900
541                       && op->membership & INSN_3900) == 0)
542                 continue;
543
544               (*info->fprintf_func) (info->stream, "%s", op->name);
545
546               d = op->args;
547               if (d != NULL && *d != '\0')
548                 {
549                   /* start-sanitize-r5900 */
550                   /* If this is an opcode completer, then do not emit
551                      a tab after the opcode.  */
552                   if (*d != '&')
553                   /* end-sanitize-r5900 */
554                     (*info->fprintf_func) (info->stream, "\t");
555                   for (; *d != '\0'; d++)
556                     /* start-sanitize-r5900 */
557                     /* If this is an escape character, go ahead and print the
558                        next character in the arg string verbatim.  */
559                     if (*d == '#')
560                       {
561                         d++;
562                         (*info->fprintf_func) (info->stream, "%c", *d);
563                       }
564                     else
565                     /* end-sanitize-r5900 */
566                       print_insn_arg (d, word, memaddr, info);
567                 }
568
569               return 4;
570             }
571         }
572     }
573
574   /* Handle undefined instructions.  */
575   (*info->fprintf_func) (info->stream, "0x%x", word);
576   return 4;
577 }
578
579 int
580 print_insn_big_mips (memaddr, info)
581      bfd_vma memaddr;
582      struct disassemble_info *info;
583 {
584   bfd_byte buffer[4];
585   int status;
586
587   if (info->mach == 16
588       || (info->flavour == bfd_target_elf_flavour
589           && info->symbols != NULL
590           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
591               == STO_MIPS16)))
592     return print_insn_mips16 (memaddr, info);
593
594   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
595   if (status == 0)
596     return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
597                              info);
598   else
599     {
600       (*info->memory_error_func) (status, memaddr, info);
601       return -1;
602     }
603 }
604
605 int
606 print_insn_little_mips (memaddr, info)
607      bfd_vma memaddr;
608      struct disassemble_info *info;
609 {
610   bfd_byte buffer[4];
611   int status;
612
613   /* start-sanitize-sky */
614 #ifdef ARCH_dvp
615   {
616     /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
617        once.  Since dvp_mach_type is a function, ensure it's only called
618        once.  */
619     int mach = dvp_info_mach_type (info);
620
621     if (bfd_mach_dvp_p (info->mach)
622         || bfd_mach_dvp_p (mach))
623       return print_insn_dvp (memaddr, info);
624   }
625 #endif
626   /* end-sanitize-sky */
627
628   if (info->mach == 16
629       || (info->flavour == bfd_target_elf_flavour
630           && info->symbols != NULL
631           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
632               == STO_MIPS16)))
633     return print_insn_mips16 (memaddr, info);
634
635   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
636   if (status == 0)
637     return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
638                              info);
639   else
640     {
641       (*info->memory_error_func) (status, memaddr, info);
642       return -1;
643     }
644 }
645 \f
646 /* Disassemble mips16 instructions.  */
647
648 static int
649 print_insn_mips16 (memaddr, info)
650      bfd_vma memaddr;
651      struct disassemble_info *info;
652 {
653   int status;
654   bfd_byte buffer[2];
655   int length;
656   int insn;
657   boolean use_extend;
658   int extend = 0;
659   const struct mips_opcode *op, *opend;
660
661   info->bytes_per_chunk = 2;
662   info->display_endian = info->endian;
663
664   info->insn_info_valid = 1;
665   info->branch_delay_insns = 0;
666   info->data_size = 0;
667   info->insn_type = dis_nonbranch;
668   info->target = 0;
669   info->target2 = 0;
670
671   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
672   if (status != 0)
673     {
674       (*info->memory_error_func) (status, memaddr, info);
675       return -1;
676     }
677
678   length = 2;
679
680   if (info->endian == BFD_ENDIAN_BIG)
681     insn = bfd_getb16 (buffer);
682   else
683     insn = bfd_getl16 (buffer);
684
685   /* Handle the extend opcode specially.  */
686   use_extend = false;
687   if ((insn & 0xf800) == 0xf000)
688     {
689       use_extend = true;
690       extend = insn & 0x7ff;
691
692       memaddr += 2;
693
694       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
695       if (status != 0)
696         {
697           (*info->fprintf_func) (info->stream, "extend 0x%x",
698                                  (unsigned int) extend);
699           (*info->memory_error_func) (status, memaddr, info);
700           return -1;
701         }
702
703       if (info->endian == BFD_ENDIAN_BIG)
704         insn = bfd_getb16 (buffer);
705       else
706         insn = bfd_getl16 (buffer);
707
708       /* Check for an extend opcode followed by an extend opcode.  */
709       if ((insn & 0xf800) == 0xf000)
710         {
711           (*info->fprintf_func) (info->stream, "extend 0x%x",
712                                  (unsigned int) extend);
713           info->insn_type = dis_noninsn;
714           return length;
715         }
716
717       length += 2;
718     }
719
720   /* FIXME: Should probably use a hash table on the major opcode here.  */
721
722   opend = mips16_opcodes + bfd_mips16_num_opcodes;
723   for (op = mips16_opcodes; op < opend; op++)
724     {
725       if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
726         {
727           const char *s;
728
729           if (strchr (op->args, 'a') != NULL)
730             {
731               if (use_extend)
732                 {
733                   (*info->fprintf_func) (info->stream, "extend 0x%x",
734                                          (unsigned int) extend);
735                   info->insn_type = dis_noninsn;
736                   return length - 2;
737                 }
738
739               use_extend = false;
740
741               memaddr += 2;
742
743               status = (*info->read_memory_func) (memaddr, buffer, 2,
744                                                   info);
745               if (status == 0)
746                 {
747                   use_extend = true;
748                   if (info->endian == BFD_ENDIAN_BIG)
749                     extend = bfd_getb16 (buffer);
750                   else
751                     extend = bfd_getl16 (buffer);
752                   length += 2;
753                 }
754             }
755
756           (*info->fprintf_func) (info->stream, "%s", op->name);
757           if (op->args[0] != '\0')
758             (*info->fprintf_func) (info->stream, "\t");
759
760           for (s = op->args; *s != '\0'; s++)
761             {
762               if (*s == ','
763                   && s[1] == 'w'
764                   && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
765                       == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
766                 {
767                   /* Skip the register and the comma.  */
768                   ++s;
769                   continue;
770                 }
771               if (*s == ','
772                   && s[1] == 'v'
773                   && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
774                       == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
775                 {
776                   /* Skip the register and the comma.  */
777                   ++s;
778                   continue;
779                 }
780               print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
781                                      info);
782             }
783
784           if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
785             {
786               info->branch_delay_insns = 1;
787               if (info->insn_type != dis_jsr)
788                 info->insn_type = dis_branch;
789             }
790
791           return length;
792         }
793     }
794
795   if (use_extend)
796     (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
797   (*info->fprintf_func) (info->stream, "0x%x", insn);
798   info->insn_type = dis_noninsn;
799
800   return length;
801 }
802
803 /* Disassemble an operand for a mips16 instruction.  */
804
805 static void
806 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
807      int type;
808      const struct mips_opcode *op;
809      int l;
810      boolean use_extend;
811      int extend;
812      bfd_vma memaddr;
813      struct disassemble_info *info;
814 {
815   switch (type)
816     {
817     case ',':
818     case '(':
819     case ')':
820       (*info->fprintf_func) (info->stream, "%c", type);
821       break;
822
823     case 'y':
824     case 'w':
825       (*info->fprintf_func) (info->stream, "$%s",
826                              mips16_reg_names[((l >> MIPS16OP_SH_RY)
827                                                & MIPS16OP_MASK_RY)]);
828       break;
829
830     case 'x':
831     case 'v':
832       (*info->fprintf_func) (info->stream, "$%s",
833                              mips16_reg_names[((l >> MIPS16OP_SH_RX)
834                                                & MIPS16OP_MASK_RX)]);
835       break;
836
837     case 'z':
838       (*info->fprintf_func) (info->stream, "$%s",
839                              mips16_reg_names[((l >> MIPS16OP_SH_RZ)
840                                                & MIPS16OP_MASK_RZ)]);
841       break;
842
843     case 'Z':
844       (*info->fprintf_func) (info->stream, "$%s",
845                              mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
846                                                & MIPS16OP_MASK_MOVE32Z)]);
847       break;
848
849     case '0':
850       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
851       break;
852
853     case 'S':
854       (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
855       break;
856
857     case 'P':
858       (*info->fprintf_func) (info->stream, "$pc");
859       break;
860
861     case 'R':
862       (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
863       break;
864
865     case 'X':
866       (*info->fprintf_func) (info->stream, "$%s",
867                              reg_names[((l >> MIPS16OP_SH_REGR32)
868                                         & MIPS16OP_MASK_REGR32)]);
869       break;
870
871     case 'Y':
872       (*info->fprintf_func) (info->stream, "$%s",
873                              reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
874       break;
875
876     case '<':
877     case '>':
878     case '[':
879     case ']':
880     case '4':
881     case '5':
882     case 'H':
883     case 'W':
884     case 'D':
885     case 'j':
886     case '6':
887     case '8':
888     case 'V':
889     case 'C':
890     case 'U':
891     case 'k':
892     case 'K':
893     case 'p':
894     case 'q':
895     case 'A':
896     case 'B':
897     case 'E':
898       {
899         int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
900
901         shift = 0;
902         signedp = 0;
903         extbits = 16;
904         pcrel = 0;
905         extu = 0;
906         branch = 0;
907         switch (type)
908           {
909           case '<':
910             nbits = 3;
911             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
912             extbits = 5;
913             extu = 1;
914             break;
915           case '>':
916             nbits = 3;
917             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
918             extbits = 5;
919             extu = 1;
920             break;
921           case '[':
922             nbits = 3;
923             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
924             extbits = 6;
925             extu = 1;
926             break;
927           case ']':
928             nbits = 3;
929             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
930             extbits = 6;
931             extu = 1;
932             break;
933           case '4':
934             nbits = 4;
935             immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
936             signedp = 1;
937             extbits = 15;
938             break;
939           case '5':
940             nbits = 5;
941             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
942             info->insn_type = dis_dref;
943             info->data_size = 1;
944             break;
945           case 'H':
946             nbits = 5;
947             shift = 1;
948             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
949             info->insn_type = dis_dref;
950             info->data_size = 2;
951             break;
952           case 'W':
953             nbits = 5;
954             shift = 2;
955             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
956             if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
957                 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
958               {
959                 info->insn_type = dis_dref;
960                 info->data_size = 4;
961               }
962             break;
963           case 'D':
964             nbits = 5;
965             shift = 3;
966             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
967             info->insn_type = dis_dref;
968             info->data_size = 8;
969             break;
970           case 'j':
971             nbits = 5;
972             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
973             signedp = 1;
974             break;
975           case '6':
976             nbits = 6;
977             immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
978             break;
979           case '8':
980             nbits = 8;
981             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
982             break;
983           case 'V':
984             nbits = 8;
985             shift = 2;
986             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
987             /* FIXME: This might be lw, or it might be addiu to $sp or
988                $pc.  We assume it's load.  */
989             info->insn_type = dis_dref;
990             info->data_size = 4;
991             break;
992           case 'C':
993             nbits = 8;
994             shift = 3;
995             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
996             info->insn_type = dis_dref;
997             info->data_size = 8;
998             break;
999           case 'U':
1000             nbits = 8;
1001             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1002             extu = 1;
1003             break;
1004           case 'k':
1005             nbits = 8;
1006             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1007             signedp = 1;
1008             break;
1009           case 'K':
1010             nbits = 8;
1011             shift = 3;
1012             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1013             signedp = 1;
1014             break;
1015           case 'p':
1016             nbits = 8;
1017             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1018             signedp = 1;
1019             pcrel = 1;
1020             branch = 1;
1021             info->insn_type = dis_condbranch;
1022             break;
1023           case 'q':
1024             nbits = 11;
1025             immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1026             signedp = 1;
1027             pcrel = 1;
1028             branch = 1;
1029             info->insn_type = dis_branch;
1030             break;
1031           case 'A':
1032             nbits = 8;
1033             shift = 2;
1034             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1035             pcrel = 1;
1036             /* FIXME: This can be lw or la.  We assume it is lw.  */
1037             info->insn_type = dis_dref;
1038             info->data_size = 4;
1039             break;
1040           case 'B':
1041             nbits = 5;
1042             shift = 3;
1043             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1044             pcrel = 1;
1045             info->insn_type = dis_dref;
1046             info->data_size = 8;
1047             break;
1048           case 'E':
1049             nbits = 5;
1050             shift = 2;
1051             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1052             pcrel = 1;
1053             break;
1054           default:
1055             abort ();
1056           }
1057
1058         if (! use_extend)
1059           {
1060             if (signedp && immed >= (1 << (nbits - 1)))
1061               immed -= 1 << nbits;
1062             immed <<= shift;
1063             if ((type == '<' || type == '>' || type == '[' || type == '[')
1064                 && immed == 0)
1065               immed = 8;
1066           }
1067         else
1068           {
1069             if (extbits == 16)
1070               immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1071             else if (extbits == 15)
1072               immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1073             else
1074               immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1075             immed &= (1 << extbits) - 1;
1076             if (! extu && immed >= (1 << (extbits - 1)))
1077               immed -= 1 << extbits;
1078           }
1079
1080         if (! pcrel)
1081           (*info->fprintf_func) (info->stream, "%d", immed);
1082         else
1083           {
1084             bfd_vma baseaddr;
1085             bfd_vma val;
1086
1087             if (branch)
1088               {
1089                 immed *= 2;
1090                 baseaddr = memaddr + 2;
1091               }
1092             else if (use_extend)
1093               baseaddr = memaddr - 2;
1094             else
1095               {
1096                 int status;
1097                 bfd_byte buffer[2];
1098
1099                 baseaddr = memaddr;
1100
1101                 /* If this instruction is in the delay slot of a jr
1102                    instruction, the base address is the address of the
1103                    jr instruction.  If it is in the delay slot of jalr
1104                    instruction, the base address is the address of the
1105                    jalr instruction.  This test is unreliable: we have
1106                    no way of knowing whether the previous word is
1107                    instruction or data.  */
1108                 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1109                                                     info);
1110                 if (status == 0
1111                     && (((info->endian == BFD_ENDIAN_BIG
1112                           ? bfd_getb16 (buffer)
1113                           : bfd_getl16 (buffer))
1114                          & 0xf800) == 0x1800))
1115                   baseaddr = memaddr - 4;
1116                 else
1117                   {
1118                     status = (*info->read_memory_func) (memaddr - 2, buffer,
1119                                                         2, info);
1120                     if (status == 0
1121                         && (((info->endian == BFD_ENDIAN_BIG
1122                               ? bfd_getb16 (buffer)
1123                               : bfd_getl16 (buffer))
1124                              & 0xf81f) == 0xe800))
1125                       baseaddr = memaddr - 2;
1126                   }
1127               }
1128             val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1129             (*info->print_address_func) (val, info);
1130             info->target = val;
1131           }
1132       }
1133       break;
1134
1135     case 'a':
1136       if (! use_extend)
1137         extend = 0;
1138       l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1139       (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1140       info->insn_type = dis_jsr;
1141       info->target = (memaddr & 0xf0000000) | l;
1142       info->branch_delay_insns = 1;
1143       break;
1144
1145     case 'l':
1146     case 'L':
1147       {
1148         int need_comma, amask, smask;
1149
1150         need_comma = 0;
1151
1152         l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1153
1154         amask = (l >> 3) & 7;
1155
1156         if (amask > 0 && amask < 5)
1157           {
1158             (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1159             if (amask > 1)
1160               (*info->fprintf_func) (info->stream, "-$%s",
1161                                      reg_names[amask + 3]);
1162             need_comma = 1;
1163           }
1164
1165         smask = (l >> 1) & 3;
1166         if (smask == 3)
1167           {
1168             (*info->fprintf_func) (info->stream, "%s??",
1169                                    need_comma ? "," : "");
1170             need_comma = 1;
1171           }
1172         else if (smask > 0)
1173           {
1174             (*info->fprintf_func) (info->stream, "%s$%s",
1175                                    need_comma ? "," : "",
1176                                    reg_names[16]);
1177             if (smask > 1)
1178               (*info->fprintf_func) (info->stream, "-$%s",
1179                                      reg_names[smask + 15]);
1180             need_comma = 1;
1181           }
1182
1183         if (l & 1)
1184           {
1185             (*info->fprintf_func) (info->stream, "%s$%s",
1186                                    need_comma ? "," : "",
1187                                    reg_names[31]);
1188             need_comma = 1;
1189           }
1190
1191         if (amask == 5 || amask == 6)
1192           {
1193             (*info->fprintf_func) (info->stream, "%s$f0",
1194                                    need_comma ? "," : "");
1195             if (amask == 6)
1196               (*info->fprintf_func) (info->stream, "-$f1");
1197           }
1198       }
1199       break;
1200
1201     default:
1202       abort ();
1203     }
1204 }