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