* mips-dis.c (print_insn_mips): Remove OPCODE_IS_MEMBER's gp32
[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 {
59 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
60 };
61
62 static const char * const mips32_reg_names[] =
63 {
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"
75 };
76
77 static const char * const mips64_reg_names[] =
78 {
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"
90 };
91
92 /* Scalar register names. _print_insn_mips() decides which register name
93 table to use. */
94 static const char * const *reg_names = NULL;
95 \f
96 /* Print insn arguments for 32/64-bit code */
97
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;
104 {
105 int delta;
106
107 switch (*d)
108 {
109 case ',':
110 case '(':
111 case ')':
112 (*info->fprintf_func) (info->stream, "%c", *d);
113 break;
114
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;
122
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;
128
129 case 'i':
130 case 'u':
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
133 break;
134
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;
143
144 case 'h':
145 (*info->fprintf_func) (info->stream, "0x%x",
146 (unsigned int) ((l >> OP_SH_PREFX)
147 & OP_MASK_PREFX));
148 break;
149
150 case 'k':
151 (*info->fprintf_func) (info->stream, "0x%x",
152 (unsigned int) ((l >> OP_SH_CACHE)
153 & OP_MASK_CACHE));
154 break;
155
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;
162
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;
172
173 case 'd':
174 (*info->fprintf_func) (info->stream, "%s",
175 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
176 break;
177
178 case 'U':
179 {
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
186 {
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]);
198 }
199 }
200 break;
201
202 case 'z':
203 (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
204 break;
205
206 case '<':
207 (*info->fprintf_func) (info->stream, "0x%x",
208 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
209 break;
210
211 case 'c':
212 (*info->fprintf_func) (info->stream, "0x%x",
213 (l >> OP_SH_CODE) & OP_MASK_CODE);
214 break;
215
216 case 'q':
217 (*info->fprintf_func) (info->stream, "0x%x",
218 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
219 break;
220
221 case 'C':
222 (*info->fprintf_func) (info->stream, "0x%x",
223 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
224 break;
225
226 case 'B':
227 (*info->fprintf_func) (info->stream, "0x%x",
228 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
229 break;
230
231 case 'J':
232 (*info->fprintf_func) (info->stream, "0x%x",
233 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
234 break;
235
236 case 'S':
237 case 'V':
238 (*info->fprintf_func) (info->stream, "$f%d",
239 (l >> OP_SH_FS) & OP_MASK_FS);
240 break;
241
242 case 'T':
243 case 'W':
244 (*info->fprintf_func) (info->stream, "$f%d",
245 (l >> OP_SH_FT) & OP_MASK_FT);
246 break;
247
248 case 'D':
249 (*info->fprintf_func) (info->stream, "$f%d",
250 (l >> OP_SH_FD) & OP_MASK_FD);
251 break;
252
253 case 'R':
254 (*info->fprintf_func) (info->stream, "$f%d",
255 (l >> OP_SH_FR) & OP_MASK_FR);
256 break;
257
258 case 'E':
259 (*info->fprintf_func) (info->stream, "$%d",
260 (l >> OP_SH_RT) & OP_MASK_RT);
261 break;
262
263 case 'G':
264 (*info->fprintf_func) (info->stream, "$%d",
265 (l >> OP_SH_RD) & OP_MASK_RD);
266 break;
267
268 case 'N':
269 (*info->fprintf_func) (info->stream, "$fcc%d",
270 (l >> OP_SH_BCC) & OP_MASK_BCC);
271 break;
272
273 case 'M':
274 (*info->fprintf_func) (info->stream, "$fcc%d",
275 (l >> OP_SH_CCC) & OP_MASK_CCC);
276 break;
277
278 case 'P':
279 (*info->fprintf_func) (info->stream, "%d",
280 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
281 break;
282
283 case 'H':
284 (*info->fprintf_func) (info->stream, "%d",
285 (l >> OP_SH_SEL) & OP_MASK_SEL);
286 break;
287
288 default:
289 /* xgettext:c-format */
290 (*info->fprintf_func) (info->stream,
291 _("# internal error, undefined modifier(%c)"),
292 *d);
293 break;
294 }
295 }
296 \f
297 /* Figure out the MIPS ISA and CPU based on the machine number. */
298
299 static void
300 mips_isa_type (mach, isa, cputype)
301 int mach;
302 int *isa;
303 int *cputype;
304 {
305 switch (mach)
306 {
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;
395 }
396 }
397
398 /* Check if the object uses NewABI conventions. */
399
400 static int
401 is_newabi(header)
402 Elf_Internal_Ehdr *header;
403 {
404 if ((header->e_flags
405 & (E_MIPS_ABI_EABI32 | E_MIPS_ABI_EABI64 | EF_MIPS_ABI2)) != 0
406 || (header->e_ident[EI_CLASS] == ELFCLASS64
407 && (header->e_flags & E_MIPS_ABI_O64) == 0))
408 return 1;
409
410 return 0;
411 }
412 \f
413 /* Print the mips instruction at address MEMADDR in debugged memory,
414 on using INFO. Returns length of the instruction, in bytes, which is
415 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
416 this is little-endian code. */
417
418 static int
419 print_insn_mips (memaddr, word, info)
420 bfd_vma memaddr;
421 unsigned long int word;
422 struct disassemble_info *info;
423 {
424 register const struct mips_opcode *op;
425 int target_processor, mips_isa;
426 static boolean init = 0;
427 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
428
429 /* Build a hash table to shorten the search time. */
430 if (! init)
431 {
432 unsigned int i;
433
434 for (i = 0; i <= OP_MASK_OP; i++)
435 {
436 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
437 {
438 if (op->pinfo == INSN_MACRO)
439 continue;
440 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
441 {
442 mips_hash[i] = op;
443 break;
444 }
445 }
446 }
447
448 init = 1;
449 }
450
451 #if ! SYMTAB_AVAILABLE
452 /* This is running out on a target machine, not in a host tool.
453 FIXME: Where does mips_target_info come from? */
454 target_processor = mips_target_info.processor;
455 mips_isa = mips_target_info.isa;
456 #else
457 mips_isa_type (info->mach, &mips_isa, &target_processor);
458 #endif
459
460 info->bytes_per_chunk = INSNLEN;
461 info->display_endian = info->endian;
462
463 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
464 if (op != NULL)
465 {
466 for (; op < &mips_opcodes[NUMOPCODES]; op++)
467 {
468 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
469 {
470 register const char *d;
471
472 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
473 continue;
474
475 (*info->fprintf_func) (info->stream, "%s", op->name);
476
477 d = op->args;
478 if (d != NULL && *d != '\0')
479 {
480 (*info->fprintf_func) (info->stream, "\t");
481 for (; *d != '\0'; d++)
482 print_insn_arg (d, word, memaddr, info);
483 }
484
485 return INSNLEN;
486 }
487 }
488 }
489
490 /* Handle undefined instructions. */
491 (*info->fprintf_func) (info->stream, "0x%x", word);
492 return INSNLEN;
493 }
494 \f
495 /* In an environment where we do not know the symbol type of the
496 instruction we are forced to assume that the low order bit of the
497 instructions' address may mark it as a mips16 instruction. If we
498 are single stepping, or the pc is within the disassembled function,
499 this works. Otherwise, we need a clue. Sometimes. */
500
501 static int
502 _print_insn_mips (memaddr, info, endianness)
503 bfd_vma memaddr;
504 struct disassemble_info *info;
505 enum bfd_endian endianness;
506 {
507 bfd_byte buffer[INSNLEN];
508 int status;
509
510 #if 1
511 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
512 /* Only a few tools will work this way. */
513 if (memaddr & 0x01)
514 return print_insn_mips16 (memaddr, info);
515 #endif
516
517 #if SYMTAB_AVAILABLE
518 if (info->mach == 16
519 || (info->flavour == bfd_target_elf_flavour
520 && info->symbols != NULL
521 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
522 == STO_MIPS16)))
523 return print_insn_mips16 (memaddr, info);
524 #endif
525
526 /* Use mips64_reg_names for new ABI. */
527 reg_names = mips32_reg_names;
528
529 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
530 {
531 Elf_Internal_Ehdr *header;
532
533 header = elf_elfheader(bfd_asymbol_bfd(*(info->symbols)));
534 if (is_newabi(header))
535 reg_names = mips64_reg_names;
536 }
537
538 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
539 if (status == 0)
540 {
541 unsigned long insn;
542
543 if (endianness == BFD_ENDIAN_BIG)
544 insn = (unsigned long) bfd_getb32 (buffer);
545 else
546 insn = (unsigned long) bfd_getl32 (buffer);
547
548 return print_insn_mips (memaddr, insn, info);
549 }
550 else
551 {
552 (*info->memory_error_func) (status, memaddr, info);
553 return -1;
554 }
555 }
556
557 int
558 print_insn_big_mips (memaddr, info)
559 bfd_vma memaddr;
560 struct disassemble_info *info;
561 {
562 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
563 }
564
565 int
566 print_insn_little_mips (memaddr, info)
567 bfd_vma memaddr;
568 struct disassemble_info *info;
569 {
570 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
571 }
572 \f
573 /* Disassemble mips16 instructions. */
574
575 static int
576 print_insn_mips16 (memaddr, info)
577 bfd_vma memaddr;
578 struct disassemble_info *info;
579 {
580 int status;
581 bfd_byte buffer[2];
582 int length;
583 int insn;
584 boolean use_extend;
585 int extend = 0;
586 const struct mips_opcode *op, *opend;
587
588 info->bytes_per_chunk = 2;
589 info->display_endian = info->endian;
590 info->insn_info_valid = 1;
591 info->branch_delay_insns = 0;
592 info->data_size = 0;
593 info->insn_type = dis_nonbranch;
594 info->target = 0;
595 info->target2 = 0;
596
597 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
598 if (status != 0)
599 {
600 (*info->memory_error_func) (status, memaddr, info);
601 return -1;
602 }
603
604 length = 2;
605
606 if (info->endian == BFD_ENDIAN_BIG)
607 insn = bfd_getb16 (buffer);
608 else
609 insn = bfd_getl16 (buffer);
610
611 /* Handle the extend opcode specially. */
612 use_extend = false;
613 if ((insn & 0xf800) == 0xf000)
614 {
615 use_extend = true;
616 extend = insn & 0x7ff;
617
618 memaddr += 2;
619
620 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
621 if (status != 0)
622 {
623 (*info->fprintf_func) (info->stream, "extend 0x%x",
624 (unsigned int) extend);
625 (*info->memory_error_func) (status, memaddr, info);
626 return -1;
627 }
628
629 if (info->endian == BFD_ENDIAN_BIG)
630 insn = bfd_getb16 (buffer);
631 else
632 insn = bfd_getl16 (buffer);
633
634 /* Check for an extend opcode followed by an extend opcode. */
635 if ((insn & 0xf800) == 0xf000)
636 {
637 (*info->fprintf_func) (info->stream, "extend 0x%x",
638 (unsigned int) extend);
639 info->insn_type = dis_noninsn;
640 return length;
641 }
642
643 length += 2;
644 }
645
646 /* FIXME: Should probably use a hash table on the major opcode here. */
647
648 opend = mips16_opcodes + bfd_mips16_num_opcodes;
649 for (op = mips16_opcodes; op < opend; op++)
650 {
651 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
652 {
653 const char *s;
654
655 if (strchr (op->args, 'a') != NULL)
656 {
657 if (use_extend)
658 {
659 (*info->fprintf_func) (info->stream, "extend 0x%x",
660 (unsigned int) extend);
661 info->insn_type = dis_noninsn;
662 return length - 2;
663 }
664
665 use_extend = false;
666
667 memaddr += 2;
668
669 status = (*info->read_memory_func) (memaddr, buffer, 2,
670 info);
671 if (status == 0)
672 {
673 use_extend = true;
674 if (info->endian == BFD_ENDIAN_BIG)
675 extend = bfd_getb16 (buffer);
676 else
677 extend = bfd_getl16 (buffer);
678 length += 2;
679 }
680 }
681
682 (*info->fprintf_func) (info->stream, "%s", op->name);
683 if (op->args[0] != '\0')
684 (*info->fprintf_func) (info->stream, "\t");
685
686 for (s = op->args; *s != '\0'; s++)
687 {
688 if (*s == ','
689 && s[1] == 'w'
690 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
691 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
692 {
693 /* Skip the register and the comma. */
694 ++s;
695 continue;
696 }
697 if (*s == ','
698 && s[1] == 'v'
699 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
700 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
701 {
702 /* Skip the register and the comma. */
703 ++s;
704 continue;
705 }
706 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
707 info);
708 }
709
710 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
711 {
712 info->branch_delay_insns = 1;
713 if (info->insn_type != dis_jsr)
714 info->insn_type = dis_branch;
715 }
716
717 return length;
718 }
719 }
720
721 if (use_extend)
722 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
723 (*info->fprintf_func) (info->stream, "0x%x", insn);
724 info->insn_type = dis_noninsn;
725
726 return length;
727 }
728
729 /* Disassemble an operand for a mips16 instruction. */
730
731 static void
732 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
733 char type;
734 const struct mips_opcode *op;
735 int l;
736 boolean use_extend;
737 int extend;
738 bfd_vma memaddr;
739 struct disassemble_info *info;
740 {
741 switch (type)
742 {
743 case ',':
744 case '(':
745 case ')':
746 (*info->fprintf_func) (info->stream, "%c", type);
747 break;
748
749 case 'y':
750 case 'w':
751 (*info->fprintf_func) (info->stream, "%s",
752 mips16_reg_names[((l >> MIPS16OP_SH_RY)
753 & MIPS16OP_MASK_RY)]);
754 break;
755
756 case 'x':
757 case 'v':
758 (*info->fprintf_func) (info->stream, "%s",
759 mips16_reg_names[((l >> MIPS16OP_SH_RX)
760 & MIPS16OP_MASK_RX)]);
761 break;
762
763 case 'z':
764 (*info->fprintf_func) (info->stream, "%s",
765 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
766 & MIPS16OP_MASK_RZ)]);
767 break;
768
769 case 'Z':
770 (*info->fprintf_func) (info->stream, "%s",
771 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
772 & MIPS16OP_MASK_MOVE32Z)]);
773 break;
774
775 case '0':
776 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
777 break;
778
779 case 'S':
780 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
781 break;
782
783 case 'P':
784 (*info->fprintf_func) (info->stream, "$pc");
785 break;
786
787 case 'R':
788 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
789 break;
790
791 case 'X':
792 (*info->fprintf_func) (info->stream, "%s",
793 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
794 & MIPS16OP_MASK_REGR32)]);
795 break;
796
797 case 'Y':
798 (*info->fprintf_func) (info->stream, "%s",
799 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
800 break;
801
802 case '<':
803 case '>':
804 case '[':
805 case ']':
806 case '4':
807 case '5':
808 case 'H':
809 case 'W':
810 case 'D':
811 case 'j':
812 case '6':
813 case '8':
814 case 'V':
815 case 'C':
816 case 'U':
817 case 'k':
818 case 'K':
819 case 'p':
820 case 'q':
821 case 'A':
822 case 'B':
823 case 'E':
824 {
825 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
826
827 shift = 0;
828 signedp = 0;
829 extbits = 16;
830 pcrel = 0;
831 extu = 0;
832 branch = 0;
833 switch (type)
834 {
835 case '<':
836 nbits = 3;
837 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
838 extbits = 5;
839 extu = 1;
840 break;
841 case '>':
842 nbits = 3;
843 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
844 extbits = 5;
845 extu = 1;
846 break;
847 case '[':
848 nbits = 3;
849 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
850 extbits = 6;
851 extu = 1;
852 break;
853 case ']':
854 nbits = 3;
855 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
856 extbits = 6;
857 extu = 1;
858 break;
859 case '4':
860 nbits = 4;
861 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
862 signedp = 1;
863 extbits = 15;
864 break;
865 case '5':
866 nbits = 5;
867 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
868 info->insn_type = dis_dref;
869 info->data_size = 1;
870 break;
871 case 'H':
872 nbits = 5;
873 shift = 1;
874 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
875 info->insn_type = dis_dref;
876 info->data_size = 2;
877 break;
878 case 'W':
879 nbits = 5;
880 shift = 2;
881 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
882 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
883 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
884 {
885 info->insn_type = dis_dref;
886 info->data_size = 4;
887 }
888 break;
889 case 'D':
890 nbits = 5;
891 shift = 3;
892 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
893 info->insn_type = dis_dref;
894 info->data_size = 8;
895 break;
896 case 'j':
897 nbits = 5;
898 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
899 signedp = 1;
900 break;
901 case '6':
902 nbits = 6;
903 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
904 break;
905 case '8':
906 nbits = 8;
907 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
908 break;
909 case 'V':
910 nbits = 8;
911 shift = 2;
912 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
913 /* FIXME: This might be lw, or it might be addiu to $sp or
914 $pc. We assume it's load. */
915 info->insn_type = dis_dref;
916 info->data_size = 4;
917 break;
918 case 'C':
919 nbits = 8;
920 shift = 3;
921 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
922 info->insn_type = dis_dref;
923 info->data_size = 8;
924 break;
925 case 'U':
926 nbits = 8;
927 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
928 extu = 1;
929 break;
930 case 'k':
931 nbits = 8;
932 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
933 signedp = 1;
934 break;
935 case 'K':
936 nbits = 8;
937 shift = 3;
938 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
939 signedp = 1;
940 break;
941 case 'p':
942 nbits = 8;
943 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
944 signedp = 1;
945 pcrel = 1;
946 branch = 1;
947 info->insn_type = dis_condbranch;
948 break;
949 case 'q':
950 nbits = 11;
951 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
952 signedp = 1;
953 pcrel = 1;
954 branch = 1;
955 info->insn_type = dis_branch;
956 break;
957 case 'A':
958 nbits = 8;
959 shift = 2;
960 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
961 pcrel = 1;
962 /* FIXME: This can be lw or la. We assume it is lw. */
963 info->insn_type = dis_dref;
964 info->data_size = 4;
965 break;
966 case 'B':
967 nbits = 5;
968 shift = 3;
969 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
970 pcrel = 1;
971 info->insn_type = dis_dref;
972 info->data_size = 8;
973 break;
974 case 'E':
975 nbits = 5;
976 shift = 2;
977 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
978 pcrel = 1;
979 break;
980 default:
981 abort ();
982 }
983
984 if (! use_extend)
985 {
986 if (signedp && immed >= (1 << (nbits - 1)))
987 immed -= 1 << nbits;
988 immed <<= shift;
989 if ((type == '<' || type == '>' || type == '[' || type == ']')
990 && immed == 0)
991 immed = 8;
992 }
993 else
994 {
995 if (extbits == 16)
996 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
997 else if (extbits == 15)
998 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
999 else
1000 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1001 immed &= (1 << extbits) - 1;
1002 if (! extu && immed >= (1 << (extbits - 1)))
1003 immed -= 1 << extbits;
1004 }
1005
1006 if (! pcrel)
1007 (*info->fprintf_func) (info->stream, "%d", immed);
1008 else
1009 {
1010 bfd_vma baseaddr;
1011 bfd_vma val;
1012
1013 if (branch)
1014 {
1015 immed *= 2;
1016 baseaddr = memaddr + 2;
1017 }
1018 else if (use_extend)
1019 baseaddr = memaddr - 2;
1020 else
1021 {
1022 int status;
1023 bfd_byte buffer[2];
1024
1025 baseaddr = memaddr;
1026
1027 /* If this instruction is in the delay slot of a jr
1028 instruction, the base address is the address of the
1029 jr instruction. If it is in the delay slot of jalr
1030 instruction, the base address is the address of the
1031 jalr instruction. This test is unreliable: we have
1032 no way of knowing whether the previous word is
1033 instruction or data. */
1034 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1035 info);
1036 if (status == 0
1037 && (((info->endian == BFD_ENDIAN_BIG
1038 ? bfd_getb16 (buffer)
1039 : bfd_getl16 (buffer))
1040 & 0xf800) == 0x1800))
1041 baseaddr = memaddr - 4;
1042 else
1043 {
1044 status = (*info->read_memory_func) (memaddr - 2, buffer,
1045 2, info);
1046 if (status == 0
1047 && (((info->endian == BFD_ENDIAN_BIG
1048 ? bfd_getb16 (buffer)
1049 : bfd_getl16 (buffer))
1050 & 0xf81f) == 0xe800))
1051 baseaddr = memaddr - 2;
1052 }
1053 }
1054 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1055 (*info->print_address_func) (val, info);
1056 info->target = val;
1057 }
1058 }
1059 break;
1060
1061 case 'a':
1062 if (! use_extend)
1063 extend = 0;
1064 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1065 (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
1066 info->insn_type = dis_jsr;
1067 info->target = ((memaddr + 4) & 0xf0000000) | l;
1068 info->branch_delay_insns = 1;
1069 break;
1070
1071 case 'l':
1072 case 'L':
1073 {
1074 int need_comma, amask, smask;
1075
1076 need_comma = 0;
1077
1078 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1079
1080 amask = (l >> 3) & 7;
1081
1082 if (amask > 0 && amask < 5)
1083 {
1084 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1085 if (amask > 1)
1086 (*info->fprintf_func) (info->stream, "-%s",
1087 mips32_reg_names[amask + 3]);
1088 need_comma = 1;
1089 }
1090
1091 smask = (l >> 1) & 3;
1092 if (smask == 3)
1093 {
1094 (*info->fprintf_func) (info->stream, "%s??",
1095 need_comma ? "," : "");
1096 need_comma = 1;
1097 }
1098 else if (smask > 0)
1099 {
1100 (*info->fprintf_func) (info->stream, "%s%s",
1101 need_comma ? "," : "",
1102 mips32_reg_names[16]);
1103 if (smask > 1)
1104 (*info->fprintf_func) (info->stream, "-%s",
1105 mips32_reg_names[smask + 15]);
1106 need_comma = 1;
1107 }
1108
1109 if (l & 1)
1110 {
1111 (*info->fprintf_func) (info->stream, "%s%s",
1112 need_comma ? "," : "",
1113 mips32_reg_names[31]);
1114 need_comma = 1;
1115 }
1116
1117 if (amask == 5 || amask == 6)
1118 {
1119 (*info->fprintf_func) (info->stream, "%s$f0",
1120 need_comma ? "," : "");
1121 if (amask == 6)
1122 (*info->fprintf_func) (info->stream, "-$f1");
1123 }
1124 }
1125 break;
1126
1127 default:
1128 /* xgettext:c-format */
1129 (*info->fprintf_func)
1130 (info->stream,
1131 _("# internal disassembler error, unrecognised modifier (%c)"),
1132 type);
1133 abort ();
1134 }
1135 }