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