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