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