Fix typos in ChangeLogs; fix dates in copyright notices
[platform/upstream/binutils.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001
4    Free Software Foundation, Inc.
5    Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
7 This file is part of GDB, GAS, and the GNU binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #include "opcode/mips.h"
26 #include "opintl.h"
27
28 /* FIXME: These are needed to figure out if the code is mips16 or
29    not. The low bit of the address is often a good indicator.  No
30    symbol table is available when this code runs out in an embedded
31    system as when it is used for disassembler support in a monitor. */
32
33 #if !defined(EMBEDDED_ENV)
34 #define SYMTAB_AVAILABLE 1
35 #include "elf-bfd.h"
36 #include "elf/mips.h"
37 #endif
38
39 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
40 static void print_mips16_insn_arg
41   PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
42            struct disassemble_info *));
43
44 /* Mips instructions are never longer than this many bytes.  */
45 #define MAXLEN 4
46
47 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
48                                     struct disassemble_info *));
49 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
50                                      struct disassemble_info *));
51
52 \f
53 /* FIXME: This should be shared with gdb somehow.  */
54 #define STD_REGISTER_NAMES      \
55     {   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3", \
56         "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7", \
57         "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7", \
58         "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra", \
59         "sr",   "lo",   "hi",   "bad",  "cause","pc",    \
60         "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7", \
61         "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15", \
62         "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",\
63         "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",\
64         "fsr",  "fir",  "fp",   "inx",  "rand", "tlblo","ctxt", "tlbhi",\
65         "epc",  "prid"\
66     }
67
68 static CONST char * CONST std_reg_names[] = STD_REGISTER_NAMES;
69
70 /* The mips16 register names.  */
71 static const char * const mips16_reg_names[] =
72 {
73   "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
74 };
75
76 /* Scalar register names. set_mips_isa_type() decides which register name
77    table to use.  */
78 static CONST char * CONST *reg_names = NULL;
79 \f
80 /* subroutine */
81 static void
82 print_insn_arg (d, l, pc, info)
83      const char *d;
84      register unsigned long int l;
85      bfd_vma pc;
86      struct disassemble_info *info;
87 {
88   int delta;
89
90   switch (*d)
91     {
92     case ',':
93     case '(':
94     case ')':
95       (*info->fprintf_func) (info->stream, "%c", *d);
96       break;
97
98     case 's':
99     case 'b':
100     case 'r':
101     case 'v':
102       (*info->fprintf_func) (info->stream, "$%s",
103                              reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
104       break;
105
106     case 't':
107     case 'w':
108       (*info->fprintf_func) (info->stream, "$%s",
109                              reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
110       break;
111
112     case 'i':
113     case 'u':
114       (*info->fprintf_func) (info->stream, "0x%x",
115                         (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
116       break;
117
118     case 'j': /* same as i, but sign-extended */
119     case 'o':
120       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
121       if (delta & 0x8000)
122         delta |= ~0xffff;
123       (*info->fprintf_func) (info->stream, "%d",
124                              delta);
125       break;
126
127     case 'h':
128       (*info->fprintf_func) (info->stream, "0x%x",
129                              (unsigned int) ((l >> OP_SH_PREFX)
130                                              & OP_MASK_PREFX));
131       break;
132
133     case 'k':
134       (*info->fprintf_func) (info->stream, "0x%x",
135                              (unsigned int) ((l >> OP_SH_CACHE)
136                                              & OP_MASK_CACHE));
137       break;
138
139     case 'a':
140       (*info->print_address_func)
141         ((((pc + 4) & ~ (bfd_vma) 0x0fffffff)
142           | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
143          info);
144       break;
145
146     case 'p':
147       /* sign extend the displacement */
148       delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
149       if (delta & 0x8000)
150         delta |= ~0xffff;
151       (*info->print_address_func)
152         ((delta << 2) + pc + 4,
153          info);
154       break;
155
156     case 'd':
157       (*info->fprintf_func) (info->stream, "$%s",
158                              reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
159       break;
160
161     case 'U':
162       {
163       /* First check for both rd and rt being equal. */
164       int reg = (l >> OP_SH_RD) & OP_MASK_RD;
165       if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
166         (*info->fprintf_func) (info->stream, "$%s",
167                                reg_names[reg]);
168       else                        
169         {
170           /* If one is zero use the other. */
171           if (reg == 0)
172             (*info->fprintf_func) (info->stream, "$%s",
173                                    reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
174           else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
175             (*info->fprintf_func) (info->stream, "$%s",
176                                    reg_names[reg]);
177           else /* Bogus, result depends on processor. */
178             (*info->fprintf_func) (info->stream, "$%s or $%s",
179                                    reg_names[reg],
180                                    reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
181           }
182       }
183       break;
184
185     case 'z':
186       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
187       break;
188
189     case '<':
190       (*info->fprintf_func) (info->stream, "0x%x",
191                              (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
192       break;
193
194     case 'c':
195       (*info->fprintf_func) (info->stream, "0x%x",
196                              (l >> OP_SH_CODE) & OP_MASK_CODE);
197       break;
198
199     case 'q':
200       (*info->fprintf_func) (info->stream, "0x%x",
201                              (l >> OP_SH_CODE2) & OP_MASK_CODE2);
202       break;
203
204     case 'C':
205       (*info->fprintf_func) (info->stream, "0x%x",
206                              (l >> OP_SH_COPZ) & OP_MASK_COPZ);
207       break;
208
209     case 'B':
210       (*info->fprintf_func) (info->stream, "0x%x",
211                              (l >> OP_SH_CODE20) & OP_MASK_CODE20);
212       break;
213
214     case 'J':
215       (*info->fprintf_func) (info->stream, "0x%x",
216                              (l >> OP_SH_CODE19) & OP_MASK_CODE19);
217       break;
218
219     case 'S':
220     case 'V':
221       (*info->fprintf_func) (info->stream, "$f%d",
222                              (l >> OP_SH_FS) & OP_MASK_FS);
223       break;
224
225     case 'T':
226     case 'W':
227       (*info->fprintf_func) (info->stream, "$f%d",
228                              (l >> OP_SH_FT) & OP_MASK_FT);
229       break;
230
231     case 'D':
232       (*info->fprintf_func) (info->stream, "$f%d",
233                              (l >> OP_SH_FD) & OP_MASK_FD);
234       break;
235
236     case 'R':
237       (*info->fprintf_func) (info->stream, "$f%d",
238                              (l >> OP_SH_FR) & OP_MASK_FR);
239       break;
240
241     case 'E':
242       (*info->fprintf_func) (info->stream, "$%d",
243                              (l >> OP_SH_RT) & OP_MASK_RT);
244       break;
245
246     case 'G':
247       (*info->fprintf_func) (info->stream, "$%d",
248                              (l >> OP_SH_RD) & OP_MASK_RD);
249       break;
250
251     case 'N':
252       (*info->fprintf_func) (info->stream, "$fcc%d",
253                              (l >> OP_SH_BCC) & OP_MASK_BCC);
254       break;
255
256     case 'M':
257       (*info->fprintf_func) (info->stream, "$fcc%d",
258                              (l >> OP_SH_CCC) & OP_MASK_CCC);
259       break;
260
261     case 'P':
262       (*info->fprintf_func) (info->stream, "%d",
263                              (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
264       break;
265
266     case 'H':
267       (*info->fprintf_func) (info->stream, "%d", 
268                              (l >> OP_SH_SEL) & OP_MASK_SEL);
269       break;
270
271     default:
272       /* xgettext:c-format */
273       (*info->fprintf_func) (info->stream,
274                              _("# internal error, undefined modifier(%c)"),
275                              *d);
276       break;
277     }
278 }
279 \f
280 #if SYMTAB_AVAILABLE
281
282 /* Figure out the MIPS ISA and CPU based on the machine number.
283    FIXME: What does this have to do with SYMTAB_AVAILABLE?  */
284
285 static void
286 set_mips_isa_type (mach, isa, cputype)
287      int mach;
288      int *isa;
289      int *cputype;
290 {
291   int target_processor = CPU_UNKNOWN;
292   int mips_isa = ISA_UNKNOWN;
293
294   /* Use standard MIPS register names by default.  */
295   reg_names = std_reg_names;
296
297   switch (mach)
298     {
299     case bfd_mach_mips3000:
300       target_processor = CPU_R3000;
301       mips_isa = ISA_MIPS1;
302       break;
303     case bfd_mach_mips3900:
304       target_processor = CPU_R3900;
305       mips_isa = ISA_MIPS1;
306       break;
307     case bfd_mach_mips4000:
308       target_processor = CPU_R4000;
309       mips_isa = ISA_MIPS3;
310       break;
311     case bfd_mach_mips4010:
312       target_processor = CPU_R4010;
313       mips_isa = ISA_MIPS2;
314       break;
315     case bfd_mach_mips4100:
316       target_processor = CPU_VR4100;
317       mips_isa = ISA_MIPS3;
318       break;
319     case bfd_mach_mips4111:
320       target_processor = CPU_VR4100; /* FIXME: Shouldn't this be CPU_R4111 ??? */
321       mips_isa = ISA_MIPS3;
322       break;
323     case bfd_mach_mips4300:
324       target_processor = CPU_R4300;
325       mips_isa = ISA_MIPS3;
326       break;
327     case bfd_mach_mips4400:
328       target_processor = CPU_R4400;
329       mips_isa = ISA_MIPS3;
330       break;
331     case bfd_mach_mips4600:
332       target_processor = CPU_R4600;
333       mips_isa = ISA_MIPS3;
334       break;
335     case bfd_mach_mips4650:
336       target_processor = CPU_R4650;
337       mips_isa = ISA_MIPS3;
338       break;
339     case bfd_mach_mips5000:
340       target_processor = CPU_R5000;
341       mips_isa = ISA_MIPS4;
342       break;
343     case bfd_mach_mips6000:
344       target_processor = CPU_R6000;
345       mips_isa = ISA_MIPS2;
346       break;
347     case bfd_mach_mips8000:
348       target_processor = CPU_R8000;
349       mips_isa = ISA_MIPS4;
350       break;
351     case bfd_mach_mips10000:
352       target_processor = CPU_R10000;
353       mips_isa = ISA_MIPS4;
354       break;
355     case bfd_mach_mips16:
356       target_processor = CPU_MIPS16;
357       mips_isa = ISA_MIPS3;
358       break;
359     case bfd_mach_mips32:
360       target_processor = CPU_MIPS32;
361       mips_isa = ISA_MIPS32;
362       break;
363     case bfd_mach_mips32_4k:
364       target_processor = CPU_MIPS32_4K;
365       mips_isa = ISA_MIPS32;
366       break;
367     case bfd_mach_mips5:
368       target_processor = CPU_MIPS5;
369       mips_isa = ISA_MIPS5;
370       break;
371     case bfd_mach_mips64:
372       target_processor = CPU_MIPS64;
373       mips_isa = ISA_MIPS64;
374       break;
375     case bfd_mach_mips_sb1:
376       target_processor = CPU_SB1;
377       mips_isa = ISA_MIPS64;
378       break;
379     default:
380       target_processor = CPU_R3000;
381       mips_isa = ISA_MIPS3;
382       break;
383     }
384
385   *isa = mips_isa;
386   *cputype = target_processor;
387 }
388
389 #endif /* SYMTAB_AVAILABLE */
390
391 /* Print the mips instruction at address MEMADDR in debugged memory,
392    on using INFO.  Returns length of the instruction, in bytes, which is
393    always 4.  BIGENDIAN must be 1 if this is big-endian code, 0 if
394    this is little-endian code.  */
395
396 static int
397 _print_insn_mips (memaddr, word, info)
398      bfd_vma memaddr;
399      unsigned long int word;
400      struct disassemble_info *info;
401 {
402   register const struct mips_opcode *op;
403   int target_processor, mips_isa;
404   static boolean init = 0;
405   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
406
407   /* Build a hash table to shorten the search time.  */
408   if (! init)
409     {
410       unsigned int i;
411
412       for (i = 0; i <= OP_MASK_OP; i++)
413         {
414           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
415             {
416               if (op->pinfo == INSN_MACRO)
417                 continue;
418               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
419                 {
420                   mips_hash[i] = op;
421                   break;
422                 }
423             }
424         }
425
426       init = 1;
427     }
428
429 #if ! SYMTAB_AVAILABLE
430   /* This is running out on a target machine, not in a host tool.
431      FIXME: Where does mips_target_info come from?  */
432   target_processor = mips_target_info.processor;
433   mips_isa = mips_target_info.isa;
434 #else  
435   set_mips_isa_type (info->mach, &mips_isa, &target_processor);
436 #endif  
437
438   info->bytes_per_chunk = 4;
439   info->display_endian = info->endian;
440
441   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
442   if (op != NULL)
443     {
444       for (; op < &mips_opcodes[NUMOPCODES]; op++)
445         {
446           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
447             {
448               register const char *d;
449
450               if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
451                 continue;
452
453               (*info->fprintf_func) (info->stream, "%s", op->name);
454
455               d = op->args;
456               if (d != NULL && *d != '\0')
457                 {
458                     (*info->fprintf_func) (info->stream, "\t");
459                   for (; *d != '\0'; d++)
460                       print_insn_arg (d, word, memaddr, info);
461                 }
462
463               return 4;
464             }
465         }
466     }
467
468   /* Handle undefined instructions.  */
469   (*info->fprintf_func) (info->stream, "0x%x", word);
470   return 4;
471 }
472
473
474 /* In an environment where we do not know the symbol type of the
475    instruction we are forced to assume that the low order bit of the
476    instructions' address may mark it as a mips16 instruction.  If we
477    are single stepping, or the pc is within the disassembled function,
478    this works.  Otherwise, we need a clue.  Sometimes.  */
479
480 int
481 print_insn_big_mips (memaddr, info)
482      bfd_vma memaddr;
483      struct disassemble_info *info;
484 {
485   bfd_byte buffer[4];
486   int status;
487
488 #if 1
489   /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
490   /* Only a few tools will work this way.  */
491   if (memaddr & 0x01)
492     return print_insn_mips16 (memaddr, info);
493 #endif  
494
495 #if SYMTAB_AVAILABLE
496   if (info->mach == 16
497       || (info->flavour == bfd_target_elf_flavour
498           && info->symbols != NULL
499           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
500               == STO_MIPS16)))
501     return print_insn_mips16 (memaddr, info);
502 #endif  
503
504   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
505   if (status == 0)
506     return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
507                              info);
508   else
509     {
510       (*info->memory_error_func) (status, memaddr, info);
511       return -1;
512     }
513 }
514
515 int
516 print_insn_little_mips (memaddr, info)
517      bfd_vma memaddr;
518      struct disassemble_info *info;
519 {
520   bfd_byte buffer[4];
521   int status;
522
523
524 #if 1
525   if (memaddr & 0x01)
526     return print_insn_mips16 (memaddr, info);
527 #endif  
528
529 #if SYMTAB_AVAILABLE
530   if (info->mach == 16
531       || (info->flavour == bfd_target_elf_flavour
532           && info->symbols != NULL
533           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
534               == STO_MIPS16)))
535     return print_insn_mips16 (memaddr, info);
536 #endif  
537
538   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
539   if (status == 0)
540     return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
541                              info);
542   else
543     {
544       (*info->memory_error_func) (status, memaddr, info);
545       return -1;
546     }
547 }
548 \f
549 /* Disassemble mips16 instructions.  */
550
551 static int
552 print_insn_mips16 (memaddr, info)
553      bfd_vma memaddr;
554      struct disassemble_info *info;
555 {
556   int status;
557   bfd_byte buffer[2];
558   int length;
559   int insn;
560   boolean use_extend;
561   int extend = 0;
562   const struct mips_opcode *op, *opend;
563
564   info->bytes_per_chunk = 2;
565   info->display_endian = info->endian;
566
567   info->insn_info_valid = 1;
568   info->branch_delay_insns = 0;
569   info->data_size = 0;
570   info->insn_type = dis_nonbranch;
571   info->target = 0;
572   info->target2 = 0;
573
574   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
575   if (status != 0)
576     {
577       (*info->memory_error_func) (status, memaddr, info);
578       return -1;
579     }
580
581   length = 2;
582
583   if (info->endian == BFD_ENDIAN_BIG)
584     insn = bfd_getb16 (buffer);
585   else
586     insn = bfd_getl16 (buffer);
587
588   /* Handle the extend opcode specially.  */
589   use_extend = false;
590   if ((insn & 0xf800) == 0xf000)
591     {
592       use_extend = true;
593       extend = insn & 0x7ff;
594
595       memaddr += 2;
596
597       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
598       if (status != 0)
599         {
600           (*info->fprintf_func) (info->stream, "extend 0x%x",
601                                  (unsigned int) extend);
602           (*info->memory_error_func) (status, memaddr, info);
603           return -1;
604         }
605
606       if (info->endian == BFD_ENDIAN_BIG)
607         insn = bfd_getb16 (buffer);
608       else
609         insn = bfd_getl16 (buffer);
610
611       /* Check for an extend opcode followed by an extend opcode.  */
612       if ((insn & 0xf800) == 0xf000)
613         {
614           (*info->fprintf_func) (info->stream, "extend 0x%x",
615                                  (unsigned int) extend);
616           info->insn_type = dis_noninsn;
617           return length;
618         }
619
620       length += 2;
621     }
622
623   /* FIXME: Should probably use a hash table on the major opcode here.  */
624
625   opend = mips16_opcodes + bfd_mips16_num_opcodes;
626   for (op = mips16_opcodes; op < opend; op++)
627     {
628       if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
629         {
630           const char *s;
631
632           if (strchr (op->args, 'a') != NULL)
633             {
634               if (use_extend)
635                 {
636                   (*info->fprintf_func) (info->stream, "extend 0x%x",
637                                          (unsigned int) extend);
638                   info->insn_type = dis_noninsn;
639                   return length - 2;
640                 }
641
642               use_extend = false;
643
644               memaddr += 2;
645
646               status = (*info->read_memory_func) (memaddr, buffer, 2,
647                                                   info);
648               if (status == 0)
649                 {
650                   use_extend = true;
651                   if (info->endian == BFD_ENDIAN_BIG)
652                     extend = bfd_getb16 (buffer);
653                   else
654                     extend = bfd_getl16 (buffer);
655                   length += 2;
656                 }
657             }
658
659           (*info->fprintf_func) (info->stream, "%s", op->name);
660           if (op->args[0] != '\0')
661             (*info->fprintf_func) (info->stream, "\t");
662
663           for (s = op->args; *s != '\0'; s++)
664             {
665               if (*s == ','
666                   && s[1] == 'w'
667                   && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
668                       == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
669                 {
670                   /* Skip the register and the comma.  */
671                   ++s;
672                   continue;
673                 }
674               if (*s == ','
675                   && s[1] == 'v'
676                   && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
677                       == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
678                 {
679                   /* Skip the register and the comma.  */
680                   ++s;
681                   continue;
682                 }
683               print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
684                                      info);
685             }
686
687           if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
688             {
689               info->branch_delay_insns = 1;
690               if (info->insn_type != dis_jsr)
691                 info->insn_type = dis_branch;
692             }
693
694           return length;
695         }
696     }
697
698   if (use_extend)
699     (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
700   (*info->fprintf_func) (info->stream, "0x%x", insn);
701   info->insn_type = dis_noninsn;
702
703   return length;
704 }
705
706 /* Disassemble an operand for a mips16 instruction.  */
707
708 static void
709 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
710      int type;
711      const struct mips_opcode *op;
712      int l;
713      boolean use_extend;
714      int extend;
715      bfd_vma memaddr;
716      struct disassemble_info *info;
717 {
718   switch (type)
719     {
720     case ',':
721     case '(':
722     case ')':
723       (*info->fprintf_func) (info->stream, "%c", type);
724       break;
725
726     case 'y':
727     case 'w':
728       (*info->fprintf_func) (info->stream, "$%s",
729                              mips16_reg_names[((l >> MIPS16OP_SH_RY)
730                                                & MIPS16OP_MASK_RY)]);
731       break;
732
733     case 'x':
734     case 'v':
735       (*info->fprintf_func) (info->stream, "$%s",
736                              mips16_reg_names[((l >> MIPS16OP_SH_RX)
737                                                & MIPS16OP_MASK_RX)]);
738       break;
739
740     case 'z':
741       (*info->fprintf_func) (info->stream, "$%s",
742                              mips16_reg_names[((l >> MIPS16OP_SH_RZ)
743                                                & MIPS16OP_MASK_RZ)]);
744       break;
745
746     case 'Z':
747       (*info->fprintf_func) (info->stream, "$%s",
748                              mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
749                                                & MIPS16OP_MASK_MOVE32Z)]);
750       break;
751
752     case '0':
753       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
754       break;
755
756     case 'S':
757       (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
758       break;
759
760     case 'P':
761       (*info->fprintf_func) (info->stream, "$pc");
762       break;
763
764     case 'R':
765       (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
766       break;
767
768     case 'X':
769       (*info->fprintf_func) (info->stream, "$%s",
770                              reg_names[((l >> MIPS16OP_SH_REGR32)
771                                         & MIPS16OP_MASK_REGR32)]);
772       break;
773
774     case 'Y':
775       (*info->fprintf_func) (info->stream, "$%s",
776                              reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
777       break;
778
779     case '<':
780     case '>':
781     case '[':
782     case ']':
783     case '4':
784     case '5':
785     case 'H':
786     case 'W':
787     case 'D':
788     case 'j':
789     case '6':
790     case '8':
791     case 'V':
792     case 'C':
793     case 'U':
794     case 'k':
795     case 'K':
796     case 'p':
797     case 'q':
798     case 'A':
799     case 'B':
800     case 'E':
801       {
802         int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
803
804         shift = 0;
805         signedp = 0;
806         extbits = 16;
807         pcrel = 0;
808         extu = 0;
809         branch = 0;
810         switch (type)
811           {
812           case '<':
813             nbits = 3;
814             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
815             extbits = 5;
816             extu = 1;
817             break;
818           case '>':
819             nbits = 3;
820             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
821             extbits = 5;
822             extu = 1;
823             break;
824           case '[':
825             nbits = 3;
826             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
827             extbits = 6;
828             extu = 1;
829             break;
830           case ']':
831             nbits = 3;
832             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
833             extbits = 6;
834             extu = 1;
835             break;
836           case '4':
837             nbits = 4;
838             immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
839             signedp = 1;
840             extbits = 15;
841             break;
842           case '5':
843             nbits = 5;
844             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
845             info->insn_type = dis_dref;
846             info->data_size = 1;
847             break;
848           case 'H':
849             nbits = 5;
850             shift = 1;
851             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
852             info->insn_type = dis_dref;
853             info->data_size = 2;
854             break;
855           case 'W':
856             nbits = 5;
857             shift = 2;
858             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
859             if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
860                 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
861               {
862                 info->insn_type = dis_dref;
863                 info->data_size = 4;
864               }
865             break;
866           case 'D':
867             nbits = 5;
868             shift = 3;
869             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
870             info->insn_type = dis_dref;
871             info->data_size = 8;
872             break;
873           case 'j':
874             nbits = 5;
875             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
876             signedp = 1;
877             break;
878           case '6':
879             nbits = 6;
880             immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
881             break;
882           case '8':
883             nbits = 8;
884             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
885             break;
886           case 'V':
887             nbits = 8;
888             shift = 2;
889             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
890             /* FIXME: This might be lw, or it might be addiu to $sp or
891                $pc.  We assume it's load.  */
892             info->insn_type = dis_dref;
893             info->data_size = 4;
894             break;
895           case 'C':
896             nbits = 8;
897             shift = 3;
898             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
899             info->insn_type = dis_dref;
900             info->data_size = 8;
901             break;
902           case 'U':
903             nbits = 8;
904             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
905             extu = 1;
906             break;
907           case 'k':
908             nbits = 8;
909             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
910             signedp = 1;
911             break;
912           case 'K':
913             nbits = 8;
914             shift = 3;
915             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
916             signedp = 1;
917             break;
918           case 'p':
919             nbits = 8;
920             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
921             signedp = 1;
922             pcrel = 1;
923             branch = 1;
924             info->insn_type = dis_condbranch;
925             break;
926           case 'q':
927             nbits = 11;
928             immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
929             signedp = 1;
930             pcrel = 1;
931             branch = 1;
932             info->insn_type = dis_branch;
933             break;
934           case 'A':
935             nbits = 8;
936             shift = 2;
937             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
938             pcrel = 1;
939             /* FIXME: This can be lw or la.  We assume it is lw.  */
940             info->insn_type = dis_dref;
941             info->data_size = 4;
942             break;
943           case 'B':
944             nbits = 5;
945             shift = 3;
946             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
947             pcrel = 1;
948             info->insn_type = dis_dref;
949             info->data_size = 8;
950             break;
951           case 'E':
952             nbits = 5;
953             shift = 2;
954             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
955             pcrel = 1;
956             break;
957           default:
958             abort ();
959           }
960
961         if (! use_extend)
962           {
963             if (signedp && immed >= (1 << (nbits - 1)))
964               immed -= 1 << nbits;
965             immed <<= shift;
966             if ((type == '<' || type == '>' || type == '[' || type == ']')
967                 && immed == 0)
968               immed = 8;
969           }
970         else
971           {
972             if (extbits == 16)
973               immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
974             else if (extbits == 15)
975               immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
976             else
977               immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
978             immed &= (1 << extbits) - 1;
979             if (! extu && immed >= (1 << (extbits - 1)))
980               immed -= 1 << extbits;
981           }
982
983         if (! pcrel)
984           (*info->fprintf_func) (info->stream, "%d", immed);
985         else
986           {
987             bfd_vma baseaddr;
988             bfd_vma val;
989
990             if (branch)
991               {
992                 immed *= 2;
993                 baseaddr = memaddr + 2;
994               }
995             else if (use_extend)
996               baseaddr = memaddr - 2;
997             else
998               {
999                 int status;
1000                 bfd_byte buffer[2];
1001
1002                 baseaddr = memaddr;
1003
1004                 /* If this instruction is in the delay slot of a jr
1005                    instruction, the base address is the address of the
1006                    jr instruction.  If it is in the delay slot of jalr
1007                    instruction, the base address is the address of the
1008                    jalr instruction.  This test is unreliable: we have
1009                    no way of knowing whether the previous word is
1010                    instruction or data.  */
1011                 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1012                                                     info);
1013                 if (status == 0
1014                     && (((info->endian == BFD_ENDIAN_BIG
1015                           ? bfd_getb16 (buffer)
1016                           : bfd_getl16 (buffer))
1017                          & 0xf800) == 0x1800))
1018                   baseaddr = memaddr - 4;
1019                 else
1020                   {
1021                     status = (*info->read_memory_func) (memaddr - 2, buffer,
1022                                                         2, info);
1023                     if (status == 0
1024                         && (((info->endian == BFD_ENDIAN_BIG
1025                               ? bfd_getb16 (buffer)
1026                               : bfd_getl16 (buffer))
1027                              & 0xf81f) == 0xe800))
1028                       baseaddr = memaddr - 2;
1029                   }
1030               }
1031             val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1032             (*info->print_address_func) (val, info);
1033             info->target = val;
1034           }
1035       }
1036       break;
1037
1038     case 'a':
1039       if (! use_extend)
1040         extend = 0;
1041       l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1042       (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
1043       info->insn_type = dis_jsr;
1044       info->target = ((memaddr + 4) & 0xf0000000) | l;
1045       info->branch_delay_insns = 1;
1046       break;
1047
1048     case 'l':
1049     case 'L':
1050       {
1051         int need_comma, amask, smask;
1052
1053         need_comma = 0;
1054
1055         l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1056
1057         amask = (l >> 3) & 7;
1058
1059         if (amask > 0 && amask < 5)
1060           {
1061             (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1062             if (amask > 1)
1063               (*info->fprintf_func) (info->stream, "-$%s",
1064                                      reg_names[amask + 3]);
1065             need_comma = 1;
1066           }
1067
1068         smask = (l >> 1) & 3;
1069         if (smask == 3)
1070           {
1071             (*info->fprintf_func) (info->stream, "%s??",
1072                                    need_comma ? "," : "");
1073             need_comma = 1;
1074           }
1075         else if (smask > 0)
1076           {
1077             (*info->fprintf_func) (info->stream, "%s$%s",
1078                                    need_comma ? "," : "",
1079                                    reg_names[16]);
1080             if (smask > 1)
1081               (*info->fprintf_func) (info->stream, "-$%s",
1082                                      reg_names[smask + 15]);
1083             need_comma = 1;
1084           }
1085
1086         if (l & 1)
1087           {
1088             (*info->fprintf_func) (info->stream, "%s$%s",
1089                                    need_comma ? "," : "",
1090                                    reg_names[31]);
1091             need_comma = 1;
1092           }
1093
1094         if (amask == 5 || amask == 6)
1095           {
1096             (*info->fprintf_func) (info->stream, "%s$f0",
1097                                    need_comma ? "," : "");
1098             if (amask == 6)
1099               (*info->fprintf_func) (info->stream, "-$f1");
1100           }
1101       }
1102       break;
1103
1104     default:
1105       abort ();
1106     }
1107 }