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