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 (*info->fprintf_func) (info->stream, "%c", *d);
91 break;
92
93 case 's':
94 case 'b':
95 case 'r':
96 case 'v':
97 (*info->fprintf_func) (info->stream, "$%s",
98 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
99 break;
100
101 case 't':
102 case 'w':
103 (*info->fprintf_func) (info->stream, "$%s",
104 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
105 break;
106
107 case 'i':
108 case 'u':
109 (*info->fprintf_func) (info->stream, "0x%x",
110 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
111 break;
112
113 case 'j': /* same as i, but sign-extended */
114 case 'o':
115 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
116 if (delta & 0x8000)
117 delta |= ~0xffff;
118 (*info->fprintf_func) (info->stream, "%d",
119 delta);
120 break;
121
122 case 'h':
123 (*info->fprintf_func) (info->stream, "0x%x",
124 (unsigned int) ((l >> OP_SH_PREFX)
125 & OP_MASK_PREFX));
126 break;
127
128 case 'k':
129 (*info->fprintf_func) (info->stream, "0x%x",
130 (unsigned int) ((l >> OP_SH_CACHE)
131 & OP_MASK_CACHE));
132 break;
133
134 case 'a':
135 (*info->print_address_func)
136 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
137 info);
138 break;
139
140 case 'p':
141 /* sign extend the displacement */
142 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
143 if (delta & 0x8000)
144 delta |= ~0xffff;
145 (*info->print_address_func)
146 ((delta << 2) + pc + 4,
147 info);
148 break;
149
150 case 'd':
151 (*info->fprintf_func) (info->stream, "$%s",
152 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
153 break;
154
155 case 'z':
156 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
157 break;
158
159 case '<':
160 (*info->fprintf_func) (info->stream, "0x%x",
161 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
162 break;
163
164 case 'c':
165 (*info->fprintf_func) (info->stream, "0x%x",
166 (l >> OP_SH_CODE) & OP_MASK_CODE);
167 break;
168
169
170 case 'q':
171 (*info->fprintf_func) (info->stream, "0x%x",
172 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
173 break;
174
175 case 'C':
176 (*info->fprintf_func) (info->stream, "0x%x",
177 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
178 break;
179
180 case 'B':
181 (*info->fprintf_func) (info->stream, "0x%x",
182 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
183 break;
184
185 case 'S':
186 case 'V':
187 (*info->fprintf_func) (info->stream, "$f%d",
188 (l >> OP_SH_FS) & OP_MASK_FS);
189 break;
190
191
192 case 'T':
193 case 'W':
194 (*info->fprintf_func) (info->stream, "$f%d",
195 (l >> OP_SH_FT) & OP_MASK_FT);
196 break;
197
198 case 'D':
199 (*info->fprintf_func) (info->stream, "$f%d",
200 (l >> OP_SH_FD) & OP_MASK_FD);
201 break;
202
203 case 'R':
204 (*info->fprintf_func) (info->stream, "$f%d",
205 (l >> OP_SH_FR) & OP_MASK_FR);
206 break;
207
208 case 'E':
209 (*info->fprintf_func) (info->stream, "$%d",
210 (l >> OP_SH_RT) & OP_MASK_RT);
211 break;
212
213 case 'G':
214 (*info->fprintf_func) (info->stream, "$%d",
215 (l >> OP_SH_RD) & OP_MASK_RD);
216 break;
217
218 case 'N':
219 (*info->fprintf_func) (info->stream, "$fcc%d",
220 (l >> OP_SH_BCC) & OP_MASK_BCC);
221 break;
222
223 case 'M':
224 (*info->fprintf_func) (info->stream, "$fcc%d",
225 (l >> OP_SH_CCC) & OP_MASK_CCC);
226 break;
227
228 case 'P':
229 (*info->fprintf_func) (info->stream, "%d",
230 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
231 break;
232
233
234 default:
235 /* xgettext:c-format */
236 (*info->fprintf_func) (info->stream,
237 _("# internal error, undefined modifier(%c)"),
238 *d);
239 break;
240 }
241 }
242 \f
243 #if SYMTAB_AVAILABLE
244
245 /* Figure out the MIPS ISA and CPU based on the machine number.
246 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
247
248 static void
249 set_mips_isa_type (mach, isa, cputype)
250 int mach;
251 int *isa;
252 int *cputype;
253 {
254 int target_processor = 0;
255 int mips_isa = 0;
256
257 switch (mach)
258 {
259 case bfd_mach_mips3000:
260 target_processor = 3000;
261 mips_isa = 1;
262 break;
263 case bfd_mach_mips3900:
264 target_processor = 3900;
265 mips_isa = 1;
266 break;
267 case bfd_mach_mips4000:
268 target_processor = 4000;
269 mips_isa = 3;
270 break;
271 case bfd_mach_mips4010:
272 target_processor = 4010;
273 mips_isa = 2;
274 break;
275 case bfd_mach_mips4100:
276 target_processor = 4100;
277 mips_isa = 3;
278 break;
279 case bfd_mach_mips4111:
280 target_processor = 4100;
281 mips_isa = 3;
282 break;
283 case bfd_mach_mips4300:
284 target_processor = 4300;
285 mips_isa = 3;
286 break;
287 case bfd_mach_mips4400:
288 target_processor = 4400;
289 mips_isa = 3;
290 break;
291 case bfd_mach_mips4600:
292 target_processor = 4600;
293 mips_isa = 3;
294 break;
295 case bfd_mach_mips4650:
296 target_processor = 4650;
297 mips_isa = 3;
298 break;
299 case bfd_mach_mips5000:
300 target_processor = 5000;
301 mips_isa = 4;
302 break;
303 case bfd_mach_mips6000:
304 target_processor = 6000;
305 mips_isa = 2;
306 break;
307 case bfd_mach_mips8000:
308 target_processor = 8000;
309 mips_isa = 4;
310 break;
311 case bfd_mach_mips10000:
312 target_processor = 10000;
313 mips_isa = 4;
314 break;
315 case bfd_mach_mips16:
316 target_processor = 16;
317 mips_isa = 3;
318 break;
319 default:
320 target_processor = 3000;
321 mips_isa = 3;
322 break;
323
324 }
325
326 *isa = mips_isa;
327 *cputype = target_processor;
328 }
329
330 #endif /* SYMTAB_AVAILABLE */
331
332 /* Print the mips instruction at address MEMADDR in debugged memory,
333 on using INFO. Returns length of the instruction, in bytes, which is
334 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
335 this is little-endian code. */
336
337 static int
338 _print_insn_mips (memaddr, word, info)
339 bfd_vma memaddr;
340 unsigned long int word;
341 struct disassemble_info *info;
342 {
343 register const struct mips_opcode *op;
344 int target_processor, mips_isa;
345 static boolean init = 0;
346 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
347
348 /* Build a hash table to shorten the search time. */
349 if (! init)
350 {
351 unsigned int i;
352
353 for (i = 0; i <= OP_MASK_OP; i++)
354 {
355 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
356 {
357 if (op->pinfo == INSN_MACRO)
358 continue;
359 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
360 {
361 mips_hash[i] = op;
362 break;
363 }
364 }
365 }
366
367 init = 1;
368 }
369
370 #if ! SYMTAB_AVAILABLE
371 /* This is running out on a target machine, not in a host tool.
372 FIXME: Where does mips_target_info come from? */
373 target_processor = mips_target_info.processor;
374 mips_isa = mips_target_info.isa;
375 #else
376 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
377 #endif
378
379 info->bytes_per_chunk = 4;
380 info->display_endian = info->endian;
381
382 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
383 if (op != NULL)
384 {
385 for (; op < &mips_opcodes[NUMOPCODES]; op++)
386 {
387 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
388 {
389 register const char *d;
390
391 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
392 continue;
393
394 (*info->fprintf_func) (info->stream, "%s", op->name);
395
396 d = op->args;
397 if (d != NULL && *d != '\0')
398 {
399 (*info->fprintf_func) (info->stream, "\t");
400 for (; *d != '\0'; d++)
401 print_insn_arg (d, word, memaddr, info);
402 }
403
404 return 4;
405 }
406 }
407 }
408
409 /* Handle undefined instructions. */
410 (*info->fprintf_func) (info->stream, "0x%x", word);
411 return 4;
412 }
413
414
415 /* In an environment where we do not know the symbol type of the
416 instruction we are forced to assume that the low order bit of the
417 instructions' address may mark it as a mips16 instruction. If we
418 are single stepping, or the pc is within the disassembled function,
419 this works. Otherwise, we need a clue. Sometimes. */
420
421 int
422 print_insn_big_mips (memaddr, info)
423 bfd_vma memaddr;
424 struct disassemble_info *info;
425 {
426 bfd_byte buffer[4];
427 int status;
428
429 #if 1
430 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
431 /* Only a few tools will work this way. */
432 if (memaddr & 0x01)
433 return print_insn_mips16 (memaddr, info);
434 #endif
435
436 #if SYMTAB_AVAILABLE
437 if (info->mach == 16
438 || (info->flavour == bfd_target_elf_flavour
439 && info->symbols != NULL
440 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
441 == STO_MIPS16)))
442 return print_insn_mips16 (memaddr, info);
443 #endif
444
445 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
446 if (status == 0)
447 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
448 info);
449 else
450 {
451 (*info->memory_error_func) (status, memaddr, info);
452 return -1;
453 }
454 }
455
456 int
457 print_insn_little_mips (memaddr, info)
458 bfd_vma memaddr;
459 struct disassemble_info *info;
460 {
461 bfd_byte buffer[4];
462 int status;
463
464
465 #if 1
466 if (memaddr & 0x01)
467 return print_insn_mips16 (memaddr, info);
468 #endif
469
470 #if SYMTAB_AVAILABLE
471 if (info->mach == 16
472 || (info->flavour == bfd_target_elf_flavour
473 && info->symbols != NULL
474 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
475 == STO_MIPS16)))
476 return print_insn_mips16 (memaddr, info);
477 #endif
478
479 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
480 if (status == 0)
481 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
482 info);
483 else
484 {
485 (*info->memory_error_func) (status, memaddr, info);
486 return -1;
487 }
488 }
489 \f
490 /* Disassemble mips16 instructions. */
491
492 static int
493 print_insn_mips16 (memaddr, info)
494 bfd_vma memaddr;
495 struct disassemble_info *info;
496 {
497 int status;
498 bfd_byte buffer[2];
499 int length;
500 int insn;
501 boolean use_extend;
502 int extend = 0;
503 const struct mips_opcode *op, *opend;
504
505 info->bytes_per_chunk = 2;
506 info->display_endian = info->endian;
507
508 info->insn_info_valid = 1;
509 info->branch_delay_insns = 0;
510 info->data_size = 0;
511 info->insn_type = dis_nonbranch;
512 info->target = 0;
513 info->target2 = 0;
514
515 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
516 if (status != 0)
517 {
518 (*info->memory_error_func) (status, memaddr, info);
519 return -1;
520 }
521
522 length = 2;
523
524 if (info->endian == BFD_ENDIAN_BIG)
525 insn = bfd_getb16 (buffer);
526 else
527 insn = bfd_getl16 (buffer);
528
529 /* Handle the extend opcode specially. */
530 use_extend = false;
531 if ((insn & 0xf800) == 0xf000)
532 {
533 use_extend = true;
534 extend = insn & 0x7ff;
535
536 memaddr += 2;
537
538 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
539 if (status != 0)
540 {
541 (*info->fprintf_func) (info->stream, "extend 0x%x",
542 (unsigned int) extend);
543 (*info->memory_error_func) (status, memaddr, info);
544 return -1;
545 }
546
547 if (info->endian == BFD_ENDIAN_BIG)
548 insn = bfd_getb16 (buffer);
549 else
550 insn = bfd_getl16 (buffer);
551
552 /* Check for an extend opcode followed by an extend opcode. */
553 if ((insn & 0xf800) == 0xf000)
554 {
555 (*info->fprintf_func) (info->stream, "extend 0x%x",
556 (unsigned int) extend);
557 info->insn_type = dis_noninsn;
558 return length;
559 }
560
561 length += 2;
562 }
563
564 /* FIXME: Should probably use a hash table on the major opcode here. */
565
566 opend = mips16_opcodes + bfd_mips16_num_opcodes;
567 for (op = mips16_opcodes; op < opend; op++)
568 {
569 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
570 {
571 const char *s;
572
573 if (strchr (op->args, 'a') != NULL)
574 {
575 if (use_extend)
576 {
577 (*info->fprintf_func) (info->stream, "extend 0x%x",
578 (unsigned int) extend);
579 info->insn_type = dis_noninsn;
580 return length - 2;
581 }
582
583 use_extend = false;
584
585 memaddr += 2;
586
587 status = (*info->read_memory_func) (memaddr, buffer, 2,
588 info);
589 if (status == 0)
590 {
591 use_extend = true;
592 if (info->endian == BFD_ENDIAN_BIG)
593 extend = bfd_getb16 (buffer);
594 else
595 extend = bfd_getl16 (buffer);
596 length += 2;
597 }
598 }
599
600 (*info->fprintf_func) (info->stream, "%s", op->name);
601 if (op->args[0] != '\0')
602 (*info->fprintf_func) (info->stream, "\t");
603
604 for (s = op->args; *s != '\0'; s++)
605 {
606 if (*s == ','
607 && s[1] == 'w'
608 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
609 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
610 {
611 /* Skip the register and the comma. */
612 ++s;
613 continue;
614 }
615 if (*s == ','
616 && s[1] == 'v'
617 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
618 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
619 {
620 /* Skip the register and the comma. */
621 ++s;
622 continue;
623 }
624 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
625 info);
626 }
627
628 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
629 {
630 info->branch_delay_insns = 1;
631 if (info->insn_type != dis_jsr)
632 info->insn_type = dis_branch;
633 }
634
635 return length;
636 }
637 }
638
639 if (use_extend)
640 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
641 (*info->fprintf_func) (info->stream, "0x%x", insn);
642 info->insn_type = dis_noninsn;
643
644 return length;
645 }
646
647 /* Disassemble an operand for a mips16 instruction. */
648
649 static void
650 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
651 int type;
652 const struct mips_opcode *op;
653 int l;
654 boolean use_extend;
655 int extend;
656 bfd_vma memaddr;
657 struct disassemble_info *info;
658 {
659 switch (type)
660 {
661 case ',':
662 case '(':
663 case ')':
664 (*info->fprintf_func) (info->stream, "%c", type);
665 break;
666
667 case 'y':
668 case 'w':
669 (*info->fprintf_func) (info->stream, "$%s",
670 mips16_reg_names[((l >> MIPS16OP_SH_RY)
671 & MIPS16OP_MASK_RY)]);
672 break;
673
674 case 'x':
675 case 'v':
676 (*info->fprintf_func) (info->stream, "$%s",
677 mips16_reg_names[((l >> MIPS16OP_SH_RX)
678 & MIPS16OP_MASK_RX)]);
679 break;
680
681 case 'z':
682 (*info->fprintf_func) (info->stream, "$%s",
683 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
684 & MIPS16OP_MASK_RZ)]);
685 break;
686
687 case 'Z':
688 (*info->fprintf_func) (info->stream, "$%s",
689 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
690 & MIPS16OP_MASK_MOVE32Z)]);
691 break;
692
693 case '0':
694 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
695 break;
696
697 case 'S':
698 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
699 break;
700
701 case 'P':
702 (*info->fprintf_func) (info->stream, "$pc");
703 break;
704
705 case 'R':
706 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
707 break;
708
709 case 'X':
710 (*info->fprintf_func) (info->stream, "$%s",
711 reg_names[((l >> MIPS16OP_SH_REGR32)
712 & MIPS16OP_MASK_REGR32)]);
713 break;
714
715 case 'Y':
716 (*info->fprintf_func) (info->stream, "$%s",
717 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
718 break;
719
720 case '<':
721 case '>':
722 case '[':
723 case ']':
724 case '4':
725 case '5':
726 case 'H':
727 case 'W':
728 case 'D':
729 case 'j':
730 case '6':
731 case '8':
732 case 'V':
733 case 'C':
734 case 'U':
735 case 'k':
736 case 'K':
737 case 'p':
738 case 'q':
739 case 'A':
740 case 'B':
741 case 'E':
742 {
743 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
744
745 shift = 0;
746 signedp = 0;
747 extbits = 16;
748 pcrel = 0;
749 extu = 0;
750 branch = 0;
751 switch (type)
752 {
753 case '<':
754 nbits = 3;
755 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
756 extbits = 5;
757 extu = 1;
758 break;
759 case '>':
760 nbits = 3;
761 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
762 extbits = 5;
763 extu = 1;
764 break;
765 case '[':
766 nbits = 3;
767 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
768 extbits = 6;
769 extu = 1;
770 break;
771 case ']':
772 nbits = 3;
773 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
774 extbits = 6;
775 extu = 1;
776 break;
777 case '4':
778 nbits = 4;
779 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
780 signedp = 1;
781 extbits = 15;
782 break;
783 case '5':
784 nbits = 5;
785 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
786 info->insn_type = dis_dref;
787 info->data_size = 1;
788 break;
789 case 'H':
790 nbits = 5;
791 shift = 1;
792 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
793 info->insn_type = dis_dref;
794 info->data_size = 2;
795 break;
796 case 'W':
797 nbits = 5;
798 shift = 2;
799 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
800 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
801 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
802 {
803 info->insn_type = dis_dref;
804 info->data_size = 4;
805 }
806 break;
807 case 'D':
808 nbits = 5;
809 shift = 3;
810 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
811 info->insn_type = dis_dref;
812 info->data_size = 8;
813 break;
814 case 'j':
815 nbits = 5;
816 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
817 signedp = 1;
818 break;
819 case '6':
820 nbits = 6;
821 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
822 break;
823 case '8':
824 nbits = 8;
825 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
826 break;
827 case 'V':
828 nbits = 8;
829 shift = 2;
830 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
831 /* FIXME: This might be lw, or it might be addiu to $sp or
832 $pc. We assume it's load. */
833 info->insn_type = dis_dref;
834 info->data_size = 4;
835 break;
836 case 'C':
837 nbits = 8;
838 shift = 3;
839 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
840 info->insn_type = dis_dref;
841 info->data_size = 8;
842 break;
843 case 'U':
844 nbits = 8;
845 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
846 extu = 1;
847 break;
848 case 'k':
849 nbits = 8;
850 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
851 signedp = 1;
852 break;
853 case 'K':
854 nbits = 8;
855 shift = 3;
856 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
857 signedp = 1;
858 break;
859 case 'p':
860 nbits = 8;
861 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
862 signedp = 1;
863 pcrel = 1;
864 branch = 1;
865 info->insn_type = dis_condbranch;
866 break;
867 case 'q':
868 nbits = 11;
869 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
870 signedp = 1;
871 pcrel = 1;
872 branch = 1;
873 info->insn_type = dis_branch;
874 break;
875 case 'A':
876 nbits = 8;
877 shift = 2;
878 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
879 pcrel = 1;
880 /* FIXME: This can be lw or la. We assume it is lw. */
881 info->insn_type = dis_dref;
882 info->data_size = 4;
883 break;
884 case 'B':
885 nbits = 5;
886 shift = 3;
887 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
888 pcrel = 1;
889 info->insn_type = dis_dref;
890 info->data_size = 8;
891 break;
892 case 'E':
893 nbits = 5;
894 shift = 2;
895 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
896 pcrel = 1;
897 break;
898 default:
899 abort ();
900 }
901
902 if (! use_extend)
903 {
904 if (signedp && immed >= (1 << (nbits - 1)))
905 immed -= 1 << nbits;
906 immed <<= shift;
907 if ((type == '<' || type == '>' || type == '[' || type == ']')
908 && immed == 0)
909 immed = 8;
910 }
911 else
912 {
913 if (extbits == 16)
914 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
915 else if (extbits == 15)
916 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
917 else
918 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
919 immed &= (1 << extbits) - 1;
920 if (! extu && immed >= (1 << (extbits - 1)))
921 immed -= 1 << extbits;
922 }
923
924 if (! pcrel)
925 (*info->fprintf_func) (info->stream, "%d", immed);
926 else
927 {
928 bfd_vma baseaddr;
929 bfd_vma val;
930
931 if (branch)
932 {
933 immed *= 2;
934 baseaddr = memaddr + 2;
935 }
936 else if (use_extend)
937 baseaddr = memaddr - 2;
938 else
939 {
940 int status;
941 bfd_byte buffer[2];
942
943 baseaddr = memaddr;
944
945 /* If this instruction is in the delay slot of a jr
946 instruction, the base address is the address of the
947 jr instruction. If it is in the delay slot of jalr
948 instruction, the base address is the address of the
949 jalr instruction. This test is unreliable: we have
950 no way of knowing whether the previous word is
951 instruction or data. */
952 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
953 info);
954 if (status == 0
955 && (((info->endian == BFD_ENDIAN_BIG
956 ? bfd_getb16 (buffer)
957 : bfd_getl16 (buffer))
958 & 0xf800) == 0x1800))
959 baseaddr = memaddr - 4;
960 else
961 {
962 status = (*info->read_memory_func) (memaddr - 2, buffer,
963 2, info);
964 if (status == 0
965 && (((info->endian == BFD_ENDIAN_BIG
966 ? bfd_getb16 (buffer)
967 : bfd_getl16 (buffer))
968 & 0xf81f) == 0xe800))
969 baseaddr = memaddr - 2;
970 }
971 }
972 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
973 (*info->print_address_func) (val, info);
974 info->target = val;
975 }
976 }
977 break;
978
979 case 'a':
980 if (! use_extend)
981 extend = 0;
982 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
983 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
984 info->insn_type = dis_jsr;
985 info->target = (memaddr & 0xf0000000) | l;
986 info->branch_delay_insns = 1;
987 break;
988
989 case 'l':
990 case 'L':
991 {
992 int need_comma, amask, smask;
993
994 need_comma = 0;
995
996 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
997
998 amask = (l >> 3) & 7;
999
1000 if (amask > 0 && amask < 5)
1001 {
1002 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1003 if (amask > 1)
1004 (*info->fprintf_func) (info->stream, "-$%s",
1005 reg_names[amask + 3]);
1006 need_comma = 1;
1007 }
1008
1009 smask = (l >> 1) & 3;
1010 if (smask == 3)
1011 {
1012 (*info->fprintf_func) (info->stream, "%s??",
1013 need_comma ? "," : "");
1014 need_comma = 1;
1015 }
1016 else if (smask > 0)
1017 {
1018 (*info->fprintf_func) (info->stream, "%s$%s",
1019 need_comma ? "," : "",
1020 reg_names[16]);
1021 if (smask > 1)
1022 (*info->fprintf_func) (info->stream, "-$%s",
1023 reg_names[smask + 15]);
1024 need_comma = 1;
1025 }
1026
1027 if (l & 1)
1028 {
1029 (*info->fprintf_func) (info->stream, "%s$%s",
1030 need_comma ? "," : "",
1031 reg_names[31]);
1032 need_comma = 1;
1033 }
1034
1035 if (amask == 5 || amask == 6)
1036 {
1037 (*info->fprintf_func) (info->stream, "%s$f0",
1038 need_comma ? "," : "");
1039 if (amask == 6)
1040 (*info->fprintf_func) (info->stream, "-$f1");
1041 }
1042 }
1043 break;
1044
1045 default:
1046 abort ();
1047 }
1048 }
This page took 0.054217 seconds and 4 git commands to generate.