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