* elflink.h (elf_link_add_object_symbols): Don't bfd_release runpath.
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
73da6b6b
AM
2 Copyright (c) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5
6This file is part of GDB, GAS, and the GNU binutils.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
252b5132
RH
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
38static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
39static 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
46static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
47 struct disassemble_info *));
48static 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. */
fb48caed 53#define STD_REGISTER_NAMES \
252b5132
RH
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
fb48caed 67static CONST char * CONST std_reg_names[] = STD_REGISTER_NAMES;
252b5132
RH
68
69/* The mips16 register names. */
70static const char * const mips16_reg_names[] =
71{
72 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
73};
fb48caed
DN
74
75/* Scalar register names. set_mips_isa_type() decides which register name
76 table to use. */
77static CONST char * CONST *reg_names = NULL;
252b5132
RH
78\f
79/* subroutine */
80static void
81print_insn_arg (d, l, pc, info)
82 const char *d;
83 register unsigned long int l;
84 bfd_vma pc;
85 struct disassemble_info *info;
86{
87 int delta;
88
89 switch (*d)
90 {
91 case ',':
92 case '(':
93 case ')':
94 (*info->fprintf_func) (info->stream, "%c", *d);
95 break;
96
97 case 's':
98 case 'b':
99 case 'r':
100 case 'v':
101 (*info->fprintf_func) (info->stream, "$%s",
102 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
103 break;
104
105 case 't':
106 case 'w':
107 (*info->fprintf_func) (info->stream, "$%s",
108 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
109 break;
110
111 case 'i':
112 case 'u':
113 (*info->fprintf_func) (info->stream, "0x%x",
114 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
115 break;
116
117 case 'j': /* same as i, but sign-extended */
118 case 'o':
119 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
120 if (delta & 0x8000)
121 delta |= ~0xffff;
122 (*info->fprintf_func) (info->stream, "%d",
123 delta);
124 break;
125
126 case 'h':
127 (*info->fprintf_func) (info->stream, "0x%x",
128 (unsigned int) ((l >> OP_SH_PREFX)
129 & OP_MASK_PREFX));
130 break;
131
132 case 'k':
133 (*info->fprintf_func) (info->stream, "0x%x",
134 (unsigned int) ((l >> OP_SH_CACHE)
135 & OP_MASK_CACHE));
136 break;
137
138 case 'a':
139 (*info->print_address_func)
73da6b6b
AM
140 (((pc & ~ (bfd_vma) 0x0fffffff)
141 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
252b5132
RH
142 info);
143 break;
144
145 case 'p':
146 /* sign extend the displacement */
147 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
148 if (delta & 0x8000)
149 delta |= ~0xffff;
150 (*info->print_address_func)
151 ((delta << 2) + pc + 4,
152 info);
153 break;
154
155 case 'd':
156 (*info->fprintf_func) (info->stream, "$%s",
157 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
158 break;
159
160 case 'z':
161 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
162 break;
163
164 case '<':
165 (*info->fprintf_func) (info->stream, "0x%x",
166 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
167 break;
168
169 case 'c':
170 (*info->fprintf_func) (info->stream, "0x%x",
171 (l >> OP_SH_CODE) & OP_MASK_CODE);
172 break;
173
174
175 case 'q':
176 (*info->fprintf_func) (info->stream, "0x%x",
177 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
178 break;
179
156c2f8b
NC
180 case 'm':
181 (*info->fprintf_func) (info->stream, "0x%x",
182 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
183 break;
184
252b5132
RH
185 case 'C':
186 (*info->fprintf_func) (info->stream, "0x%x",
187 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
188 break;
189
190 case 'B':
191 (*info->fprintf_func) (info->stream, "0x%x",
192 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
193 break;
194
195 case 'S':
196 case 'V':
197 (*info->fprintf_func) (info->stream, "$f%d",
198 (l >> OP_SH_FS) & OP_MASK_FS);
199 break;
200
201
202 case 'T':
203 case 'W':
204 (*info->fprintf_func) (info->stream, "$f%d",
205 (l >> OP_SH_FT) & OP_MASK_FT);
206 break;
207
208 case 'D':
209 (*info->fprintf_func) (info->stream, "$f%d",
210 (l >> OP_SH_FD) & OP_MASK_FD);
211 break;
212
213 case 'R':
214 (*info->fprintf_func) (info->stream, "$f%d",
215 (l >> OP_SH_FR) & OP_MASK_FR);
216 break;
217
218 case 'E':
219 (*info->fprintf_func) (info->stream, "$%d",
220 (l >> OP_SH_RT) & OP_MASK_RT);
221 break;
222
223 case 'G':
224 (*info->fprintf_func) (info->stream, "$%d",
225 (l >> OP_SH_RD) & OP_MASK_RD);
226 break;
227
228 case 'N':
229 (*info->fprintf_func) (info->stream, "$fcc%d",
230 (l >> OP_SH_BCC) & OP_MASK_BCC);
231 break;
232
233 case 'M':
234 (*info->fprintf_func) (info->stream, "$fcc%d",
235 (l >> OP_SH_CCC) & OP_MASK_CCC);
236 break;
237
238 case 'P':
239 (*info->fprintf_func) (info->stream, "%d",
240 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
241 break;
242
156c2f8b
NC
243 case 'H':
244 (*info->fprintf_func) (info->stream, "%d",
245 (l >> OP_SH_SEL) & OP_MASK_SEL);
246 break;
252b5132
RH
247
248 default:
249 /* xgettext:c-format */
250 (*info->fprintf_func) (info->stream,
251 _("# internal error, undefined modifier(%c)"),
252 *d);
253 break;
254 }
255}
256\f
257#if SYMTAB_AVAILABLE
258
259/* Figure out the MIPS ISA and CPU based on the machine number.
260 FIXME: What does this have to do with SYMTAB_AVAILABLE? */
261
262static void
263set_mips_isa_type (mach, isa, cputype)
264 int mach;
265 int *isa;
266 int *cputype;
267{
268 int target_processor = 0;
269 int mips_isa = 0;
270
fb48caed
DN
271 /* Use standard MIPS register names by default. */
272 reg_names = std_reg_names;
273
252b5132
RH
274 switch (mach)
275 {
156c2f8b
NC
276 case bfd_mach_mips3000:
277 target_processor = CPU_R3000;
278 mips_isa = 1;
279 break;
280 case bfd_mach_mips3900:
281 target_processor = CPU_R3900;
282 mips_isa = 1;
283 break;
284 case bfd_mach_mips4000:
285 target_processor = CPU_R4000;
286 mips_isa = 3;
287 break;
288 case bfd_mach_mips4010:
289 target_processor = CPU_R4010;
290 mips_isa = 2;
291 break;
292 case bfd_mach_mips4100:
293 target_processor = CPU_VR4100;
294 mips_isa = 3;
295 break;
296 case bfd_mach_mips4111:
297 target_processor = CPU_VR4100; /* FIXME: Shouldn't this be CPU_R4111 ??? */
298 mips_isa = 3;
299 break;
300 case bfd_mach_mips4300:
301 target_processor = CPU_R4300;
302 mips_isa = 3;
303 break;
304 case bfd_mach_mips4400:
305 target_processor = CPU_R4400;
306 mips_isa = 3;
307 break;
308 case bfd_mach_mips4600:
309 target_processor = CPU_R4600;
310 mips_isa = 3;
311 break;
312 case bfd_mach_mips4650:
313 target_processor = CPU_R4650;
314 mips_isa = 3;
315 break;
316 case bfd_mach_mips4K:
317 target_processor = CPU_4K;
318 mips_isa = 2;
319 break;
320 case bfd_mach_mips5000:
321 target_processor = CPU_R5000;
322 mips_isa = 4;
323 break;
324 case bfd_mach_mips6000:
325 target_processor = CPU_R6000;
326 mips_isa = 2;
327 break;
328 case bfd_mach_mips8000:
329 target_processor = CPU_R8000;
330 mips_isa = 4;
331 break;
332 case bfd_mach_mips10000:
333 target_processor = CPU_R10000;
334 mips_isa = 4;
335 break;
336 case bfd_mach_mips16:
337 target_processor = CPU_MIPS16;
338 mips_isa = 3;
339 break;
340 default:
341 target_processor = CPU_R3000;
342 mips_isa = 3;
343 break;
252b5132
RH
344 }
345
346 *isa = mips_isa;
347 *cputype = target_processor;
348}
349
350#endif /* SYMTAB_AVAILABLE */
351
352/* Print the mips instruction at address MEMADDR in debugged memory,
353 on using INFO. Returns length of the instruction, in bytes, which is
354 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
355 this is little-endian code. */
356
357static int
358_print_insn_mips (memaddr, word, info)
359 bfd_vma memaddr;
360 unsigned long int word;
361 struct disassemble_info *info;
362{
363 register const struct mips_opcode *op;
364 int target_processor, mips_isa;
365 static boolean init = 0;
366 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
367
368 /* Build a hash table to shorten the search time. */
369 if (! init)
370 {
371 unsigned int i;
372
373 for (i = 0; i <= OP_MASK_OP; i++)
374 {
375 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
376 {
377 if (op->pinfo == INSN_MACRO)
378 continue;
379 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
380 {
381 mips_hash[i] = op;
382 break;
383 }
384 }
385 }
386
387 init = 1;
388 }
389
390#if ! SYMTAB_AVAILABLE
391 /* This is running out on a target machine, not in a host tool.
392 FIXME: Where does mips_target_info come from? */
393 target_processor = mips_target_info.processor;
394 mips_isa = mips_target_info.isa;
395#else
396 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
397#endif
398
399 info->bytes_per_chunk = 4;
400 info->display_endian = info->endian;
401
402 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
403 if (op != NULL)
404 {
405 for (; op < &mips_opcodes[NUMOPCODES]; op++)
406 {
407 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
408 {
409 register const char *d;
2bd7f1f3 410
8027df89 411 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
252b5132
RH
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
441int
442print_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
476int
477print_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
512static int
513print_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
669static void
670print_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.096997 seconds and 4 git commands to generate.