2001-06-06 H.J. Lu <hjl@gnu.org>
[binutils.git] / opcodes / mips-dis.c
blob3d737f67c311ba6351ecd72a83df5abefe985cd9
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).
7 This file is part of GDB, GAS, and the GNU binutils.
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.
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.
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. */
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #include "opcode/mips.h"
26 #include "opintl.h"
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. */
33 #if !defined(EMBEDDED_ENV)
34 #define SYMTAB_AVAILABLE 1
35 #include "elf-bfd.h"
36 #include "elf/mips.h"
37 #endif
39 /* Mips instructions are at maximum this many bytes long. */
40 #define INSNLEN 4
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 *));
54 /* FIXME: These should be shared with gdb somehow. */
56 /* The mips16 register names. */
57 static const char * const mips16_reg_names[] =
59 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
62 static const char * const mips32_reg_names[] =
64 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
65 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
66 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
67 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
68 "sr", "lo", "hi", "bad", "cause", "pc",
69 "fv0", "$f1", "fv1", "$f3", "ft0", "$f5", "ft1", "$f7",
70 "ft2", "$f9", "ft3", "$f11", "fa0", "$f13", "fa1", "$f15",
71 "ft4", "f17", "ft5", "f19", "fs0", "f21", "fs1", "f23",
72 "fs2", "$f25", "fs3", "$f27", "fs4", "$f29", "fs5", "$f31",
73 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
74 "epc", "prid"
77 static const char * const mips64_reg_names[] =
79 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
80 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
81 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
82 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
83 "sr", "lo", "hi", "bad", "cause", "pc",
84 "fv0", "$f1", "fv1", "$f3", "ft0", "ft1", "ft2", "ft3",
85 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
86 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
87 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
88 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
89 "epc", "prid"
92 /* Scalar register names. _print_insn_mips() decides which register name
93 table to use. */
94 static const char * const *reg_names = NULL;
96 /* Print insn arguments for 32/64-bit code */
98 static void
99 print_insn_arg (d, l, pc, info)
100 const char *d;
101 register unsigned long int l;
102 bfd_vma pc;
103 struct disassemble_info *info;
105 int delta;
107 switch (*d)
109 case ',':
110 case '(':
111 case ')':
112 (*info->fprintf_func) (info->stream, "%c", *d);
113 break;
115 case 's':
116 case 'b':
117 case 'r':
118 case 'v':
119 (*info->fprintf_func) (info->stream, "%s",
120 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
121 break;
123 case 't':
124 case 'w':
125 (*info->fprintf_func) (info->stream, "%s",
126 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
127 break;
129 case 'i':
130 case 'u':
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
133 break;
135 case 'j': /* same as i, but sign-extended */
136 case 'o':
137 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
138 if (delta & 0x8000)
139 delta |= ~0xffff;
140 (*info->fprintf_func) (info->stream, "%d",
141 delta);
142 break;
144 case 'h':
145 (*info->fprintf_func) (info->stream, "0x%x",
146 (unsigned int) ((l >> OP_SH_PREFX)
147 & OP_MASK_PREFX));
148 break;
150 case 'k':
151 (*info->fprintf_func) (info->stream, "0x%x",
152 (unsigned int) ((l >> OP_SH_CACHE)
153 & OP_MASK_CACHE));
154 break;
156 case 'a':
157 (*info->print_address_func)
158 ((((pc + 4) & ~ (bfd_vma) 0x0fffffff)
159 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
160 info);
161 break;
163 case 'p':
164 /* sign extend the displacement */
165 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
166 if (delta & 0x8000)
167 delta |= ~0xffff;
168 (*info->print_address_func)
169 ((delta << 2) + pc + INSNLEN,
170 info);
171 break;
173 case 'd':
174 (*info->fprintf_func) (info->stream, "%s",
175 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
176 break;
178 case 'U':
180 /* First check for both rd and rt being equal. */
181 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
182 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
183 (*info->fprintf_func) (info->stream, "%s",
184 reg_names[reg]);
185 else
187 /* If one is zero use the other. */
188 if (reg == 0)
189 (*info->fprintf_func) (info->stream, "%s",
190 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
191 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
192 (*info->fprintf_func) (info->stream, "%s",
193 reg_names[reg]);
194 else /* Bogus, result depends on processor. */
195 (*info->fprintf_func) (info->stream, "%s or %s",
196 reg_names[reg],
197 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
200 break;
202 case 'z':
203 (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
204 break;
206 case '<':
207 (*info->fprintf_func) (info->stream, "0x%x",
208 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
209 break;
211 case 'c':
212 (*info->fprintf_func) (info->stream, "0x%x",
213 (l >> OP_SH_CODE) & OP_MASK_CODE);
214 break;
216 case 'q':
217 (*info->fprintf_func) (info->stream, "0x%x",
218 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
219 break;
221 case 'C':
222 (*info->fprintf_func) (info->stream, "0x%x",
223 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
224 break;
226 case 'B':
227 (*info->fprintf_func) (info->stream, "0x%x",
228 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
229 break;
231 case 'J':
232 (*info->fprintf_func) (info->stream, "0x%x",
233 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
234 break;
236 case 'S':
237 case 'V':
238 (*info->fprintf_func) (info->stream, "$f%d",
239 (l >> OP_SH_FS) & OP_MASK_FS);
240 break;
242 case 'T':
243 case 'W':
244 (*info->fprintf_func) (info->stream, "$f%d",
245 (l >> OP_SH_FT) & OP_MASK_FT);
246 break;
248 case 'D':
249 (*info->fprintf_func) (info->stream, "$f%d",
250 (l >> OP_SH_FD) & OP_MASK_FD);
251 break;
253 case 'R':
254 (*info->fprintf_func) (info->stream, "$f%d",
255 (l >> OP_SH_FR) & OP_MASK_FR);
256 break;
258 case 'E':
259 (*info->fprintf_func) (info->stream, "%s",
260 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
261 break;
263 case 'G':
264 (*info->fprintf_func) (info->stream, "%s",
265 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
266 break;
268 case 'N':
269 (*info->fprintf_func) (info->stream, "$fcc%d",
270 (l >> OP_SH_BCC) & OP_MASK_BCC);
271 break;
273 case 'M':
274 (*info->fprintf_func) (info->stream, "$fcc%d",
275 (l >> OP_SH_CCC) & OP_MASK_CCC);
276 break;
278 case 'P':
279 (*info->fprintf_func) (info->stream, "%d",
280 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
281 break;
283 case 'H':
284 (*info->fprintf_func) (info->stream, "%d",
285 (l >> OP_SH_SEL) & OP_MASK_SEL);
286 break;
288 default:
289 /* xgettext:c-format */
290 (*info->fprintf_func) (info->stream,
291 _("# internal error, undefined modifier(%c)"),
292 *d);
293 break;
297 /* Figure out the MIPS ISA and CPU based on the machine number. */
299 static void
300 mips_isa_type (mach, isa, cputype)
301 int mach;
302 int *isa;
303 int *cputype;
305 switch (mach)
307 case bfd_mach_mips3000:
308 *cputype = CPU_R3000;
309 *isa = ISA_MIPS1;
310 break;
311 case bfd_mach_mips3900:
312 *cputype = CPU_R3900;
313 *isa = ISA_MIPS1;
314 break;
315 case bfd_mach_mips4000:
316 *cputype = CPU_R4000;
317 *isa = ISA_MIPS3;
318 break;
319 case bfd_mach_mips4010:
320 *cputype = CPU_R4010;
321 *isa = ISA_MIPS2;
322 break;
323 case bfd_mach_mips4100:
324 *cputype = CPU_VR4100;
325 *isa = ISA_MIPS3;
326 break;
327 case bfd_mach_mips4111:
328 *cputype = CPU_R4111;
329 *isa = ISA_MIPS3;
330 break;
331 case bfd_mach_mips4300:
332 *cputype = CPU_R4300;
333 *isa = ISA_MIPS3;
334 break;
335 case bfd_mach_mips4400:
336 *cputype = CPU_R4400;
337 *isa = ISA_MIPS3;
338 break;
339 case bfd_mach_mips4600:
340 *cputype = CPU_R4600;
341 *isa = ISA_MIPS3;
342 break;
343 case bfd_mach_mips4650:
344 *cputype = CPU_R4650;
345 *isa = ISA_MIPS3;
346 break;
347 case bfd_mach_mips5000:
348 *cputype = CPU_R5000;
349 *isa = ISA_MIPS4;
350 break;
351 case bfd_mach_mips6000:
352 *cputype = CPU_R6000;
353 *isa = ISA_MIPS2;
354 break;
355 case bfd_mach_mips8000:
356 *cputype = CPU_R8000;
357 *isa = ISA_MIPS4;
358 break;
359 case bfd_mach_mips10000:
360 *cputype = CPU_R10000;
361 *isa = ISA_MIPS4;
362 break;
363 case bfd_mach_mips12000:
364 *cputype = CPU_R12000;
365 *isa = ISA_MIPS4;
366 break;
367 case bfd_mach_mips16:
368 *cputype = CPU_MIPS16;
369 *isa = ISA_MIPS3;
370 break;
371 case bfd_mach_mips32:
372 *cputype = CPU_MIPS32;
373 *isa = ISA_MIPS32;
374 break;
375 case bfd_mach_mips32_4k:
376 *cputype = CPU_MIPS32_4K;
377 *isa = ISA_MIPS32;
378 break;
379 case bfd_mach_mips5:
380 *cputype = CPU_MIPS5;
381 *isa = ISA_MIPS5;
382 break;
383 case bfd_mach_mips64:
384 *cputype = CPU_MIPS64;
385 *isa = ISA_MIPS64;
386 break;
387 case bfd_mach_mips_sb1:
388 *cputype = CPU_SB1;
389 *isa = ISA_MIPS64;
390 break;
391 default:
392 *cputype = CPU_R3000;
393 *isa = ISA_MIPS3;
394 break;
398 /* Figure out ISA from disassemble_info data */
400 static int
401 get_mips_isa (info)
402 struct disassemble_info *info;
404 int isa;
405 int cpu;
407 mips_isa_type (info->mach, &isa, &cpu);
408 return isa;
411 /* Print the mips instruction at address MEMADDR in debugged memory,
412 on using INFO. Returns length of the instruction, in bytes, which is
413 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
414 this is little-endian code. */
416 static int
417 print_insn_mips (memaddr, word, info)
418 bfd_vma memaddr;
419 unsigned long int word;
420 struct disassemble_info *info;
422 register const struct mips_opcode *op;
423 int target_processor, mips_isa;
424 static boolean init = 0;
425 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
427 /* Build a hash table to shorten the search time. */
428 if (! init)
430 unsigned int i;
432 for (i = 0; i <= OP_MASK_OP; i++)
434 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
436 if (op->pinfo == INSN_MACRO)
437 continue;
438 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
440 mips_hash[i] = op;
441 break;
446 init = 1;
449 #if ! SYMTAB_AVAILABLE
450 /* This is running out on a target machine, not in a host tool.
451 FIXME: Where does mips_target_info come from? */
452 target_processor = mips_target_info.processor;
453 mips_isa = mips_target_info.isa;
454 #else
455 mips_isa_type (info->mach, &mips_isa, &target_processor);
456 #endif
458 info->bytes_per_chunk = INSNLEN;
459 info->display_endian = info->endian;
461 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
462 if (op != NULL)
464 for (; op < &mips_opcodes[NUMOPCODES]; op++)
466 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
468 register const char *d;
470 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
471 continue;
473 (*info->fprintf_func) (info->stream, "%s", op->name);
475 d = op->args;
476 if (d != NULL && *d != '\0')
478 (*info->fprintf_func) (info->stream, "\t");
479 for (; *d != '\0'; d++)
480 print_insn_arg (d, word, memaddr, info);
483 return INSNLEN;
488 /* Handle undefined instructions. */
489 (*info->fprintf_func) (info->stream, "0x%x", word);
490 return INSNLEN;
493 /* In an environment where we do not know the symbol type of the
494 instruction we are forced to assume that the low order bit of the
495 instructions' address may mark it as a mips16 instruction. If we
496 are single stepping, or the pc is within the disassembled function,
497 this works. Otherwise, we need a clue. Sometimes. */
499 static int
500 _print_insn_mips (memaddr, info, endianness)
501 bfd_vma memaddr;
502 struct disassemble_info *info;
503 enum bfd_endian endianness;
505 bfd_byte buffer[INSNLEN];
506 int status;
508 #if 1
509 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
510 /* Only a few tools will work this way. */
511 if (memaddr & 0x01)
512 return print_insn_mips16 (memaddr, info);
513 #endif
515 #if SYMTAB_AVAILABLE
516 if (info->mach == 16
517 || (info->flavour == bfd_target_elf_flavour
518 && info->symbols != NULL
519 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
520 == STO_MIPS16)))
521 return print_insn_mips16 (memaddr, info);
522 #endif
524 /* Use mips64_reg_names for new ABI. */
525 if (info->flavour == bfd_target_elf_flavour
526 && info->symbols != NULL
527 && (((get_mips_isa(info) | INSN_ISA_MASK) & ISA_MIPS2) != 0)
528 && ((elf_elfheader (bfd_asymbol_bfd(*(info->symbols)))->e_flags
529 & EF_MIPS_ABI2) != 0))
530 reg_names = mips64_reg_names;
531 else
532 reg_names = mips32_reg_names;
534 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
535 if (status == 0)
537 unsigned long insn;
539 if (endianness == BFD_ENDIAN_BIG)
540 insn = (unsigned long) bfd_getb32 (buffer);
541 else
542 insn = (unsigned long) bfd_getl32 (buffer);
544 return print_insn_mips (memaddr, insn, info);
546 else
548 (*info->memory_error_func) (status, memaddr, info);
549 return -1;
554 print_insn_big_mips (memaddr, info)
555 bfd_vma memaddr;
556 struct disassemble_info *info;
558 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
562 print_insn_little_mips (memaddr, info)
563 bfd_vma memaddr;
564 struct disassemble_info *info;
566 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
569 /* Disassemble mips16 instructions. */
571 static int
572 print_insn_mips16 (memaddr, info)
573 bfd_vma memaddr;
574 struct disassemble_info *info;
576 int status;
577 bfd_byte buffer[2];
578 int length;
579 int insn;
580 boolean use_extend;
581 int extend = 0;
582 const struct mips_opcode *op, *opend;
584 info->bytes_per_chunk = 2;
585 info->display_endian = info->endian;
586 info->insn_info_valid = 1;
587 info->branch_delay_insns = 0;
588 info->data_size = 0;
589 info->insn_type = dis_nonbranch;
590 info->target = 0;
591 info->target2 = 0;
593 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
594 if (status != 0)
596 (*info->memory_error_func) (status, memaddr, info);
597 return -1;
600 length = 2;
602 if (info->endian == BFD_ENDIAN_BIG)
603 insn = bfd_getb16 (buffer);
604 else
605 insn = bfd_getl16 (buffer);
607 /* Handle the extend opcode specially. */
608 use_extend = false;
609 if ((insn & 0xf800) == 0xf000)
611 use_extend = true;
612 extend = insn & 0x7ff;
614 memaddr += 2;
616 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
617 if (status != 0)
619 (*info->fprintf_func) (info->stream, "extend 0x%x",
620 (unsigned int) extend);
621 (*info->memory_error_func) (status, memaddr, info);
622 return -1;
625 if (info->endian == BFD_ENDIAN_BIG)
626 insn = bfd_getb16 (buffer);
627 else
628 insn = bfd_getl16 (buffer);
630 /* Check for an extend opcode followed by an extend opcode. */
631 if ((insn & 0xf800) == 0xf000)
633 (*info->fprintf_func) (info->stream, "extend 0x%x",
634 (unsigned int) extend);
635 info->insn_type = dis_noninsn;
636 return length;
639 length += 2;
642 /* FIXME: Should probably use a hash table on the major opcode here. */
644 opend = mips16_opcodes + bfd_mips16_num_opcodes;
645 for (op = mips16_opcodes; op < opend; op++)
647 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
649 const char *s;
651 if (strchr (op->args, 'a') != NULL)
653 if (use_extend)
655 (*info->fprintf_func) (info->stream, "extend 0x%x",
656 (unsigned int) extend);
657 info->insn_type = dis_noninsn;
658 return length - 2;
661 use_extend = false;
663 memaddr += 2;
665 status = (*info->read_memory_func) (memaddr, buffer, 2,
666 info);
667 if (status == 0)
669 use_extend = true;
670 if (info->endian == BFD_ENDIAN_BIG)
671 extend = bfd_getb16 (buffer);
672 else
673 extend = bfd_getl16 (buffer);
674 length += 2;
678 (*info->fprintf_func) (info->stream, "%s", op->name);
679 if (op->args[0] != '\0')
680 (*info->fprintf_func) (info->stream, "\t");
682 for (s = op->args; *s != '\0'; s++)
684 if (*s == ','
685 && s[1] == 'w'
686 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
687 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
689 /* Skip the register and the comma. */
690 ++s;
691 continue;
693 if (*s == ','
694 && s[1] == 'v'
695 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
696 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
698 /* Skip the register and the comma. */
699 ++s;
700 continue;
702 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
703 info);
706 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
708 info->branch_delay_insns = 1;
709 if (info->insn_type != dis_jsr)
710 info->insn_type = dis_branch;
713 return length;
717 if (use_extend)
718 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
719 (*info->fprintf_func) (info->stream, "0x%x", insn);
720 info->insn_type = dis_noninsn;
722 return length;
725 /* Disassemble an operand for a mips16 instruction. */
727 static void
728 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
729 char type;
730 const struct mips_opcode *op;
731 int l;
732 boolean use_extend;
733 int extend;
734 bfd_vma memaddr;
735 struct disassemble_info *info;
737 switch (type)
739 case ',':
740 case '(':
741 case ')':
742 (*info->fprintf_func) (info->stream, "%c", type);
743 break;
745 case 'y':
746 case 'w':
747 (*info->fprintf_func) (info->stream, "%s",
748 mips16_reg_names[((l >> MIPS16OP_SH_RY)
749 & MIPS16OP_MASK_RY)]);
750 break;
752 case 'x':
753 case 'v':
754 (*info->fprintf_func) (info->stream, "%s",
755 mips16_reg_names[((l >> MIPS16OP_SH_RX)
756 & MIPS16OP_MASK_RX)]);
757 break;
759 case 'z':
760 (*info->fprintf_func) (info->stream, "%s",
761 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
762 & MIPS16OP_MASK_RZ)]);
763 break;
765 case 'Z':
766 (*info->fprintf_func) (info->stream, "%s",
767 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
768 & MIPS16OP_MASK_MOVE32Z)]);
769 break;
771 case '0':
772 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
773 break;
775 case 'S':
776 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
777 break;
779 case 'P':
780 (*info->fprintf_func) (info->stream, "$pc");
781 break;
783 case 'R':
784 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
785 break;
787 case 'X':
788 (*info->fprintf_func) (info->stream, "%s",
789 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
790 & MIPS16OP_MASK_REGR32)]);
791 break;
793 case 'Y':
794 (*info->fprintf_func) (info->stream, "%s",
795 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
796 break;
798 case '<':
799 case '>':
800 case '[':
801 case ']':
802 case '4':
803 case '5':
804 case 'H':
805 case 'W':
806 case 'D':
807 case 'j':
808 case '6':
809 case '8':
810 case 'V':
811 case 'C':
812 case 'U':
813 case 'k':
814 case 'K':
815 case 'p':
816 case 'q':
817 case 'A':
818 case 'B':
819 case 'E':
821 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
823 shift = 0;
824 signedp = 0;
825 extbits = 16;
826 pcrel = 0;
827 extu = 0;
828 branch = 0;
829 switch (type)
831 case '<':
832 nbits = 3;
833 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
834 extbits = 5;
835 extu = 1;
836 break;
837 case '>':
838 nbits = 3;
839 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
840 extbits = 5;
841 extu = 1;
842 break;
843 case '[':
844 nbits = 3;
845 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
846 extbits = 6;
847 extu = 1;
848 break;
849 case ']':
850 nbits = 3;
851 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
852 extbits = 6;
853 extu = 1;
854 break;
855 case '4':
856 nbits = 4;
857 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
858 signedp = 1;
859 extbits = 15;
860 break;
861 case '5':
862 nbits = 5;
863 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
864 info->insn_type = dis_dref;
865 info->data_size = 1;
866 break;
867 case 'H':
868 nbits = 5;
869 shift = 1;
870 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
871 info->insn_type = dis_dref;
872 info->data_size = 2;
873 break;
874 case 'W':
875 nbits = 5;
876 shift = 2;
877 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
878 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
879 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
881 info->insn_type = dis_dref;
882 info->data_size = 4;
884 break;
885 case 'D':
886 nbits = 5;
887 shift = 3;
888 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
889 info->insn_type = dis_dref;
890 info->data_size = 8;
891 break;
892 case 'j':
893 nbits = 5;
894 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
895 signedp = 1;
896 break;
897 case '6':
898 nbits = 6;
899 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
900 break;
901 case '8':
902 nbits = 8;
903 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
904 break;
905 case 'V':
906 nbits = 8;
907 shift = 2;
908 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
909 /* FIXME: This might be lw, or it might be addiu to $sp or
910 $pc. We assume it's load. */
911 info->insn_type = dis_dref;
912 info->data_size = 4;
913 break;
914 case 'C':
915 nbits = 8;
916 shift = 3;
917 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
918 info->insn_type = dis_dref;
919 info->data_size = 8;
920 break;
921 case 'U':
922 nbits = 8;
923 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
924 extu = 1;
925 break;
926 case 'k':
927 nbits = 8;
928 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
929 signedp = 1;
930 break;
931 case 'K':
932 nbits = 8;
933 shift = 3;
934 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
935 signedp = 1;
936 break;
937 case 'p':
938 nbits = 8;
939 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
940 signedp = 1;
941 pcrel = 1;
942 branch = 1;
943 info->insn_type = dis_condbranch;
944 break;
945 case 'q':
946 nbits = 11;
947 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
948 signedp = 1;
949 pcrel = 1;
950 branch = 1;
951 info->insn_type = dis_branch;
952 break;
953 case 'A':
954 nbits = 8;
955 shift = 2;
956 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
957 pcrel = 1;
958 /* FIXME: This can be lw or la. We assume it is lw. */
959 info->insn_type = dis_dref;
960 info->data_size = 4;
961 break;
962 case 'B':
963 nbits = 5;
964 shift = 3;
965 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
966 pcrel = 1;
967 info->insn_type = dis_dref;
968 info->data_size = 8;
969 break;
970 case 'E':
971 nbits = 5;
972 shift = 2;
973 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
974 pcrel = 1;
975 break;
976 default:
977 abort ();
980 if (! use_extend)
982 if (signedp && immed >= (1 << (nbits - 1)))
983 immed -= 1 << nbits;
984 immed <<= shift;
985 if ((type == '<' || type == '>' || type == '[' || type == ']')
986 && immed == 0)
987 immed = 8;
989 else
991 if (extbits == 16)
992 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
993 else if (extbits == 15)
994 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
995 else
996 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
997 immed &= (1 << extbits) - 1;
998 if (! extu && immed >= (1 << (extbits - 1)))
999 immed -= 1 << extbits;
1002 if (! pcrel)
1003 (*info->fprintf_func) (info->stream, "%d", immed);
1004 else
1006 bfd_vma baseaddr;
1007 bfd_vma val;
1009 if (branch)
1011 immed *= 2;
1012 baseaddr = memaddr + 2;
1014 else if (use_extend)
1015 baseaddr = memaddr - 2;
1016 else
1018 int status;
1019 bfd_byte buffer[2];
1021 baseaddr = memaddr;
1023 /* If this instruction is in the delay slot of a jr
1024 instruction, the base address is the address of the
1025 jr instruction. If it is in the delay slot of jalr
1026 instruction, the base address is the address of the
1027 jalr instruction. This test is unreliable: we have
1028 no way of knowing whether the previous word is
1029 instruction or data. */
1030 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1031 info);
1032 if (status == 0
1033 && (((info->endian == BFD_ENDIAN_BIG
1034 ? bfd_getb16 (buffer)
1035 : bfd_getl16 (buffer))
1036 & 0xf800) == 0x1800))
1037 baseaddr = memaddr - 4;
1038 else
1040 status = (*info->read_memory_func) (memaddr - 2, buffer,
1041 2, info);
1042 if (status == 0
1043 && (((info->endian == BFD_ENDIAN_BIG
1044 ? bfd_getb16 (buffer)
1045 : bfd_getl16 (buffer))
1046 & 0xf81f) == 0xe800))
1047 baseaddr = memaddr - 2;
1050 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1051 (*info->print_address_func) (val, info);
1052 info->target = val;
1055 break;
1057 case 'a':
1058 if (! use_extend)
1059 extend = 0;
1060 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1061 (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
1062 info->insn_type = dis_jsr;
1063 info->target = ((memaddr + 4) & 0xf0000000) | l;
1064 info->branch_delay_insns = 1;
1065 break;
1067 case 'l':
1068 case 'L':
1070 int need_comma, amask, smask;
1072 need_comma = 0;
1074 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1076 amask = (l >> 3) & 7;
1078 if (amask > 0 && amask < 5)
1080 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1081 if (amask > 1)
1082 (*info->fprintf_func) (info->stream, "-%s",
1083 mips32_reg_names[amask + 3]);
1084 need_comma = 1;
1087 smask = (l >> 1) & 3;
1088 if (smask == 3)
1090 (*info->fprintf_func) (info->stream, "%s??",
1091 need_comma ? "," : "");
1092 need_comma = 1;
1094 else if (smask > 0)
1096 (*info->fprintf_func) (info->stream, "%s%s",
1097 need_comma ? "," : "",
1098 mips32_reg_names[16]);
1099 if (smask > 1)
1100 (*info->fprintf_func) (info->stream, "-%s",
1101 mips32_reg_names[smask + 15]);
1102 need_comma = 1;
1105 if (l & 1)
1107 (*info->fprintf_func) (info->stream, "%s%s",
1108 need_comma ? "," : "",
1109 mips32_reg_names[31]);
1110 need_comma = 1;
1113 if (amask == 5 || amask == 6)
1115 (*info->fprintf_func) (info->stream, "%s$f0",
1116 need_comma ? "," : "");
1117 if (amask == 6)
1118 (*info->fprintf_func) (info->stream, "-$f1");
1121 break;
1123 default:
1124 /* xgettext:c-format */
1125 (*info->fprintf_func)
1126 (info->stream,
1127 _("# internal disassembler error, unrecognised modifier (%c)"),
1128 type);
1129 abort ();