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