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