]> Git Repo - binutils.git/blob - opcodes/mips-dis.c
formatting fixes
[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([email protected]).
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-vr5400 */
91     case '[':
92     case ']':
93       /* end-sanitize-vr5400 */
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-vr5400 */
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-vr5400 */
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       case bfd_mach_mips4300:
422         target_processor = 4300;
423         mips_isa = 3;
424         break;
425         /* start-sanitize-vr4320 */
426       case bfd_mach_mips4320:
427         target_processor = 4320;
428         mips_isa = 3;
429         break;
430         /* end-sanitize-vr4320 */
431       case bfd_mach_mips4400:
432         target_processor = 4400;
433         mips_isa = 3;
434         break;
435       case bfd_mach_mips4600:
436         target_processor = 4600;
437         mips_isa = 3;
438         break;
439       case bfd_mach_mips4650:
440         target_processor = 4650;
441         mips_isa = 3;
442         break;
443       /* start-sanitize-tx49 */
444       case bfd_mach_mips4900:
445         target_processor = 4900;
446         mips_isa = 3;
447         break;
448       /* end-sanitize-tx49 */
449       case bfd_mach_mips5000:
450         target_processor = 5000;
451         mips_isa = 4;
452         break;
453       /* start-sanitize-vr5400 */
454       case bfd_mach_mips5400:
455         target_processor = 5400;
456         mips_isa = 3;
457         break;
458       /* end-sanitize-vr5400 */
459       /* start-sanitize-r5900 */
460       case bfd_mach_mips5900:
461         target_processor = 5900;
462         mips_isa = 3;
463         break;
464       /* end-sanitize-r5900 */
465       case bfd_mach_mips6000:
466         target_processor = 6000;
467         mips_isa = 2;
468         break;
469       case bfd_mach_mips8000:
470         target_processor = 8000;
471         mips_isa = 4;
472         break;
473       case bfd_mach_mips10000:
474         target_processor = 10000;
475         mips_isa = 4;
476         break;
477       case bfd_mach_mips16:
478         target_processor = 16;
479         mips_isa = 3;
480         break;
481       default:
482         target_processor = 3000;
483         mips_isa = 3;
484         break;
485
486     }
487
488   *isa = mips_isa;
489   *cputype = target_processor;
490 }
491
492 #endif /* SYMTAB_AVAILABLE */
493
494 /* Print the mips instruction at address MEMADDR in debugged memory,
495    on using INFO.  Returns length of the instruction, in bytes, which is
496    always 4.  BIGENDIAN must be 1 if this is big-endian code, 0 if
497    this is little-endian code.  */
498
499 static int
500 _print_insn_mips (memaddr, word, info)
501      bfd_vma memaddr;
502      unsigned long int word;
503      struct disassemble_info *info;
504 {
505   register const struct mips_opcode *op;
506   int target_processor, mips_isa;
507   static boolean init = 0;
508   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
509
510   /* Build a hash table to shorten the search time.  */
511   if (! init)
512     {
513       unsigned int i;
514
515       for (i = 0; i <= OP_MASK_OP; i++)
516         {
517           for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
518             {
519               if (op->pinfo == INSN_MACRO)
520                 continue;
521               if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
522                 {
523                   mips_hash[i] = op;
524                   break;
525                 }
526             }
527         }
528
529       init = 1;
530     }
531
532 #if ! SYMTAB_AVAILABLE
533   /* This is running out on a target machine, not in a host tool.
534      FIXME: Where does mips_target_info come from?  */
535   target_processor = mips_target_info.processor;
536   mips_isa = mips_target_info.isa;
537 #else  
538   set_mips_isa_type (info->mach, &target_processor, &mips_isa);
539 #endif  
540
541   info->bytes_per_chunk = 4;
542   info->display_endian = info->endian;
543
544   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
545   if (op != NULL)
546     {
547       for (; op < &mips_opcodes[NUMOPCODES]; op++)
548         {
549           if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
550             {
551               register const char *d;
552               int insn_isa;
553
554               if ((op->membership & INSN_ISA) == INSN_ISA1)
555                 insn_isa = 1;
556               else if ((op->membership & INSN_ISA) == INSN_ISA2)
557                 insn_isa = 2;
558               else if ((op->membership & INSN_ISA) == INSN_ISA3)
559                 insn_isa = 3;
560               else if ((op->membership & INSN_ISA) == INSN_ISA4)
561                 insn_isa = 4;
562               else
563                 insn_isa = 15;
564
565               if (insn_isa > mips_isa
566                   && (target_processor == 4650
567                       && op->membership & INSN_4650) == 0
568                   && (target_processor == 4010
569                       && op->membership & INSN_4010) == 0
570                   && (target_processor == 4100
571                       && op->membership & INSN_4100) == 0
572                   /* start-sanitize-vr4320 */
573                   && (target_processor == 4320
574                       && op->membership & INSN_4320) == 0
575                   /* end-sanitize-vr4320 */
576                   /* start-sanitize-vr5400 */
577                   && (target_processor == 5400
578                       && op->membership & INSN_5400) == 0
579                   /* end-sanitize-vr5400 */
580                   /* start-sanitize-r5900 */
581                   && (target_processor == 5900
582                       && op->membership & INSN_5900) == 0
583                   /* end-sanitize-r5900 */
584                   /* start-sanitize-tx49 */
585                   && (target_processor == 4900
586                       && op->membership & INSN_4900) == 0
587                   /* end-sanitize-tx49 */
588                   && (target_processor == 3900
589                       && op->membership & INSN_3900) == 0)
590                 continue;
591
592               (*info->fprintf_func) (info->stream, "%s", op->name);
593
594               d = op->args;
595               if (d != NULL && *d != '\0')
596                 {
597                   /* start-sanitize-r5900 */
598                   /* If this is an opcode completer, then do not emit
599                      a tab after the opcode.  */
600                   if (*d != '&' && *d != ';')
601                   /* end-sanitize-r5900 */
602                     (*info->fprintf_func) (info->stream, "\t");
603                   for (; *d != '\0'; d++)
604                     /* start-sanitize-r5900 */
605                     /* If this is an escape character, go ahead and print the
606                        next character in the arg string verbatim.  */
607                     if (*d == '#')
608                       {
609                         d++;
610                         (*info->fprintf_func) (info->stream, "%c", *d);
611                       }
612                     else
613                     /* end-sanitize-r5900 */
614                       print_insn_arg (d, word, memaddr, info);
615                 }
616
617               return 4;
618             }
619         }
620     }
621
622   /* Handle undefined instructions.  */
623   (*info->fprintf_func) (info->stream, "0x%x", word);
624   return 4;
625 }
626
627
628 /* In an environment where we do not know the symbol type of the
629    instruction we are forced to assume that the low order bit of the
630    instructions' address may mark it as a mips16 instruction.  If we
631    are single stepping, or the pc is within the disassembled function,
632    this works.  Otherwise, we need a clue.  Sometimes.  */
633
634 int
635 print_insn_big_mips (memaddr, info)
636      bfd_vma memaddr;
637      struct disassemble_info *info;
638 {
639   bfd_byte buffer[4];
640   int status;
641
642 #if 1
643   /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
644   /* Only a few tools will work this way.  */
645   if (memaddr & 0x01)
646     return print_insn_mips16 (memaddr, info);
647 #endif  
648
649 #if SYMTAB_AVAILABLE
650   if (info->mach == 16
651       || (info->flavour == bfd_target_elf_flavour
652           && info->symbols != NULL
653           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
654               == STO_MIPS16)))
655     return print_insn_mips16 (memaddr, info);
656 #endif  
657
658   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
659   if (status == 0)
660     return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
661                              info);
662   else
663     {
664       (*info->memory_error_func) (status, memaddr, info);
665       return -1;
666     }
667 }
668
669 int
670 print_insn_little_mips (memaddr, info)
671      bfd_vma memaddr;
672      struct disassemble_info *info;
673 {
674   bfd_byte buffer[4];
675   int status;
676
677   /* start-sanitize-sky */
678 #ifdef ARCH_dvp
679   {
680     /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
681        once.  Since dvp_mach_type is a function, ensure it's only called
682        once.  */
683     int mach = dvp_info_mach_type (info);
684
685     if (bfd_mach_dvp_p (info->mach)
686         || bfd_mach_dvp_p (mach))
687       return print_insn_dvp (memaddr, info);
688   }
689 #endif
690   /* end-sanitize-sky */
691
692 #if 1
693   if (memaddr & 0x01)
694     return print_insn_mips16 (memaddr, info);
695 #endif  
696
697 #if SYMTAB_AVAILABLE
698   if (info->mach == 16
699       || (info->flavour == bfd_target_elf_flavour
700           && info->symbols != NULL
701           && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
702               == STO_MIPS16)))
703     return print_insn_mips16 (memaddr, info);
704 #endif  
705
706   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
707   if (status == 0)
708     return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
709                              info);
710   else
711     {
712       (*info->memory_error_func) (status, memaddr, info);
713       return -1;
714     }
715 }
716 \f
717 /* Disassemble mips16 instructions.  */
718
719 static int
720 print_insn_mips16 (memaddr, info)
721      bfd_vma memaddr;
722      struct disassemble_info *info;
723 {
724   int status;
725   bfd_byte buffer[2];
726   int length;
727   int insn;
728   boolean use_extend;
729   int extend = 0;
730   const struct mips_opcode *op, *opend;
731
732   info->bytes_per_chunk = 2;
733   info->display_endian = info->endian;
734
735   info->insn_info_valid = 1;
736   info->branch_delay_insns = 0;
737   info->data_size = 0;
738   info->insn_type = dis_nonbranch;
739   info->target = 0;
740   info->target2 = 0;
741
742   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
743   if (status != 0)
744     {
745       (*info->memory_error_func) (status, memaddr, info);
746       return -1;
747     }
748
749   length = 2;
750
751   if (info->endian == BFD_ENDIAN_BIG)
752     insn = bfd_getb16 (buffer);
753   else
754     insn = bfd_getl16 (buffer);
755
756   /* Handle the extend opcode specially.  */
757   use_extend = false;
758   if ((insn & 0xf800) == 0xf000)
759     {
760       use_extend = true;
761       extend = insn & 0x7ff;
762
763       memaddr += 2;
764
765       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
766       if (status != 0)
767         {
768           (*info->fprintf_func) (info->stream, "extend 0x%x",
769                                  (unsigned int) extend);
770           (*info->memory_error_func) (status, memaddr, info);
771           return -1;
772         }
773
774       if (info->endian == BFD_ENDIAN_BIG)
775         insn = bfd_getb16 (buffer);
776       else
777         insn = bfd_getl16 (buffer);
778
779       /* Check for an extend opcode followed by an extend opcode.  */
780       if ((insn & 0xf800) == 0xf000)
781         {
782           (*info->fprintf_func) (info->stream, "extend 0x%x",
783                                  (unsigned int) extend);
784           info->insn_type = dis_noninsn;
785           return length;
786         }
787
788       length += 2;
789     }
790
791   /* FIXME: Should probably use a hash table on the major opcode here.  */
792
793   opend = mips16_opcodes + bfd_mips16_num_opcodes;
794   for (op = mips16_opcodes; op < opend; op++)
795     {
796       if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
797         {
798           const char *s;
799
800           if (strchr (op->args, 'a') != NULL)
801             {
802               if (use_extend)
803                 {
804                   (*info->fprintf_func) (info->stream, "extend 0x%x",
805                                          (unsigned int) extend);
806                   info->insn_type = dis_noninsn;
807                   return length - 2;
808                 }
809
810               use_extend = false;
811
812               memaddr += 2;
813
814               status = (*info->read_memory_func) (memaddr, buffer, 2,
815                                                   info);
816               if (status == 0)
817                 {
818                   use_extend = true;
819                   if (info->endian == BFD_ENDIAN_BIG)
820                     extend = bfd_getb16 (buffer);
821                   else
822                     extend = bfd_getl16 (buffer);
823                   length += 2;
824                 }
825             }
826
827           (*info->fprintf_func) (info->stream, "%s", op->name);
828           if (op->args[0] != '\0')
829             (*info->fprintf_func) (info->stream, "\t");
830
831           for (s = op->args; *s != '\0'; s++)
832             {
833               if (*s == ','
834                   && s[1] == 'w'
835                   && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
836                       == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
837                 {
838                   /* Skip the register and the comma.  */
839                   ++s;
840                   continue;
841                 }
842               if (*s == ','
843                   && s[1] == 'v'
844                   && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
845                       == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
846                 {
847                   /* Skip the register and the comma.  */
848                   ++s;
849                   continue;
850                 }
851               print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
852                                      info);
853             }
854
855           if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
856             {
857               info->branch_delay_insns = 1;
858               if (info->insn_type != dis_jsr)
859                 info->insn_type = dis_branch;
860             }
861
862           return length;
863         }
864     }
865
866   if (use_extend)
867     (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
868   (*info->fprintf_func) (info->stream, "0x%x", insn);
869   info->insn_type = dis_noninsn;
870
871   return length;
872 }
873
874 /* Disassemble an operand for a mips16 instruction.  */
875
876 static void
877 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
878      int type;
879      const struct mips_opcode *op;
880      int l;
881      boolean use_extend;
882      int extend;
883      bfd_vma memaddr;
884      struct disassemble_info *info;
885 {
886   switch (type)
887     {
888     case ',':
889     case '(':
890     case ')':
891       (*info->fprintf_func) (info->stream, "%c", type);
892       break;
893
894     case 'y':
895     case 'w':
896       (*info->fprintf_func) (info->stream, "$%s",
897                              mips16_reg_names[((l >> MIPS16OP_SH_RY)
898                                                & MIPS16OP_MASK_RY)]);
899       break;
900
901     case 'x':
902     case 'v':
903       (*info->fprintf_func) (info->stream, "$%s",
904                              mips16_reg_names[((l >> MIPS16OP_SH_RX)
905                                                & MIPS16OP_MASK_RX)]);
906       break;
907
908     case 'z':
909       (*info->fprintf_func) (info->stream, "$%s",
910                              mips16_reg_names[((l >> MIPS16OP_SH_RZ)
911                                                & MIPS16OP_MASK_RZ)]);
912       break;
913
914     case 'Z':
915       (*info->fprintf_func) (info->stream, "$%s",
916                              mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
917                                                & MIPS16OP_MASK_MOVE32Z)]);
918       break;
919
920     case '0':
921       (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
922       break;
923
924     case 'S':
925       (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
926       break;
927
928     case 'P':
929       (*info->fprintf_func) (info->stream, "$pc");
930       break;
931
932     case 'R':
933       (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
934       break;
935
936     case 'X':
937       (*info->fprintf_func) (info->stream, "$%s",
938                              reg_names[((l >> MIPS16OP_SH_REGR32)
939                                         & MIPS16OP_MASK_REGR32)]);
940       break;
941
942     case 'Y':
943       (*info->fprintf_func) (info->stream, "$%s",
944                              reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
945       break;
946
947     case '<':
948     case '>':
949     case '[':
950     case ']':
951     case '4':
952     case '5':
953     case 'H':
954     case 'W':
955     case 'D':
956     case 'j':
957     case '6':
958     case '8':
959     case 'V':
960     case 'C':
961     case 'U':
962     case 'k':
963     case 'K':
964     case 'p':
965     case 'q':
966     case 'A':
967     case 'B':
968     case 'E':
969       {
970         int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
971
972         shift = 0;
973         signedp = 0;
974         extbits = 16;
975         pcrel = 0;
976         extu = 0;
977         branch = 0;
978         switch (type)
979           {
980           case '<':
981             nbits = 3;
982             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
983             extbits = 5;
984             extu = 1;
985             break;
986           case '>':
987             nbits = 3;
988             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
989             extbits = 5;
990             extu = 1;
991             break;
992           case '[':
993             nbits = 3;
994             immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
995             extbits = 6;
996             extu = 1;
997             break;
998           case ']':
999             nbits = 3;
1000             immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1001             extbits = 6;
1002             extu = 1;
1003             break;
1004           case '4':
1005             nbits = 4;
1006             immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1007             signedp = 1;
1008             extbits = 15;
1009             break;
1010           case '5':
1011             nbits = 5;
1012             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1013             info->insn_type = dis_dref;
1014             info->data_size = 1;
1015             break;
1016           case 'H':
1017             nbits = 5;
1018             shift = 1;
1019             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1020             info->insn_type = dis_dref;
1021             info->data_size = 2;
1022             break;
1023           case 'W':
1024             nbits = 5;
1025             shift = 2;
1026             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1027             if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1028                 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1029               {
1030                 info->insn_type = dis_dref;
1031                 info->data_size = 4;
1032               }
1033             break;
1034           case 'D':
1035             nbits = 5;
1036             shift = 3;
1037             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1038             info->insn_type = dis_dref;
1039             info->data_size = 8;
1040             break;
1041           case 'j':
1042             nbits = 5;
1043             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1044             signedp = 1;
1045             break;
1046           case '6':
1047             nbits = 6;
1048             immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1049             break;
1050           case '8':
1051             nbits = 8;
1052             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1053             break;
1054           case 'V':
1055             nbits = 8;
1056             shift = 2;
1057             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1058             /* FIXME: This might be lw, or it might be addiu to $sp or
1059                $pc.  We assume it's load.  */
1060             info->insn_type = dis_dref;
1061             info->data_size = 4;
1062             break;
1063           case 'C':
1064             nbits = 8;
1065             shift = 3;
1066             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1067             info->insn_type = dis_dref;
1068             info->data_size = 8;
1069             break;
1070           case 'U':
1071             nbits = 8;
1072             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1073             extu = 1;
1074             break;
1075           case 'k':
1076             nbits = 8;
1077             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1078             signedp = 1;
1079             break;
1080           case 'K':
1081             nbits = 8;
1082             shift = 3;
1083             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1084             signedp = 1;
1085             break;
1086           case 'p':
1087             nbits = 8;
1088             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1089             signedp = 1;
1090             pcrel = 1;
1091             branch = 1;
1092             info->insn_type = dis_condbranch;
1093             break;
1094           case 'q':
1095             nbits = 11;
1096             immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1097             signedp = 1;
1098             pcrel = 1;
1099             branch = 1;
1100             info->insn_type = dis_branch;
1101             break;
1102           case 'A':
1103             nbits = 8;
1104             shift = 2;
1105             immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1106             pcrel = 1;
1107             /* FIXME: This can be lw or la.  We assume it is lw.  */
1108             info->insn_type = dis_dref;
1109             info->data_size = 4;
1110             break;
1111           case 'B':
1112             nbits = 5;
1113             shift = 3;
1114             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1115             pcrel = 1;
1116             info->insn_type = dis_dref;
1117             info->data_size = 8;
1118             break;
1119           case 'E':
1120             nbits = 5;
1121             shift = 2;
1122             immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1123             pcrel = 1;
1124             break;
1125           default:
1126             abort ();
1127           }
1128
1129         if (! use_extend)
1130           {
1131             if (signedp && immed >= (1 << (nbits - 1)))
1132               immed -= 1 << nbits;
1133             immed <<= shift;
1134             if ((type == '<' || type == '>' || type == '[' || type == ']')
1135                 && immed == 0)
1136               immed = 8;
1137           }
1138         else
1139           {
1140             if (extbits == 16)
1141               immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1142             else if (extbits == 15)
1143               immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1144             else
1145               immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1146             immed &= (1 << extbits) - 1;
1147             if (! extu && immed >= (1 << (extbits - 1)))
1148               immed -= 1 << extbits;
1149           }
1150
1151         if (! pcrel)
1152           (*info->fprintf_func) (info->stream, "%d", immed);
1153         else
1154           {
1155             bfd_vma baseaddr;
1156             bfd_vma val;
1157
1158             if (branch)
1159               {
1160                 immed *= 2;
1161                 baseaddr = memaddr + 2;
1162               }
1163             else if (use_extend)
1164               baseaddr = memaddr - 2;
1165             else
1166               {
1167                 int status;
1168                 bfd_byte buffer[2];
1169
1170                 baseaddr = memaddr;
1171
1172                 /* If this instruction is in the delay slot of a jr
1173                    instruction, the base address is the address of the
1174                    jr instruction.  If it is in the delay slot of jalr
1175                    instruction, the base address is the address of the
1176                    jalr instruction.  This test is unreliable: we have
1177                    no way of knowing whether the previous word is
1178                    instruction or data.  */
1179                 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1180                                                     info);
1181                 if (status == 0
1182                     && (((info->endian == BFD_ENDIAN_BIG
1183                           ? bfd_getb16 (buffer)
1184                           : bfd_getl16 (buffer))
1185                          & 0xf800) == 0x1800))
1186                   baseaddr = memaddr - 4;
1187                 else
1188                   {
1189                     status = (*info->read_memory_func) (memaddr - 2, buffer,
1190                                                         2, info);
1191                     if (status == 0
1192                         && (((info->endian == BFD_ENDIAN_BIG
1193                               ? bfd_getb16 (buffer)
1194                               : bfd_getl16 (buffer))
1195                              & 0xf81f) == 0xe800))
1196                       baseaddr = memaddr - 2;
1197                   }
1198               }
1199             val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1200             (*info->print_address_func) (val, info);
1201             info->target = val;
1202           }
1203       }
1204       break;
1205
1206     case 'a':
1207       if (! use_extend)
1208         extend = 0;
1209       l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1210       (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1211       info->insn_type = dis_jsr;
1212       info->target = (memaddr & 0xf0000000) | l;
1213       info->branch_delay_insns = 1;
1214       break;
1215
1216     case 'l':
1217     case 'L':
1218       {
1219         int need_comma, amask, smask;
1220
1221         need_comma = 0;
1222
1223         l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1224
1225         amask = (l >> 3) & 7;
1226
1227         if (amask > 0 && amask < 5)
1228           {
1229             (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1230             if (amask > 1)
1231               (*info->fprintf_func) (info->stream, "-$%s",
1232                                      reg_names[amask + 3]);
1233             need_comma = 1;
1234           }
1235
1236         smask = (l >> 1) & 3;
1237         if (smask == 3)
1238           {
1239             (*info->fprintf_func) (info->stream, "%s??",
1240                                    need_comma ? "," : "");
1241             need_comma = 1;
1242           }
1243         else if (smask > 0)
1244           {
1245             (*info->fprintf_func) (info->stream, "%s$%s",
1246                                    need_comma ? "," : "",
1247                                    reg_names[16]);
1248             if (smask > 1)
1249               (*info->fprintf_func) (info->stream, "-$%s",
1250                                      reg_names[smask + 15]);
1251             need_comma = 1;
1252           }
1253
1254         if (l & 1)
1255           {
1256             (*info->fprintf_func) (info->stream, "%s$%s",
1257                                    need_comma ? "," : "",
1258                                    reg_names[31]);
1259             need_comma = 1;
1260           }
1261
1262         if (amask == 5 || amask == 6)
1263           {
1264             (*info->fprintf_func) (info->stream, "%s$f0",
1265                                    need_comma ? "," : "");
1266             if (amask == 6)
1267               (*info->fprintf_func) (info->stream, "-$f1");
1268           }
1269       }
1270       break;
1271
1272     default:
1273       abort ();
1274     }
1275 }
This page took 0.097136 seconds and 4 git commands to generate.