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 int insn_isa;
391
392 if ((op->membership & INSN_ISA) == INSN_ISA1)
393 insn_isa = 1;
394 else if ((op->membership & INSN_ISA) == INSN_ISA2)
395 insn_isa = 2;
396 else if ((op->membership & INSN_ISA) == INSN_ISA3)
397 insn_isa = 3;
398 else if ((op->membership & INSN_ISA) == INSN_ISA4)
399 insn_isa = 4;
400 else
401 insn_isa = 15;
402
403 if (insn_isa > mips_isa
404 && (target_processor == 4650
405 && op->membership & INSN_4650) == 0
406 && (target_processor == 4010
407 && op->membership & INSN_4010) == 0
408 && (target_processor == 4100
409 && op->membership & INSN_4100) == 0
410 && (target_processor == 3900
411 && op->membership & INSN_3900) == 0)
412 continue;
413
414 (*info->fprintf_func) (info->stream, "%s", op->name);
415
416 d = op->args;
417 if (d != NULL && *d != '\0')
418 {
419 (*info->fprintf_func) (info->stream, "\t");
420 for (; *d != '\0'; d++)
421 print_insn_arg (d, word, memaddr, info);
422 }
423
424 return 4;
425 }
426 }
427 }
428
429 /* Handle undefined instructions. */
430 (*info->fprintf_func) (info->stream, "0x%x", word);
431 return 4;
432 }
433
434
435 /* In an environment where we do not know the symbol type of the
436 instruction we are forced to assume that the low order bit of the
437 instructions' address may mark it as a mips16 instruction. If we
438 are single stepping, or the pc is within the disassembled function,
439 this works. Otherwise, we need a clue. Sometimes. */
440
441 int
442 print_insn_big_mips (memaddr, info)
443 bfd_vma memaddr;
444 struct disassemble_info *info;
445 {
446 bfd_byte buffer[4];
447 int status;
448
449 #if 1
450 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
451 /* Only a few tools will work this way. */
452 if (memaddr & 0x01)
453 return print_insn_mips16 (memaddr, info);
454 #endif
455
456 #if SYMTAB_AVAILABLE
457 if (info->mach == 16
458 || (info->flavour == bfd_target_elf_flavour
459 && info->symbols != NULL
460 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
461 == STO_MIPS16)))
462 return print_insn_mips16 (memaddr, info);
463 #endif
464
465 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
466 if (status == 0)
467 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
468 info);
469 else
470 {
471 (*info->memory_error_func) (status, memaddr, info);
472 return -1;
473 }
474 }
475
476 int
477 print_insn_little_mips (memaddr, info)
478 bfd_vma memaddr;
479 struct disassemble_info *info;
480 {
481 bfd_byte buffer[4];
482 int status;
483
484
485 #if 1
486 if (memaddr & 0x01)
487 return print_insn_mips16 (memaddr, info);
488 #endif
489
490 #if SYMTAB_AVAILABLE
491 if (info->mach == 16
492 || (info->flavour == bfd_target_elf_flavour
493 && info->symbols != NULL
494 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
495 == STO_MIPS16)))
496 return print_insn_mips16 (memaddr, info);
497 #endif
498
499 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
500 if (status == 0)
501 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
502 info);
503 else
504 {
505 (*info->memory_error_func) (status, memaddr, info);
506 return -1;
507 }
508 }
509 \f
510 /* Disassemble mips16 instructions. */
511
512 static int
513 print_insn_mips16 (memaddr, info)
514 bfd_vma memaddr;
515 struct disassemble_info *info;
516 {
517 int status;
518 bfd_byte buffer[2];
519 int length;
520 int insn;
521 boolean use_extend;
522 int extend = 0;
523 const struct mips_opcode *op, *opend;
524
525 info->bytes_per_chunk = 2;
526 info->display_endian = info->endian;
527
528 info->insn_info_valid = 1;
529 info->branch_delay_insns = 0;
530 info->data_size = 0;
531 info->insn_type = dis_nonbranch;
532 info->target = 0;
533 info->target2 = 0;
534
535 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
536 if (status != 0)
537 {
538 (*info->memory_error_func) (status, memaddr, info);
539 return -1;
540 }
541
542 length = 2;
543
544 if (info->endian == BFD_ENDIAN_BIG)
545 insn = bfd_getb16 (buffer);
546 else
547 insn = bfd_getl16 (buffer);
548
549 /* Handle the extend opcode specially. */
550 use_extend = false;
551 if ((insn & 0xf800) == 0xf000)
552 {
553 use_extend = true;
554 extend = insn & 0x7ff;
555
556 memaddr += 2;
557
558 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
559 if (status != 0)
560 {
561 (*info->fprintf_func) (info->stream, "extend 0x%x",
562 (unsigned int) extend);
563 (*info->memory_error_func) (status, memaddr, info);
564 return -1;
565 }
566
567 if (info->endian == BFD_ENDIAN_BIG)
568 insn = bfd_getb16 (buffer);
569 else
570 insn = bfd_getl16 (buffer);
571
572 /* Check for an extend opcode followed by an extend opcode. */
573 if ((insn & 0xf800) == 0xf000)
574 {
575 (*info->fprintf_func) (info->stream, "extend 0x%x",
576 (unsigned int) extend);
577 info->insn_type = dis_noninsn;
578 return length;
579 }
580
581 length += 2;
582 }
583
584 /* FIXME: Should probably use a hash table on the major opcode here. */
585
586 opend = mips16_opcodes + bfd_mips16_num_opcodes;
587 for (op = mips16_opcodes; op < opend; op++)
588 {
589 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
590 {
591 const char *s;
592
593 if (strchr (op->args, 'a') != NULL)
594 {
595 if (use_extend)
596 {
597 (*info->fprintf_func) (info->stream, "extend 0x%x",
598 (unsigned int) extend);
599 info->insn_type = dis_noninsn;
600 return length - 2;
601 }
602
603 use_extend = false;
604
605 memaddr += 2;
606
607 status = (*info->read_memory_func) (memaddr, buffer, 2,
608 info);
609 if (status == 0)
610 {
611 use_extend = true;
612 if (info->endian == BFD_ENDIAN_BIG)
613 extend = bfd_getb16 (buffer);
614 else
615 extend = bfd_getl16 (buffer);
616 length += 2;
617 }
618 }
619
620 (*info->fprintf_func) (info->stream, "%s", op->name);
621 if (op->args[0] != '\0')
622 (*info->fprintf_func) (info->stream, "\t");
623
624 for (s = op->args; *s != '\0'; s++)
625 {
626 if (*s == ','
627 && s[1] == 'w'
628 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
629 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
630 {
631 /* Skip the register and the comma. */
632 ++s;
633 continue;
634 }
635 if (*s == ','
636 && s[1] == 'v'
637 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
638 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
639 {
640 /* Skip the register and the comma. */
641 ++s;
642 continue;
643 }
644 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
645 info);
646 }
647
648 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
649 {
650 info->branch_delay_insns = 1;
651 if (info->insn_type != dis_jsr)
652 info->insn_type = dis_branch;
653 }
654
655 return length;
656 }
657 }
658
659 if (use_extend)
660 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
661 (*info->fprintf_func) (info->stream, "0x%x", insn);
662 info->insn_type = dis_noninsn;
663
664 return length;
665 }
666
667 /* Disassemble an operand for a mips16 instruction. */
668
669 static void
670 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
671 int type;
672 const struct mips_opcode *op;
673 int l;
674 boolean use_extend;
675 int extend;
676 bfd_vma memaddr;
677 struct disassemble_info *info;
678 {
679 switch (type)
680 {
681 case ',':
682 case '(':
683 case ')':
684 (*info->fprintf_func) (info->stream, "%c", type);
685 break;
686
687 case 'y':
688 case 'w':
689 (*info->fprintf_func) (info->stream, "$%s",
690 mips16_reg_names[((l >> MIPS16OP_SH_RY)
691 & MIPS16OP_MASK_RY)]);
692 break;
693
694 case 'x':
695 case 'v':
696 (*info->fprintf_func) (info->stream, "$%s",
697 mips16_reg_names[((l >> MIPS16OP_SH_RX)
698 & MIPS16OP_MASK_RX)]);
699 break;
700
701 case 'z':
702 (*info->fprintf_func) (info->stream, "$%s",
703 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
704 & MIPS16OP_MASK_RZ)]);
705 break;
706
707 case 'Z':
708 (*info->fprintf_func) (info->stream, "$%s",
709 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
710 & MIPS16OP_MASK_MOVE32Z)]);
711 break;
712
713 case '0':
714 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
715 break;
716
717 case 'S':
718 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
719 break;
720
721 case 'P':
722 (*info->fprintf_func) (info->stream, "$pc");
723 break;
724
725 case 'R':
726 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
727 break;
728
729 case 'X':
730 (*info->fprintf_func) (info->stream, "$%s",
731 reg_names[((l >> MIPS16OP_SH_REGR32)
732 & MIPS16OP_MASK_REGR32)]);
733 break;
734
735 case 'Y':
736 (*info->fprintf_func) (info->stream, "$%s",
737 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
738 break;
739
740 case '<':
741 case '>':
742 case '[':
743 case ']':
744 case '4':
745 case '5':
746 case 'H':
747 case 'W':
748 case 'D':
749 case 'j':
750 case '6':
751 case '8':
752 case 'V':
753 case 'C':
754 case 'U':
755 case 'k':
756 case 'K':
757 case 'p':
758 case 'q':
759 case 'A':
760 case 'B':
761 case 'E':
762 {
763 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
764
765 shift = 0;
766 signedp = 0;
767 extbits = 16;
768 pcrel = 0;
769 extu = 0;
770 branch = 0;
771 switch (type)
772 {
773 case '<':
774 nbits = 3;
775 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
776 extbits = 5;
777 extu = 1;
778 break;
779 case '>':
780 nbits = 3;
781 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
782 extbits = 5;
783 extu = 1;
784 break;
785 case '[':
786 nbits = 3;
787 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
788 extbits = 6;
789 extu = 1;
790 break;
791 case ']':
792 nbits = 3;
793 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
794 extbits = 6;
795 extu = 1;
796 break;
797 case '4':
798 nbits = 4;
799 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
800 signedp = 1;
801 extbits = 15;
802 break;
803 case '5':
804 nbits = 5;
805 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
806 info->insn_type = dis_dref;
807 info->data_size = 1;
808 break;
809 case 'H':
810 nbits = 5;
811 shift = 1;
812 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
813 info->insn_type = dis_dref;
814 info->data_size = 2;
815 break;
816 case 'W':
817 nbits = 5;
818 shift = 2;
819 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
820 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
821 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
822 {
823 info->insn_type = dis_dref;
824 info->data_size = 4;
825 }
826 break;
827 case 'D':
828 nbits = 5;
829 shift = 3;
830 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
831 info->insn_type = dis_dref;
832 info->data_size = 8;
833 break;
834 case 'j':
835 nbits = 5;
836 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
837 signedp = 1;
838 break;
839 case '6':
840 nbits = 6;
841 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
842 break;
843 case '8':
844 nbits = 8;
845 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
846 break;
847 case 'V':
848 nbits = 8;
849 shift = 2;
850 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
851 /* FIXME: This might be lw, or it might be addiu to $sp or
852 $pc. We assume it's load. */
853 info->insn_type = dis_dref;
854 info->data_size = 4;
855 break;
856 case 'C':
857 nbits = 8;
858 shift = 3;
859 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
860 info->insn_type = dis_dref;
861 info->data_size = 8;
862 break;
863 case 'U':
864 nbits = 8;
865 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
866 extu = 1;
867 break;
868 case 'k':
869 nbits = 8;
870 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
871 signedp = 1;
872 break;
873 case 'K':
874 nbits = 8;
875 shift = 3;
876 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
877 signedp = 1;
878 break;
879 case 'p':
880 nbits = 8;
881 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
882 signedp = 1;
883 pcrel = 1;
884 branch = 1;
885 info->insn_type = dis_condbranch;
886 break;
887 case 'q':
888 nbits = 11;
889 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
890 signedp = 1;
891 pcrel = 1;
892 branch = 1;
893 info->insn_type = dis_branch;
894 break;
895 case 'A':
896 nbits = 8;
897 shift = 2;
898 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
899 pcrel = 1;
900 /* FIXME: This can be lw or la. We assume it is lw. */
901 info->insn_type = dis_dref;
902 info->data_size = 4;
903 break;
904 case 'B':
905 nbits = 5;
906 shift = 3;
907 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
908 pcrel = 1;
909 info->insn_type = dis_dref;
910 info->data_size = 8;
911 break;
912 case 'E':
913 nbits = 5;
914 shift = 2;
915 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
916 pcrel = 1;
917 break;
918 default:
919 abort ();
920 }
921
922 if (! use_extend)
923 {
924 if (signedp && immed >= (1 << (nbits - 1)))
925 immed -= 1 << nbits;
926 immed <<= shift;
927 if ((type == '<' || type == '>' || type == '[' || type == ']')
928 && immed == 0)
929 immed = 8;
930 }
931 else
932 {
933 if (extbits == 16)
934 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
935 else if (extbits == 15)
936 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
937 else
938 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
939 immed &= (1 << extbits) - 1;
940 if (! extu && immed >= (1 << (extbits - 1)))
941 immed -= 1 << extbits;
942 }
943
944 if (! pcrel)
945 (*info->fprintf_func) (info->stream, "%d", immed);
946 else
947 {
948 bfd_vma baseaddr;
949 bfd_vma val;
950
951 if (branch)
952 {
953 immed *= 2;
954 baseaddr = memaddr + 2;
955 }
956 else if (use_extend)
957 baseaddr = memaddr - 2;
958 else
959 {
960 int status;
961 bfd_byte buffer[2];
962
963 baseaddr = memaddr;
964
965 /* If this instruction is in the delay slot of a jr
966 instruction, the base address is the address of the
967 jr instruction. If it is in the delay slot of jalr
968 instruction, the base address is the address of the
969 jalr instruction. This test is unreliable: we have
970 no way of knowing whether the previous word is
971 instruction or data. */
972 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
973 info);
974 if (status == 0
975 && (((info->endian == BFD_ENDIAN_BIG
976 ? bfd_getb16 (buffer)
977 : bfd_getl16 (buffer))
978 & 0xf800) == 0x1800))
979 baseaddr = memaddr - 4;
980 else
981 {
982 status = (*info->read_memory_func) (memaddr - 2, buffer,
983 2, info);
984 if (status == 0
985 && (((info->endian == BFD_ENDIAN_BIG
986 ? bfd_getb16 (buffer)
987 : bfd_getl16 (buffer))
988 & 0xf81f) == 0xe800))
989 baseaddr = memaddr - 2;
990 }
991 }
992 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
993 (*info->print_address_func) (val, info);
994 info->target = val;
995 }
996 }
997 break;
998
999 case 'a':
1000 if (! use_extend)
1001 extend = 0;
1002 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1003 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1004 info->insn_type = dis_jsr;
1005 info->target = (memaddr & 0xf0000000) | l;
1006 info->branch_delay_insns = 1;
1007 break;
1008
1009 case 'l':
1010 case 'L':
1011 {
1012 int need_comma, amask, smask;
1013
1014 need_comma = 0;
1015
1016 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1017
1018 amask = (l >> 3) & 7;
1019
1020 if (amask > 0 && amask < 5)
1021 {
1022 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1023 if (amask > 1)
1024 (*info->fprintf_func) (info->stream, "-$%s",
1025 reg_names[amask + 3]);
1026 need_comma = 1;
1027 }
1028
1029 smask = (l >> 1) & 3;
1030 if (smask == 3)
1031 {
1032 (*info->fprintf_func) (info->stream, "%s??",
1033 need_comma ? "," : "");
1034 need_comma = 1;
1035 }
1036 else if (smask > 0)
1037 {
1038 (*info->fprintf_func) (info->stream, "%s$%s",
1039 need_comma ? "," : "",
1040 reg_names[16]);
1041 if (smask > 1)
1042 (*info->fprintf_func) (info->stream, "-$%s",
1043 reg_names[smask + 15]);
1044 need_comma = 1;
1045 }
1046
1047 if (l & 1)
1048 {
1049 (*info->fprintf_func) (info->stream, "%s$%s",
1050 need_comma ? "," : "",
1051 reg_names[31]);
1052 need_comma = 1;
1053 }
1054
1055 if (amask == 5 || amask == 6)
1056 {
1057 (*info->fprintf_func) (info->stream, "%s$f0",
1058 need_comma ? "," : "");
1059 if (amask == 6)
1060 (*info->fprintf_func) (info->stream, "-$f1");
1061 }
1062 }
1063 break;
1064
1065 default:
1066 abort ();
1067 }
1068 }
This page took 0.052526 seconds and 5 git commands to generate.