* parse.c (target_map_name_to_register): Check target specific
[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 this is a mips16 symbol or
28 not. It would be better to think of a cleaner way to do this. */
29 #include "elf-bfd.h"
30 #include "elf/mips.h"
31
32 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
33 static void print_mips16_insn_arg
34 PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
35 struct disassemble_info *));
36
37 /* Mips instructions are never longer than this many bytes. */
38 #define MAXLEN 4
39
40 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
41 struct disassemble_info *));
42 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
43 struct disassemble_info *));
44
45 \f
46 /* FIXME: This should be shared with gdb somehow. */
47 #define REGISTER_NAMES \
48 { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
49 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
50 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
51 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
52 "sr", "lo", "hi", "bad", "cause","pc", \
53 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
54 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
55 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
56 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
57 "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
58 "epc", "prid"\
59 }
60
61 static CONST char * CONST reg_names[] = REGISTER_NAMES;
62
63 /* The mips16 register names. */
64 static const char * const mips16_reg_names[] =
65 {
66 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
67 };
68 \f
69 /* subroutine */
70 static void
71 print_insn_arg (d, l, pc, info)
72 const char *d;
73 register unsigned long int l;
74 bfd_vma pc;
75 struct disassemble_info *info;
76 {
77 int delta;
78
79 switch (*d)
80 {
81 case ',':
82 case '(':
83 case ')':
84 /* start-sanitize-vr5400 */
85 case '[':
86 case ']':
87 /* end-sanitize-vr5400 */
88 /* start-sanitize-r5900 */
89 case '+':
90 case '-':
91 /* end-sanitize-r5900 */
92 (*info->fprintf_func) (info->stream, "%c", *d);
93 break;
94
95 case 's':
96 case 'b':
97 case 'r':
98 case 'v':
99 (*info->fprintf_func) (info->stream, "$%s",
100 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
101 break;
102
103 case 't':
104 case 'w':
105 (*info->fprintf_func) (info->stream, "$%s",
106 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
107 break;
108
109 case 'i':
110 case 'u':
111 (*info->fprintf_func) (info->stream, "0x%x",
112 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
113 break;
114
115 case 'j': /* same as i, but sign-extended */
116 case 'o':
117 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
118 if (delta & 0x8000)
119 delta |= ~0xffff;
120 (*info->fprintf_func) (info->stream, "%d",
121 delta);
122 break;
123
124 case 'h':
125 (*info->fprintf_func) (info->stream, "0x%x",
126 (unsigned int) ((l >> OP_SH_PREFX)
127 & OP_MASK_PREFX));
128 break;
129
130 case 'k':
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (unsigned int) ((l >> OP_SH_CACHE)
133 & OP_MASK_CACHE));
134 break;
135
136 case 'a':
137 (*info->print_address_func)
138 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
139 info);
140 break;
141
142 case 'p':
143 /* sign extend the displacement */
144 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
145 if (delta & 0x8000)
146 delta |= ~0xffff;
147 (*info->print_address_func)
148 ((delta << 2) + pc + 4,
149 info);
150 break;
151
152 case 'd':
153 (*info->fprintf_func) (info->stream, "$%s",
154 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
155 break;
156
157 case 'z':
158 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
159 break;
160
161 case '<':
162 (*info->fprintf_func) (info->stream, "0x%x",
163 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
164 break;
165
166 case 'c':
167 (*info->fprintf_func) (info->stream, "0x%x",
168 (l >> OP_SH_CODE) & OP_MASK_CODE);
169 break;
170
171
172 case 'q':
173 (*info->fprintf_func) (info->stream, "0x%x",
174 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
175 break;
176
177 case 'C':
178 (*info->fprintf_func) (info->stream, "0x%x",
179 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
180 break;
181
182 case 'B':
183 (*info->fprintf_func) (info->stream, "0x%x",
184 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
185 break;
186
187 case 'S':
188 case 'V':
189 (*info->fprintf_func) (info->stream, "$f%d",
190 (l >> OP_SH_FS) & OP_MASK_FS);
191 break;
192
193 /* start-sanitize-r5900 */
194 case '0':
195 (*info->fprintf_func) (info->stream, "0x%x",
196 (l >> 6) & 0x1f);
197 break;
198
199 case '9':
200 (*info->fprintf_func) (info->stream, "vi27");
201 break;
202
203 case '1':
204 (*info->fprintf_func) (info->stream, "vf%d",
205 (l >> OP_SH_FT) & OP_MASK_FT);
206 break;
207 case '2':
208 (*info->fprintf_func) (info->stream, "vf%d",
209 (l >> OP_SH_FS) & OP_MASK_FS);
210 break;
211 case '3':
212 (*info->fprintf_func) (info->stream, "vf%d",
213 (l >> OP_SH_FD) & OP_MASK_FD);
214 break;
215
216 case '4':
217 (*info->fprintf_func) (info->stream, "vi%d",
218 (l >> OP_SH_FT) & OP_MASK_FT);
219 break;
220 case '5':
221 (*info->fprintf_func) (info->stream, "vi%d",
222 (l >> OP_SH_FS) & OP_MASK_FS);
223 break;
224 case '6':
225 (*info->fprintf_func) (info->stream, "vi%d",
226 (l >> OP_SH_FD) & OP_MASK_FD);
227 break;
228
229 case '7':
230 (*info->fprintf_func) (info->stream, "vf%d",
231 (l >> OP_SH_FT) & OP_MASK_FT);
232 switch ((l >> 23) & 0x3)
233 {
234 case 0:
235 (*info->fprintf_func) (info->stream, "x");
236 break;
237 case 1:
238 (*info->fprintf_func) (info->stream, "y");
239 break;
240 case 2:
241 (*info->fprintf_func) (info->stream, "z");
242 break;
243 case 3:
244 (*info->fprintf_func) (info->stream, "w");
245 break;
246 }
247 break;
248 case 'K':
249 break;
250
251 case ';':
252 (*info->fprintf_func) (info->stream, ".xyz\t");
253 break;
254
255 case '&':
256 (*info->fprintf_func) (info->stream, ".");
257 if (l & (1 << 21))
258 (*info->fprintf_func) (info->stream, "w");
259 if (l & (1 << 24))
260 (*info->fprintf_func) (info->stream, "x");
261 if (l & (1 << 23))
262 (*info->fprintf_func) (info->stream, "y");
263 if (l & (1 << 22))
264 (*info->fprintf_func) (info->stream, "z");
265 (*info->fprintf_func) (info->stream, "\t");
266 break;
267
268 case '8':
269 (*info->fprintf_func) (info->stream, "vf%d",
270 (l >> OP_SH_FS) & OP_MASK_FS);
271 switch ((l >> 21) & 0x3)
272 {
273 case 0:
274 (*info->fprintf_func) (info->stream, "x");
275 break;
276 case 1:
277 (*info->fprintf_func) (info->stream, "y");
278 break;
279 case 2:
280 (*info->fprintf_func) (info->stream, "z");
281 break;
282 case 3:
283 (*info->fprintf_func) (info->stream, "w");
284 break;
285 }
286 break;
287 case 'J':
288 (*info->fprintf_func) (info->stream, "I");
289 break;
290
291 case 'Q':
292 (*info->fprintf_func) (info->stream, "Q");
293 break;
294
295 case 'X':
296 (*info->fprintf_func) (info->stream, "R");
297 break;
298
299 case 'U':
300 (*info->fprintf_func) (info->stream, "ACC");
301 break;
302
303 case 'O':
304 delta = (l >> 6) & 0x7fff;
305 delta <<= 3;
306 (*info->print_address_func) (delta, info);
307 break;
308
309 /* end-sanitize-r5900 */
310
311 case 'T':
312 case 'W':
313 (*info->fprintf_func) (info->stream, "$f%d",
314 (l >> OP_SH_FT) & OP_MASK_FT);
315 break;
316
317 case 'D':
318 (*info->fprintf_func) (info->stream, "$f%d",
319 (l >> OP_SH_FD) & OP_MASK_FD);
320 break;
321
322 case 'R':
323 (*info->fprintf_func) (info->stream, "$f%d",
324 (l >> OP_SH_FR) & OP_MASK_FR);
325 break;
326
327 case 'E':
328 (*info->fprintf_func) (info->stream, "$%d",
329 (l >> OP_SH_RT) & OP_MASK_RT);
330 break;
331
332 case 'G':
333 (*info->fprintf_func) (info->stream, "$%d",
334 (l >> OP_SH_RD) & OP_MASK_RD);
335 break;
336
337 case 'N':
338 (*info->fprintf_func) (info->stream, "$fcc%d",
339 (l >> OP_SH_BCC) & OP_MASK_BCC);
340 break;
341
342 case 'M':
343 (*info->fprintf_func) (info->stream, "$fcc%d",
344 (l >> OP_SH_CCC) & OP_MASK_CCC);
345 break;
346
347 case 'P':
348 (*info->fprintf_func) (info->stream, "%d",
349 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
350 break;
351
352 /* start-sanitize-vr5400 */
353 case 'e':
354 (*info->fprintf_func) (info->stream, "%d",
355 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
356 break;
357
358 case '%':
359 (*info->fprintf_func) (info->stream, "%d",
360 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
361 break;
362 /* end-sanitize-vr5400 */
363
364 default:
365 /* xgettext:c-format */
366 (*info->fprintf_func) (info->stream,
367 _("# internal error, undefined modifier(%c)"),
368 *d);
369 break;
370 }
371 }
372 \f
373 /* Print the mips instruction at address MEMADDR in debugged memory,
374 on using INFO. Returns length of the instruction, in bytes, which is
375 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
376 this is little-endian code. */
377
378 static int
379 _print_insn_mips (memaddr, word, info)
380 bfd_vma memaddr;
381 unsigned long int word;
382 struct disassemble_info *info;
383 {
384 register const struct mips_opcode *op;
385 int target_processor, mips_isa;
386 static boolean init = 0;
387 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
388
389 /* Build a hash table to shorten the search time. */
390 if (! init)
391 {
392 unsigned int i;
393
394 for (i = 0; i <= OP_MASK_OP; i++)
395 {
396 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
397 {
398 if (op->pinfo == INSN_MACRO)
399 continue;
400 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
401 {
402 mips_hash[i] = op;
403 break;
404 }
405 }
406 }
407
408 init = 1;
409 }
410
411 switch (info->mach)
412 {
413 /* start-sanitize-tx19 */
414 case bfd_mach_mips1900:
415 target_processor = 1900;
416 mips_isa = 1;
417 break;
418 /* end-sanitize-tx19 */
419 case bfd_mach_mips3000:
420 target_processor = 3000;
421 mips_isa = 1;
422 break;
423 case bfd_mach_mips3900:
424 target_processor = 3900;
425 mips_isa = 1;
426 break;
427 case bfd_mach_mips4000:
428 target_processor = 4000;
429 mips_isa = 3;
430 break;
431 case bfd_mach_mips4010:
432 target_processor = 4010;
433 mips_isa = 2;
434 break;
435 case bfd_mach_mips4100:
436 target_processor = 4100;
437 mips_isa = 3;
438 break;
439 case bfd_mach_mips4300:
440 target_processor = 4300;
441 mips_isa = 3;
442 break;
443 /* start-sanitize-vr4320 */
444 case bfd_mach_mips4320:
445 target_processor = 4320;
446 mips_isa = 3;
447 break;
448 /* end-sanitize-vr4320 */
449 case bfd_mach_mips4400:
450 target_processor = 4400;
451 mips_isa = 3;
452 break;
453 case bfd_mach_mips4600:
454 target_processor = 4600;
455 mips_isa = 3;
456 break;
457 case bfd_mach_mips4650:
458 target_processor = 4650;
459 mips_isa = 3;
460 break;
461 /* start-sanitize-tx49 */
462 case bfd_mach_mips4900:
463 target_processor = 4900;
464 mips_isa = 3;
465 break;
466 /* end-sanitize-tx49 */
467 case bfd_mach_mips5000:
468 target_processor = 5000;
469 mips_isa = 4;
470 break;
471 /* start-sanitize-vr5400 */
472 case bfd_mach_mips5400:
473 target_processor = 5400;
474 mips_isa = 3;
475 break;
476 /* end-sanitize-vr5400 */
477 /* start-sanitize-r5900 */
478 case bfd_mach_mips5900:
479 target_processor = 5900;
480 mips_isa = 3;
481 break;
482 /* end-sanitize-r5900 */
483 case bfd_mach_mips6000:
484 target_processor = 6000;
485 mips_isa = 2;
486 break;
487 case bfd_mach_mips8000:
488 target_processor = 8000;
489 mips_isa = 4;
490 break;
491 case bfd_mach_mips10000:
492 target_processor = 10000;
493 mips_isa = 4;
494 break;
495 case bfd_mach_mips16:
496 target_processor = 16;
497 mips_isa = 3;
498 break;
499 default:
500 target_processor = 3000;
501 mips_isa = 3;
502 break;
503
504 }
505
506 info->bytes_per_chunk = 4;
507 info->display_endian = info->endian;
508
509 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
510 if (op != NULL)
511 {
512 for (; op < &mips_opcodes[NUMOPCODES]; op++)
513 {
514 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
515 {
516 register const char *d;
517 int insn_isa;
518
519 if ((op->membership & INSN_ISA) == INSN_ISA1)
520 insn_isa = 1;
521 else if ((op->membership & INSN_ISA) == INSN_ISA2)
522 insn_isa = 2;
523 else if ((op->membership & INSN_ISA) == INSN_ISA3)
524 insn_isa = 3;
525 else if ((op->membership & INSN_ISA) == INSN_ISA4)
526 insn_isa = 4;
527 else
528 insn_isa = 15;
529
530 if (insn_isa > mips_isa
531 && (target_processor == 4650
532 && op->membership & INSN_4650) == 0
533 && (target_processor == 4010
534 && op->membership & INSN_4010) == 0
535 && (target_processor == 4100
536 && op->membership & INSN_4100) == 0
537 /* start-sanitize-vr4320 */
538 && (target_processor == 4320
539 && op->membership & INSN_4320) == 0
540 /* end-sanitize-vr4320 */
541 /* start-sanitize-vr5400 */
542 && (target_processor == 5400
543 && op->membership & INSN_5400) == 0
544 /* end-sanitize-vr5400 */
545 /* start-sanitize-r5900 */
546 && (target_processor == 5900
547 && op->membership & INSN_5900) == 0
548 /* end-sanitize-r5900 */
549 /* start-sanitize-tx49 */
550 && (target_processor == 4900
551 && op->membership & INSN_4900) == 0
552 /* end-sanitize-tx49 */
553 && (target_processor == 3900
554 && op->membership & INSN_3900) == 0)
555 continue;
556
557 (*info->fprintf_func) (info->stream, "%s", op->name);
558
559 d = op->args;
560 if (d != NULL && *d != '\0')
561 {
562 /* start-sanitize-r5900 */
563 /* If this is an opcode completer, then do not emit
564 a tab after the opcode. */
565 if (*d != '&' && *d != ';')
566 /* end-sanitize-r5900 */
567 (*info->fprintf_func) (info->stream, "\t");
568 for (; *d != '\0'; d++)
569 /* start-sanitize-r5900 */
570 /* If this is an escape character, go ahead and print the
571 next character in the arg string verbatim. */
572 if (*d == '#')
573 {
574 d++;
575 (*info->fprintf_func) (info->stream, "%c", *d);
576 }
577 else
578 /* end-sanitize-r5900 */
579 print_insn_arg (d, word, memaddr, info);
580 }
581
582 return 4;
583 }
584 }
585 }
586
587 /* Handle undefined instructions. */
588 (*info->fprintf_func) (info->stream, "0x%x", word);
589 return 4;
590 }
591
592 int
593 print_insn_big_mips (memaddr, info)
594 bfd_vma memaddr;
595 struct disassemble_info *info;
596 {
597 bfd_byte buffer[4];
598 int status;
599
600 if (info->mach == 16
601 || (info->flavour == bfd_target_elf_flavour
602 && info->symbols != NULL
603 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
604 == STO_MIPS16)))
605 return print_insn_mips16 (memaddr, info);
606
607 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
608 if (status == 0)
609 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
610 info);
611 else
612 {
613 (*info->memory_error_func) (status, memaddr, info);
614 return -1;
615 }
616 }
617
618 int
619 print_insn_little_mips (memaddr, info)
620 bfd_vma memaddr;
621 struct disassemble_info *info;
622 {
623 bfd_byte buffer[4];
624 int status;
625
626 /* start-sanitize-sky */
627 #ifdef ARCH_dvp
628 {
629 /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
630 once. Since dvp_mach_type is a function, ensure it's only called
631 once. */
632 int mach = dvp_info_mach_type (info);
633
634 if (bfd_mach_dvp_p (info->mach)
635 || bfd_mach_dvp_p (mach))
636 return print_insn_dvp (memaddr, info);
637 }
638 #endif
639 /* end-sanitize-sky */
640
641 if (info->mach == 16
642 || (info->flavour == bfd_target_elf_flavour
643 && info->symbols != NULL
644 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
645 == STO_MIPS16)))
646 return print_insn_mips16 (memaddr, info);
647
648 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
649 if (status == 0)
650 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
651 info);
652 else
653 {
654 (*info->memory_error_func) (status, memaddr, info);
655 return -1;
656 }
657 }
658 \f
659 /* Disassemble mips16 instructions. */
660
661 static int
662 print_insn_mips16 (memaddr, info)
663 bfd_vma memaddr;
664 struct disassemble_info *info;
665 {
666 int status;
667 bfd_byte buffer[2];
668 int length;
669 int insn;
670 boolean use_extend;
671 int extend = 0;
672 const struct mips_opcode *op, *opend;
673
674 info->bytes_per_chunk = 2;
675 info->display_endian = info->endian;
676
677 info->insn_info_valid = 1;
678 info->branch_delay_insns = 0;
679 info->data_size = 0;
680 info->insn_type = dis_nonbranch;
681 info->target = 0;
682 info->target2 = 0;
683
684 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
685 if (status != 0)
686 {
687 (*info->memory_error_func) (status, memaddr, info);
688 return -1;
689 }
690
691 length = 2;
692
693 if (info->endian == BFD_ENDIAN_BIG)
694 insn = bfd_getb16 (buffer);
695 else
696 insn = bfd_getl16 (buffer);
697
698 /* Handle the extend opcode specially. */
699 use_extend = false;
700 if ((insn & 0xf800) == 0xf000)
701 {
702 use_extend = true;
703 extend = insn & 0x7ff;
704
705 memaddr += 2;
706
707 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
708 if (status != 0)
709 {
710 (*info->fprintf_func) (info->stream, "extend 0x%x",
711 (unsigned int) extend);
712 (*info->memory_error_func) (status, memaddr, info);
713 return -1;
714 }
715
716 if (info->endian == BFD_ENDIAN_BIG)
717 insn = bfd_getb16 (buffer);
718 else
719 insn = bfd_getl16 (buffer);
720
721 /* Check for an extend opcode followed by an extend opcode. */
722 if ((insn & 0xf800) == 0xf000)
723 {
724 (*info->fprintf_func) (info->stream, "extend 0x%x",
725 (unsigned int) extend);
726 info->insn_type = dis_noninsn;
727 return length;
728 }
729
730 length += 2;
731 }
732
733 /* FIXME: Should probably use a hash table on the major opcode here. */
734
735 opend = mips16_opcodes + bfd_mips16_num_opcodes;
736 for (op = mips16_opcodes; op < opend; op++)
737 {
738 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
739 {
740 const char *s;
741
742 if (strchr (op->args, 'a') != NULL)
743 {
744 if (use_extend)
745 {
746 (*info->fprintf_func) (info->stream, "extend 0x%x",
747 (unsigned int) extend);
748 info->insn_type = dis_noninsn;
749 return length - 2;
750 }
751
752 use_extend = false;
753
754 memaddr += 2;
755
756 status = (*info->read_memory_func) (memaddr, buffer, 2,
757 info);
758 if (status == 0)
759 {
760 use_extend = true;
761 if (info->endian == BFD_ENDIAN_BIG)
762 extend = bfd_getb16 (buffer);
763 else
764 extend = bfd_getl16 (buffer);
765 length += 2;
766 }
767 }
768
769 (*info->fprintf_func) (info->stream, "%s", op->name);
770 if (op->args[0] != '\0')
771 (*info->fprintf_func) (info->stream, "\t");
772
773 for (s = op->args; *s != '\0'; s++)
774 {
775 if (*s == ','
776 && s[1] == 'w'
777 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
778 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
779 {
780 /* Skip the register and the comma. */
781 ++s;
782 continue;
783 }
784 if (*s == ','
785 && s[1] == 'v'
786 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
787 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
788 {
789 /* Skip the register and the comma. */
790 ++s;
791 continue;
792 }
793 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
794 info);
795 }
796
797 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
798 {
799 info->branch_delay_insns = 1;
800 if (info->insn_type != dis_jsr)
801 info->insn_type = dis_branch;
802 }
803
804 return length;
805 }
806 }
807
808 if (use_extend)
809 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
810 (*info->fprintf_func) (info->stream, "0x%x", insn);
811 info->insn_type = dis_noninsn;
812
813 return length;
814 }
815
816 /* Disassemble an operand for a mips16 instruction. */
817
818 static void
819 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
820 int type;
821 const struct mips_opcode *op;
822 int l;
823 boolean use_extend;
824 int extend;
825 bfd_vma memaddr;
826 struct disassemble_info *info;
827 {
828 switch (type)
829 {
830 case ',':
831 case '(':
832 case ')':
833 (*info->fprintf_func) (info->stream, "%c", type);
834 break;
835
836 case 'y':
837 case 'w':
838 (*info->fprintf_func) (info->stream, "$%s",
839 mips16_reg_names[((l >> MIPS16OP_SH_RY)
840 & MIPS16OP_MASK_RY)]);
841 break;
842
843 case 'x':
844 case 'v':
845 (*info->fprintf_func) (info->stream, "$%s",
846 mips16_reg_names[((l >> MIPS16OP_SH_RX)
847 & MIPS16OP_MASK_RX)]);
848 break;
849
850 case 'z':
851 (*info->fprintf_func) (info->stream, "$%s",
852 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
853 & MIPS16OP_MASK_RZ)]);
854 break;
855
856 case 'Z':
857 (*info->fprintf_func) (info->stream, "$%s",
858 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
859 & MIPS16OP_MASK_MOVE32Z)]);
860 break;
861
862 case '0':
863 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
864 break;
865
866 case 'S':
867 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
868 break;
869
870 case 'P':
871 (*info->fprintf_func) (info->stream, "$pc");
872 break;
873
874 case 'R':
875 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
876 break;
877
878 case 'X':
879 (*info->fprintf_func) (info->stream, "$%s",
880 reg_names[((l >> MIPS16OP_SH_REGR32)
881 & MIPS16OP_MASK_REGR32)]);
882 break;
883
884 case 'Y':
885 (*info->fprintf_func) (info->stream, "$%s",
886 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
887 break;
888
889 case '<':
890 case '>':
891 case '[':
892 case ']':
893 case '4':
894 case '5':
895 case 'H':
896 case 'W':
897 case 'D':
898 case 'j':
899 case '6':
900 case '8':
901 case 'V':
902 case 'C':
903 case 'U':
904 case 'k':
905 case 'K':
906 case 'p':
907 case 'q':
908 case 'A':
909 case 'B':
910 case 'E':
911 {
912 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
913
914 shift = 0;
915 signedp = 0;
916 extbits = 16;
917 pcrel = 0;
918 extu = 0;
919 branch = 0;
920 switch (type)
921 {
922 case '<':
923 nbits = 3;
924 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
925 extbits = 5;
926 extu = 1;
927 break;
928 case '>':
929 nbits = 3;
930 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
931 extbits = 5;
932 extu = 1;
933 break;
934 case '[':
935 nbits = 3;
936 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
937 extbits = 6;
938 extu = 1;
939 break;
940 case ']':
941 nbits = 3;
942 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
943 extbits = 6;
944 extu = 1;
945 break;
946 case '4':
947 nbits = 4;
948 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
949 signedp = 1;
950 extbits = 15;
951 break;
952 case '5':
953 nbits = 5;
954 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
955 info->insn_type = dis_dref;
956 info->data_size = 1;
957 break;
958 case 'H':
959 nbits = 5;
960 shift = 1;
961 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
962 info->insn_type = dis_dref;
963 info->data_size = 2;
964 break;
965 case 'W':
966 nbits = 5;
967 shift = 2;
968 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
969 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
970 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
971 {
972 info->insn_type = dis_dref;
973 info->data_size = 4;
974 }
975 break;
976 case 'D':
977 nbits = 5;
978 shift = 3;
979 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
980 info->insn_type = dis_dref;
981 info->data_size = 8;
982 break;
983 case 'j':
984 nbits = 5;
985 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
986 signedp = 1;
987 break;
988 case '6':
989 nbits = 6;
990 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
991 break;
992 case '8':
993 nbits = 8;
994 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
995 break;
996 case 'V':
997 nbits = 8;
998 shift = 2;
999 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1000 /* FIXME: This might be lw, or it might be addiu to $sp or
1001 $pc. We assume it's load. */
1002 info->insn_type = dis_dref;
1003 info->data_size = 4;
1004 break;
1005 case 'C':
1006 nbits = 8;
1007 shift = 3;
1008 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1009 info->insn_type = dis_dref;
1010 info->data_size = 8;
1011 break;
1012 case 'U':
1013 nbits = 8;
1014 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1015 extu = 1;
1016 break;
1017 case 'k':
1018 nbits = 8;
1019 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1020 signedp = 1;
1021 break;
1022 case 'K':
1023 nbits = 8;
1024 shift = 3;
1025 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1026 signedp = 1;
1027 break;
1028 case 'p':
1029 nbits = 8;
1030 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1031 signedp = 1;
1032 pcrel = 1;
1033 branch = 1;
1034 info->insn_type = dis_condbranch;
1035 break;
1036 case 'q':
1037 nbits = 11;
1038 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1039 signedp = 1;
1040 pcrel = 1;
1041 branch = 1;
1042 info->insn_type = dis_branch;
1043 break;
1044 case 'A':
1045 nbits = 8;
1046 shift = 2;
1047 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1048 pcrel = 1;
1049 /* FIXME: This can be lw or la. We assume it is lw. */
1050 info->insn_type = dis_dref;
1051 info->data_size = 4;
1052 break;
1053 case 'B':
1054 nbits = 5;
1055 shift = 3;
1056 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1057 pcrel = 1;
1058 info->insn_type = dis_dref;
1059 info->data_size = 8;
1060 break;
1061 case 'E':
1062 nbits = 5;
1063 shift = 2;
1064 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1065 pcrel = 1;
1066 break;
1067 default:
1068 abort ();
1069 }
1070
1071 if (! use_extend)
1072 {
1073 if (signedp && immed >= (1 << (nbits - 1)))
1074 immed -= 1 << nbits;
1075 immed <<= shift;
1076 if ((type == '<' || type == '>' || type == '[' || type == '[')
1077 && immed == 0)
1078 immed = 8;
1079 }
1080 else
1081 {
1082 if (extbits == 16)
1083 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1084 else if (extbits == 15)
1085 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1086 else
1087 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1088 immed &= (1 << extbits) - 1;
1089 if (! extu && immed >= (1 << (extbits - 1)))
1090 immed -= 1 << extbits;
1091 }
1092
1093 if (! pcrel)
1094 (*info->fprintf_func) (info->stream, "%d", immed);
1095 else
1096 {
1097 bfd_vma baseaddr;
1098 bfd_vma val;
1099
1100 if (branch)
1101 {
1102 immed *= 2;
1103 baseaddr = memaddr + 2;
1104 }
1105 else if (use_extend)
1106 baseaddr = memaddr - 2;
1107 else
1108 {
1109 int status;
1110 bfd_byte buffer[2];
1111
1112 baseaddr = memaddr;
1113
1114 /* If this instruction is in the delay slot of a jr
1115 instruction, the base address is the address of the
1116 jr instruction. If it is in the delay slot of jalr
1117 instruction, the base address is the address of the
1118 jalr instruction. This test is unreliable: we have
1119 no way of knowing whether the previous word is
1120 instruction or data. */
1121 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1122 info);
1123 if (status == 0
1124 && (((info->endian == BFD_ENDIAN_BIG
1125 ? bfd_getb16 (buffer)
1126 : bfd_getl16 (buffer))
1127 & 0xf800) == 0x1800))
1128 baseaddr = memaddr - 4;
1129 else
1130 {
1131 status = (*info->read_memory_func) (memaddr - 2, buffer,
1132 2, info);
1133 if (status == 0
1134 && (((info->endian == BFD_ENDIAN_BIG
1135 ? bfd_getb16 (buffer)
1136 : bfd_getl16 (buffer))
1137 & 0xf81f) == 0xe800))
1138 baseaddr = memaddr - 2;
1139 }
1140 }
1141 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1142 (*info->print_address_func) (val, info);
1143 info->target = val;
1144 }
1145 }
1146 break;
1147
1148 case 'a':
1149 if (! use_extend)
1150 extend = 0;
1151 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1152 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1153 info->insn_type = dis_jsr;
1154 info->target = (memaddr & 0xf0000000) | l;
1155 info->branch_delay_insns = 1;
1156 break;
1157
1158 case 'l':
1159 case 'L':
1160 {
1161 int need_comma, amask, smask;
1162
1163 need_comma = 0;
1164
1165 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1166
1167 amask = (l >> 3) & 7;
1168
1169 if (amask > 0 && amask < 5)
1170 {
1171 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1172 if (amask > 1)
1173 (*info->fprintf_func) (info->stream, "-$%s",
1174 reg_names[amask + 3]);
1175 need_comma = 1;
1176 }
1177
1178 smask = (l >> 1) & 3;
1179 if (smask == 3)
1180 {
1181 (*info->fprintf_func) (info->stream, "%s??",
1182 need_comma ? "," : "");
1183 need_comma = 1;
1184 }
1185 else if (smask > 0)
1186 {
1187 (*info->fprintf_func) (info->stream, "%s$%s",
1188 need_comma ? "," : "",
1189 reg_names[16]);
1190 if (smask > 1)
1191 (*info->fprintf_func) (info->stream, "-$%s",
1192 reg_names[smask + 15]);
1193 need_comma = 1;
1194 }
1195
1196 if (l & 1)
1197 {
1198 (*info->fprintf_func) (info->stream, "%s$%s",
1199 need_comma ? "," : "",
1200 reg_names[31]);
1201 need_comma = 1;
1202 }
1203
1204 if (amask == 5 || amask == 6)
1205 {
1206 (*info->fprintf_func) (info->stream, "%s$f0",
1207 need_comma ? "," : "");
1208 if (amask == 6)
1209 (*info->fprintf_func) (info->stream, "-$f1");
1210 }
1211 }
1212 break;
1213
1214 default:
1215 abort ();
1216 }
1217 }
This page took 0.105957 seconds and 4 git commands to generate.