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