52efafe38b44ae80d84daebb056e0d09e239004c
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (c) 1989, 91-97, 1998 Free Software Foundation, Inc.
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include <ansidecl.h>
22 #include "sysdep.h"
23 #include "dis-asm.h"
24 #include "opcode/mips.h"
25 #include "opintl.h"
26
27 /* FIXME: These are needed to figure out if the code is mips16 or
28 not. The low bit of the address is often a good indicator. No
29 symbol table is available when this code runs out in an embedded
30 system as when it is used for disassembler support in a monitor. */
31
32 #if !defined(EMBEDDED_ENV)
33 #define SYMTAB_AVAILABLE 1
34 #include "elf-bfd.h"
35 #include "elf/mips.h"
36 #endif
37
38 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
39 static void print_mips16_insn_arg
40 PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
41 struct disassemble_info *));
42
43 /* Mips instructions are never longer than this many bytes. */
44 #define MAXLEN 4
45
46 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
47 struct disassemble_info *));
48 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
49 struct disassemble_info *));
50
51 \f
52 /* FIXME: This should be shared with gdb somehow. */
53 #define REGISTER_NAMES \
54 { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
55 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
56 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
57 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
58 "sr", "lo", "hi", "bad", "cause","pc", \
59 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
60 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
61 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
62 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
63 "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
64 "epc", "prid"\
65 }
66
67 static CONST char * CONST reg_names[] = REGISTER_NAMES;
68
69 /* The mips16 register names. */
70 static const char * const mips16_reg_names[] =
71 {
72 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
73 };
74 \f
75 /* subroutine */
76 static void
77 print_insn_arg (d, l, pc, info)
78 const char *d;
79 register unsigned long int l;
80 bfd_vma pc;
81 struct disassemble_info *info;
82 {
83 int delta;
84
85 switch (*d)
86 {
87 case ',':
88 case '(':
89 case ')':
90 /* start-sanitize-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
380
381 #if SYMTAB_AVAILABLE
382
383 static
384 void set_mips_isa_type (int mach, int * isa, int *cputype)
385 {
386 int target_processor = 0 ;
387 int mips_isa = 0 ;
388 switch (mach)
389 {
390 /* start-sanitize-tx19 */
391 case bfd_mach_mips1900:
392 target_processor = 1900;
393 mips_isa = 1;
394 break;
395 /* end-sanitize-tx19 */
396 case bfd_mach_mips3000:
397 target_processor = 3000;
398 mips_isa = 1;
399 break;
400 case bfd_mach_mips3900:
401 target_processor = 3900;
402 mips_isa = 1;
403 break;
404 case bfd_mach_mips4000:
405 target_processor = 4000;
406 mips_isa = 3;
407 break;
408 case bfd_mach_mips4010:
409 target_processor = 4010;
410 mips_isa = 2;
411 break;
412 case bfd_mach_mips4100:
413 target_processor = 4100;
414 mips_isa = 3;
415 break;
416 case bfd_mach_mips4300:
417 target_processor = 4300;
418 mips_isa = 3;
419 break;
420 /* start-sanitize-vr4320 */
421 case bfd_mach_mips4320:
422 target_processor = 4320;
423 mips_isa = 3;
424 break;
425 /* end-sanitize-vr4320 */
426 case bfd_mach_mips4400:
427 target_processor = 4400;
428 mips_isa = 3;
429 break;
430 case bfd_mach_mips4600:
431 target_processor = 4600;
432 mips_isa = 3;
433 break;
434 case bfd_mach_mips4650:
435 target_processor = 4650;
436 mips_isa = 3;
437 break;
438 /* start-sanitize-tx49 */
439 case bfd_mach_mips4900:
440 target_processor = 4900;
441 mips_isa = 3;
442 break;
443 /* end-sanitize-tx49 */
444 case bfd_mach_mips5000:
445 target_processor = 5000;
446 mips_isa = 4;
447 break;
448 /* start-sanitize-vr5400 */
449 case bfd_mach_mips5400:
450 target_processor = 5400;
451 mips_isa = 3;
452 break;
453 /* end-sanitize-vr5400 */
454 /* start-sanitize-r5900 */
455 case bfd_mach_mips5900:
456 target_processor = 5900;
457 mips_isa = 3;
458 break;
459 /* end-sanitize-r5900 */
460 case bfd_mach_mips6000:
461 target_processor = 6000;
462 mips_isa = 2;
463 break;
464 case bfd_mach_mips8000:
465 target_processor = 8000;
466 mips_isa = 4;
467 break;
468 case bfd_mach_mips10000:
469 target_processor = 10000;
470 mips_isa = 4;
471 break;
472 case bfd_mach_mips16:
473 target_processor = 16;
474 mips_isa = 3;
475 break;
476 default:
477 target_processor = 3000;
478 mips_isa = 3;
479 break;
480
481 }
482 *isa = mips_isa ;
483 *cputype = target_processor ;
484 }
485 #endif /* symbol table available */
486
487 /* Print the mips instruction at address MEMADDR in debugged memory,
488 on using INFO. Returns length of the instruction, in bytes, which is
489 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
490 this is little-endian code. */
491
492 static int
493 _print_insn_mips (memaddr, word, info)
494 bfd_vma memaddr;
495 unsigned long int word;
496 struct disassemble_info *info;
497 {
498 register const struct mips_opcode *op;
499 int target_processor, mips_isa;
500 static boolean init = 0;
501 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
502
503 /* Build a hash table to shorten the search time. */
504 if (! init)
505 {
506 unsigned int i;
507
508 for (i = 0; i <= OP_MASK_OP; i++)
509 {
510 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
511 {
512 if (op->pinfo == INSN_MACRO)
513 continue;
514 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
515 {
516 mips_hash[i] = op;
517 break;
518 }
519 }
520 }
521
522 init = 1;
523 }
524 #if ! SYMTAB_AVAILABLE
525 /* This is running out on a target machine, not in a host tool */
526 target_processor = mips_target_info.processor ;
527 mips_isa = mips_target_info.isa ;
528 #else
529 set_mips_isa_type(info->mach, &target_processor, &mips_isa) ;
530 #endif
531
532 info->bytes_per_chunk = 4;
533 info->display_endian = info->endian;
534
535 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
536 if (op != NULL)
537 {
538 for (; op < &mips_opcodes[NUMOPCODES]; op++)
539 {
540 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
541 {
542 register const char *d;
543 int insn_isa;
544
545 if ((op->membership & INSN_ISA) == INSN_ISA1)
546 insn_isa = 1;
547 else if ((op->membership & INSN_ISA) == INSN_ISA2)
548 insn_isa = 2;
549 else if ((op->membership & INSN_ISA) == INSN_ISA3)
550 insn_isa = 3;
551 else if ((op->membership & INSN_ISA) == INSN_ISA4)
552 insn_isa = 4;
553 else
554 insn_isa = 15;
555
556 if (insn_isa > mips_isa
557 && (target_processor == 4650
558 && op->membership & INSN_4650) == 0
559 && (target_processor == 4010
560 && op->membership & INSN_4010) == 0
561 && (target_processor == 4100
562 && op->membership & INSN_4100) == 0
563 /* start-sanitize-vr4320 */
564 && (target_processor == 4320
565 && op->membership & INSN_4320) == 0
566 /* end-sanitize-vr4320 */
567 /* start-sanitize-vr5400 */
568 && (target_processor == 5400
569 && op->membership & INSN_5400) == 0
570 /* end-sanitize-vr5400 */
571 /* start-sanitize-r5900 */
572 && (target_processor == 5900
573 && op->membership & INSN_5900) == 0
574 /* end-sanitize-r5900 */
575 /* start-sanitize-tx49 */
576 && (target_processor == 4900
577 && op->membership & INSN_4900) == 0
578 /* end-sanitize-tx49 */
579 && (target_processor == 3900
580 && op->membership & INSN_3900) == 0)
581 continue;
582
583 (*info->fprintf_func) (info->stream, "%s", op->name);
584
585 d = op->args;
586 if (d != NULL && *d != '\0')
587 {
588 /* start-sanitize-r5900 */
589 /* If this is an opcode completer, then do not emit
590 a tab after the opcode. */
591 if (*d != '&' && *d != ';')
592 /* end-sanitize-r5900 */
593 (*info->fprintf_func) (info->stream, "\t");
594 for (; *d != '\0'; d++)
595 /* start-sanitize-r5900 */
596 /* If this is an escape character, go ahead and print the
597 next character in the arg string verbatim. */
598 if (*d == '#')
599 {
600 d++;
601 (*info->fprintf_func) (info->stream, "%c", *d);
602 }
603 else
604 /* end-sanitize-r5900 */
605 print_insn_arg (d, word, memaddr, info);
606 }
607
608 return 4;
609 }
610 }
611 }
612
613 /* Handle undefined instructions. */
614 (*info->fprintf_func) (info->stream, "0x%x", word);
615 return 4;
616 }
617
618
619 /* In an environment where we do not know the symbol type of the instruction
620 we are forces to assumd the low order bit of the instructions address
621 may mark it as a mips16 instruction. If we are sincle stepping or the
622 pc is within the disassembled function, this works. Otherwise,
623 we need a clue. Sometimes. */
624
625
626 int
627 print_insn_big_mips (memaddr, info)
628 bfd_vma memaddr;
629 struct disassemble_info *info;
630 {
631 bfd_byte buffer[4];
632 int status;
633
634 #if 1
635 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction */
636 /* Only a few tools will work this way */
637 if (memaddr & 0x01)
638 return print_insn_mips16 (memaddr, info);
639 #endif
640
641 #if SYMTAB_AVAILABLE
642 if (info->mach == 16
643 || (info->flavour == bfd_target_elf_flavour
644 && info->symbols != NULL
645 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
646 == STO_MIPS16)))
647 return print_insn_mips16 (memaddr, info);
648 #endif
649
650 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
651 if (status == 0)
652 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
653 info);
654 else
655 {
656 (*info->memory_error_func) (status, memaddr, info);
657 return -1;
658 }
659 }
660
661 int
662 print_insn_little_mips (memaddr, info)
663 bfd_vma memaddr;
664 struct disassemble_info *info;
665 {
666 bfd_byte buffer[4];
667 int status;
668
669 /* start-sanitize-sky */
670 #ifdef ARCH_dvp
671 {
672 /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
673 once. Since dvp_mach_type is a function, ensure it's only called
674 once. */
675 int mach = dvp_info_mach_type (info);
676
677 if (bfd_mach_dvp_p (info->mach)
678 || bfd_mach_dvp_p (mach))
679 return print_insn_dvp (memaddr, info);
680 }
681 #endif
682 /* end-sanitize-sky */
683
684 #if 1
685 if (memaddr & 0x01) return print_insn_mips16 (memaddr, info);
686 #endif
687
688 #if SYMTAB_AVAILABLE
689 if (info->mach == 16
690 || (info->flavour == bfd_target_elf_flavour
691 && info->symbols != NULL
692 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
693 == STO_MIPS16)))
694 return print_insn_mips16 (memaddr, info);
695 #endif
696
697 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
698 if (status == 0)
699 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
700 info);
701 else
702 {
703 (*info->memory_error_func) (status, memaddr, info);
704 return -1;
705 }
706 }
707 \f
708 /* Disassemble mips16 instructions. */
709
710 static int
711 print_insn_mips16 (memaddr, info)
712 bfd_vma memaddr;
713 struct disassemble_info *info;
714 {
715 int status;
716 bfd_byte buffer[2];
717 int length;
718 int insn;
719 boolean use_extend;
720 int extend = 0;
721 const struct mips_opcode *op, *opend;
722
723 info->bytes_per_chunk = 2;
724 info->display_endian = info->endian;
725
726 info->insn_info_valid = 1;
727 info->branch_delay_insns = 0;
728 info->data_size = 0;
729 info->insn_type = dis_nonbranch;
730 info->target = 0;
731 info->target2 = 0;
732
733 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
734 if (status != 0)
735 {
736 (*info->memory_error_func) (status, memaddr, info);
737 return -1;
738 }
739
740 length = 2;
741
742 if (info->endian == BFD_ENDIAN_BIG)
743 insn = bfd_getb16 (buffer);
744 else
745 insn = bfd_getl16 (buffer);
746
747 /* Handle the extend opcode specially. */
748 use_extend = false;
749 if ((insn & 0xf800) == 0xf000)
750 {
751 use_extend = true;
752 extend = insn & 0x7ff;
753
754 memaddr += 2;
755
756 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
757 if (status != 0)
758 {
759 (*info->fprintf_func) (info->stream, "extend 0x%x",
760 (unsigned int) extend);
761 (*info->memory_error_func) (status, memaddr, info);
762 return -1;
763 }
764
765 if (info->endian == BFD_ENDIAN_BIG)
766 insn = bfd_getb16 (buffer);
767 else
768 insn = bfd_getl16 (buffer);
769
770 /* Check for an extend opcode followed by an extend opcode. */
771 if ((insn & 0xf800) == 0xf000)
772 {
773 (*info->fprintf_func) (info->stream, "extend 0x%x",
774 (unsigned int) extend);
775 info->insn_type = dis_noninsn;
776 return length;
777 }
778
779 length += 2;
780 }
781
782 /* FIXME: Should probably use a hash table on the major opcode here. */
783
784 opend = mips16_opcodes + bfd_mips16_num_opcodes;
785 for (op = mips16_opcodes; op < opend; op++)
786 {
787 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
788 {
789 const char *s;
790
791 if (strchr (op->args, 'a') != NULL)
792 {
793 if (use_extend)
794 {
795 (*info->fprintf_func) (info->stream, "extend 0x%x",
796 (unsigned int) extend);
797 info->insn_type = dis_noninsn;
798 return length - 2;
799 }
800
801 use_extend = false;
802
803 memaddr += 2;
804
805 status = (*info->read_memory_func) (memaddr, buffer, 2,
806 info);
807 if (status == 0)
808 {
809 use_extend = true;
810 if (info->endian == BFD_ENDIAN_BIG)
811 extend = bfd_getb16 (buffer);
812 else
813 extend = bfd_getl16 (buffer);
814 length += 2;
815 }
816 }
817
818 (*info->fprintf_func) (info->stream, "%s", op->name);
819 if (op->args[0] != '\0')
820 (*info->fprintf_func) (info->stream, "\t");
821
822 for (s = op->args; *s != '\0'; s++)
823 {
824 if (*s == ','
825 && s[1] == 'w'
826 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
827 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
828 {
829 /* Skip the register and the comma. */
830 ++s;
831 continue;
832 }
833 if (*s == ','
834 && s[1] == 'v'
835 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
836 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
837 {
838 /* Skip the register and the comma. */
839 ++s;
840 continue;
841 }
842 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
843 info);
844 }
845
846 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
847 {
848 info->branch_delay_insns = 1;
849 if (info->insn_type != dis_jsr)
850 info->insn_type = dis_branch;
851 }
852
853 return length;
854 }
855 }
856
857 if (use_extend)
858 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
859 (*info->fprintf_func) (info->stream, "0x%x", insn);
860 info->insn_type = dis_noninsn;
861
862 return length;
863 }
864
865 /* Disassemble an operand for a mips16 instruction. */
866
867 static void
868 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
869 int type;
870 const struct mips_opcode *op;
871 int l;
872 boolean use_extend;
873 int extend;
874 bfd_vma memaddr;
875 struct disassemble_info *info;
876 {
877 switch (type)
878 {
879 case ',':
880 case '(':
881 case ')':
882 (*info->fprintf_func) (info->stream, "%c", type);
883 break;
884
885 case 'y':
886 case 'w':
887 (*info->fprintf_func) (info->stream, "$%s",
888 mips16_reg_names[((l >> MIPS16OP_SH_RY)
889 & MIPS16OP_MASK_RY)]);
890 break;
891
892 case 'x':
893 case 'v':
894 (*info->fprintf_func) (info->stream, "$%s",
895 mips16_reg_names[((l >> MIPS16OP_SH_RX)
896 & MIPS16OP_MASK_RX)]);
897 break;
898
899 case 'z':
900 (*info->fprintf_func) (info->stream, "$%s",
901 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
902 & MIPS16OP_MASK_RZ)]);
903 break;
904
905 case 'Z':
906 (*info->fprintf_func) (info->stream, "$%s",
907 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
908 & MIPS16OP_MASK_MOVE32Z)]);
909 break;
910
911 case '0':
912 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
913 break;
914
915 case 'S':
916 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
917 break;
918
919 case 'P':
920 (*info->fprintf_func) (info->stream, "$pc");
921 break;
922
923 case 'R':
924 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
925 break;
926
927 case 'X':
928 (*info->fprintf_func) (info->stream, "$%s",
929 reg_names[((l >> MIPS16OP_SH_REGR32)
930 & MIPS16OP_MASK_REGR32)]);
931 break;
932
933 case 'Y':
934 (*info->fprintf_func) (info->stream, "$%s",
935 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
936 break;
937
938 case '<':
939 case '>':
940 case '[':
941 case ']':
942 case '4':
943 case '5':
944 case 'H':
945 case 'W':
946 case 'D':
947 case 'j':
948 case '6':
949 case '8':
950 case 'V':
951 case 'C':
952 case 'U':
953 case 'k':
954 case 'K':
955 case 'p':
956 case 'q':
957 case 'A':
958 case 'B':
959 case 'E':
960 {
961 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
962
963 shift = 0;
964 signedp = 0;
965 extbits = 16;
966 pcrel = 0;
967 extu = 0;
968 branch = 0;
969 switch (type)
970 {
971 case '<':
972 nbits = 3;
973 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
974 extbits = 5;
975 extu = 1;
976 break;
977 case '>':
978 nbits = 3;
979 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
980 extbits = 5;
981 extu = 1;
982 break;
983 case '[':
984 nbits = 3;
985 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
986 extbits = 6;
987 extu = 1;
988 break;
989 case ']':
990 nbits = 3;
991 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
992 extbits = 6;
993 extu = 1;
994 break;
995 case '4':
996 nbits = 4;
997 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
998 signedp = 1;
999 extbits = 15;
1000 break;
1001 case '5':
1002 nbits = 5;
1003 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1004 info->insn_type = dis_dref;
1005 info->data_size = 1;
1006 break;
1007 case 'H':
1008 nbits = 5;
1009 shift = 1;
1010 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1011 info->insn_type = dis_dref;
1012 info->data_size = 2;
1013 break;
1014 case 'W':
1015 nbits = 5;
1016 shift = 2;
1017 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1018 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1019 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1020 {
1021 info->insn_type = dis_dref;
1022 info->data_size = 4;
1023 }
1024 break;
1025 case 'D':
1026 nbits = 5;
1027 shift = 3;
1028 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1029 info->insn_type = dis_dref;
1030 info->data_size = 8;
1031 break;
1032 case 'j':
1033 nbits = 5;
1034 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1035 signedp = 1;
1036 break;
1037 case '6':
1038 nbits = 6;
1039 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1040 break;
1041 case '8':
1042 nbits = 8;
1043 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1044 break;
1045 case 'V':
1046 nbits = 8;
1047 shift = 2;
1048 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1049 /* FIXME: This might be lw, or it might be addiu to $sp or
1050 $pc. We assume it's load. */
1051 info->insn_type = dis_dref;
1052 info->data_size = 4;
1053 break;
1054 case 'C':
1055 nbits = 8;
1056 shift = 3;
1057 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1058 info->insn_type = dis_dref;
1059 info->data_size = 8;
1060 break;
1061 case 'U':
1062 nbits = 8;
1063 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1064 extu = 1;
1065 break;
1066 case 'k':
1067 nbits = 8;
1068 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1069 signedp = 1;
1070 break;
1071 case 'K':
1072 nbits = 8;
1073 shift = 3;
1074 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1075 signedp = 1;
1076 break;
1077 case 'p':
1078 nbits = 8;
1079 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1080 signedp = 1;
1081 pcrel = 1;
1082 branch = 1;
1083 info->insn_type = dis_condbranch;
1084 break;
1085 case 'q':
1086 nbits = 11;
1087 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1088 signedp = 1;
1089 pcrel = 1;
1090 branch = 1;
1091 info->insn_type = dis_branch;
1092 break;
1093 case 'A':
1094 nbits = 8;
1095 shift = 2;
1096 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1097 pcrel = 1;
1098 /* FIXME: This can be lw or la. We assume it is lw. */
1099 info->insn_type = dis_dref;
1100 info->data_size = 4;
1101 break;
1102 case 'B':
1103 nbits = 5;
1104 shift = 3;
1105 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1106 pcrel = 1;
1107 info->insn_type = dis_dref;
1108 info->data_size = 8;
1109 break;
1110 case 'E':
1111 nbits = 5;
1112 shift = 2;
1113 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1114 pcrel = 1;
1115 break;
1116 default:
1117 abort ();
1118 }
1119
1120 if (! use_extend)
1121 {
1122 if (signedp && immed >= (1 << (nbits - 1)))
1123 immed -= 1 << nbits;
1124 immed <<= shift;
1125 if ((type == '<' || type == '>' || type == '[' || type == ']')
1126 && immed == 0)
1127 immed = 8;
1128 }
1129 else
1130 {
1131 if (extbits == 16)
1132 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1133 else if (extbits == 15)
1134 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1135 else
1136 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1137 immed &= (1 << extbits) - 1;
1138 if (! extu && immed >= (1 << (extbits - 1)))
1139 immed -= 1 << extbits;
1140 }
1141
1142 if (! pcrel)
1143 (*info->fprintf_func) (info->stream, "%d", immed);
1144 else
1145 {
1146 bfd_vma baseaddr;
1147 bfd_vma val;
1148
1149 if (branch)
1150 {
1151 immed *= 2;
1152 baseaddr = memaddr + 2;
1153 }
1154 else if (use_extend)
1155 baseaddr = memaddr - 2;
1156 else
1157 {
1158 int status;
1159 bfd_byte buffer[2];
1160
1161 baseaddr = memaddr;
1162
1163 /* If this instruction is in the delay slot of a jr
1164 instruction, the base address is the address of the
1165 jr instruction. If it is in the delay slot of jalr
1166 instruction, the base address is the address of the
1167 jalr instruction. This test is unreliable: we have
1168 no way of knowing whether the previous word is
1169 instruction or data. */
1170 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1171 info);
1172 if (status == 0
1173 && (((info->endian == BFD_ENDIAN_BIG
1174 ? bfd_getb16 (buffer)
1175 : bfd_getl16 (buffer))
1176 & 0xf800) == 0x1800))
1177 baseaddr = memaddr - 4;
1178 else
1179 {
1180 status = (*info->read_memory_func) (memaddr - 2, buffer,
1181 2, info);
1182 if (status == 0
1183 && (((info->endian == BFD_ENDIAN_BIG
1184 ? bfd_getb16 (buffer)
1185 : bfd_getl16 (buffer))
1186 & 0xf81f) == 0xe800))
1187 baseaddr = memaddr - 2;
1188 }
1189 }
1190 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1191 (*info->print_address_func) (val, info);
1192 info->target = val;
1193 }
1194 }
1195 break;
1196
1197 case 'a':
1198 if (! use_extend)
1199 extend = 0;
1200 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1201 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1202 info->insn_type = dis_jsr;
1203 info->target = (memaddr & 0xf0000000) | l;
1204 info->branch_delay_insns = 1;
1205 break;
1206
1207 case 'l':
1208 case 'L':
1209 {
1210 int need_comma, amask, smask;
1211
1212 need_comma = 0;
1213
1214 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1215
1216 amask = (l >> 3) & 7;
1217
1218 if (amask > 0 && amask < 5)
1219 {
1220 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1221 if (amask > 1)
1222 (*info->fprintf_func) (info->stream, "-$%s",
1223 reg_names[amask + 3]);
1224 need_comma = 1;
1225 }
1226
1227 smask = (l >> 1) & 3;
1228 if (smask == 3)
1229 {
1230 (*info->fprintf_func) (info->stream, "%s??",
1231 need_comma ? "," : "");
1232 need_comma = 1;
1233 }
1234 else if (smask > 0)
1235 {
1236 (*info->fprintf_func) (info->stream, "%s$%s",
1237 need_comma ? "," : "",
1238 reg_names[16]);
1239 if (smask > 1)
1240 (*info->fprintf_func) (info->stream, "-$%s",
1241 reg_names[smask + 15]);
1242 need_comma = 1;
1243 }
1244
1245 if (l & 1)
1246 {
1247 (*info->fprintf_func) (info->stream, "%s$%s",
1248 need_comma ? "," : "",
1249 reg_names[31]);
1250 need_comma = 1;
1251 }
1252
1253 if (amask == 5 || amask == 6)
1254 {
1255 (*info->fprintf_func) (info->stream, "%s$f0",
1256 need_comma ? "," : "");
1257 if (amask == 6)
1258 (*info->fprintf_func) (info->stream, "-$f1");
1259 }
1260 }
1261 break;
1262
1263 default:
1264 abort ();
1265 }
1266 }
This page took 0.05686 seconds and 4 git commands to generate.