formatting fixes
[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 #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.065531 seconds and 5 git commands to generate.