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