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