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