Replace bfd_read with bfd_bread.
[binutils.git] / opcodes / mips-dis.c
blob661c179cbea70794828000c9301689869c9cbed5
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).
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 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 *));
58 /* FIXME: These should be shared with gdb somehow. */
60 /* The mips16 register names. */
61 static const char * const mips16_reg_names[] = {
62 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
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"
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"
93 /* Scalar register names. _print_insn_mips() decides which register name
94 table to use. */
95 static const char * const *reg_names = NULL;
97 /* Print insn arguments for 32/64-bit code. */
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;
106 int delta;
108 switch (*d)
110 case ',':
111 case '(':
112 case ')':
113 (*info->fprintf_func) (info->stream, "%c", *d);
114 break;
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;
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;
130 case 'i':
131 case 'u':
132 (*info->fprintf_func) (info->stream, "0x%x",
133 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
134 break;
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;
145 case 'h':
146 (*info->fprintf_func) (info->stream, "0x%x",
147 (unsigned int) ((l >> OP_SH_PREFX)
148 & OP_MASK_PREFX));
149 break;
151 case 'k':
152 (*info->fprintf_func) (info->stream, "0x%x",
153 (unsigned int) ((l >> OP_SH_CACHE)
154 & OP_MASK_CACHE));
155 break;
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;
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;
172 case 'd':
173 (*info->fprintf_func) (info->stream, "%s",
174 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
175 break;
177 case 'U':
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
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]);
199 break;
201 case 'z':
202 (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
203 break;
205 case '<':
206 (*info->fprintf_func) (info->stream, "0x%x",
207 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
208 break;
210 case 'c':
211 (*info->fprintf_func) (info->stream, "0x%x",
212 (l >> OP_SH_CODE) & OP_MASK_CODE);
213 break;
215 case 'q':
216 (*info->fprintf_func) (info->stream, "0x%x",
217 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
218 break;
220 case 'C':
221 (*info->fprintf_func) (info->stream, "0x%x",
222 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
223 break;
225 case 'B':
226 (*info->fprintf_func) (info->stream, "0x%x",
227 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
228 break;
230 case 'J':
231 (*info->fprintf_func) (info->stream, "0x%x",
232 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
233 break;
235 case 'S':
236 case 'V':
237 (*info->fprintf_func) (info->stream, "$f%d",
238 (l >> OP_SH_FS) & OP_MASK_FS);
239 break;
241 case 'T':
242 case 'W':
243 (*info->fprintf_func) (info->stream, "$f%d",
244 (l >> OP_SH_FT) & OP_MASK_FT);
245 break;
247 case 'D':
248 (*info->fprintf_func) (info->stream, "$f%d",
249 (l >> OP_SH_FD) & OP_MASK_FD);
250 break;
252 case 'R':
253 (*info->fprintf_func) (info->stream, "$f%d",
254 (l >> OP_SH_FR) & OP_MASK_FR);
255 break;
257 case 'E':
258 (*info->fprintf_func) (info->stream, "$%d",
259 (l >> OP_SH_RT) & OP_MASK_RT);
260 break;
262 case 'G':
263 (*info->fprintf_func) (info->stream, "$%d",
264 (l >> OP_SH_RD) & OP_MASK_RD);
265 break;
267 case 'N':
268 (*info->fprintf_func) (info->stream, "$fcc%d",
269 (l >> OP_SH_BCC) & OP_MASK_BCC);
270 break;
272 case 'M':
273 (*info->fprintf_func) (info->stream, "$fcc%d",
274 (l >> OP_SH_CCC) & OP_MASK_CCC);
275 break;
277 case 'P':
278 (*info->fprintf_func) (info->stream, "%d",
279 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
280 break;
282 case 'H':
283 (*info->fprintf_func) (info->stream, "%d",
284 (l >> OP_SH_SEL) & OP_MASK_SEL);
285 break;
287 default:
288 /* xgettext:c-format */
289 (*info->fprintf_func) (info->stream,
290 _("# internal error, undefined modifier(%c)"),
291 *d);
292 break;
296 /* Figure out the MIPS ISA and CPU based on the machine number. */
298 static void
299 mips_isa_type (mach, isa, cputype)
300 int mach;
301 int *isa;
302 int *cputype;
304 switch (mach)
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;
393 default:
394 *cputype = CPU_R3000;
395 *isa = ISA_MIPS3;
396 break;
400 /* Check if the object uses NewABI conventions. */
402 static int
403 is_newabi (header)
404 Elf_Internal_Ehdr *header;
406 /* There are no old-style ABIs which use 64-bit ELF. */
407 if (header->e_ident[EI_CLASS] == ELFCLASS64)
408 return 1;
410 /* If a 32-bit ELF file, n32 is a new-style ABI. */
411 if ((header->e_flags & EF_MIPS_ABI2) != 0)
412 return 1;
414 return 0;
417 /* Print the mips instruction at address MEMADDR in debugged memory,
418 on using INFO. Returns length of the instruction, in bytes, which is
419 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
420 this is little-endian code. */
422 static int
423 print_insn_mips (memaddr, word, info)
424 bfd_vma memaddr;
425 unsigned long int word;
426 struct disassemble_info *info;
428 register const struct mips_opcode *op;
429 int target_processor, mips_isa;
430 static boolean init = 0;
431 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
433 /* Build a hash table to shorten the search time. */
434 if (! init)
436 unsigned int i;
438 for (i = 0; i <= OP_MASK_OP; i++)
440 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
442 if (op->pinfo == INSN_MACRO)
443 continue;
444 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
446 mips_hash[i] = op;
447 break;
452 init = 1;
455 #if ! SYMTAB_AVAILABLE
456 /* This is running out on a target machine, not in a host tool.
457 FIXME: Where does mips_target_info come from? */
458 target_processor = mips_target_info.processor;
459 mips_isa = mips_target_info.isa;
460 #else
461 mips_isa_type (info->mach, &mips_isa, &target_processor);
462 #endif
464 info->bytes_per_chunk = INSNLEN;
465 info->display_endian = info->endian;
466 info->insn_info_valid = 1;
467 info->branch_delay_insns = 0;
468 info->data_size = 0;
469 info->insn_type = dis_nonbranch;
470 info->target = 0;
471 info->target2 = 0;
473 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
474 if (op != NULL)
476 for (; op < &mips_opcodes[NUMOPCODES]; op++)
478 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
480 register const char *d;
482 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
483 continue;
485 /* Figure out instruction type and branch delay information. */
486 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
488 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
489 info->insn_type = dis_jsr;
490 else
491 info->insn_type = dis_branch;
492 info->branch_delay_insns = 1;
494 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
495 | INSN_COND_BRANCH_LIKELY)) != 0)
497 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
498 info->insn_type = dis_condjsr;
499 else
500 info->insn_type = dis_condbranch;
501 info->branch_delay_insns = 1;
503 else if ((op->pinfo & (INSN_STORE_MEMORY
504 | INSN_LOAD_MEMORY_DELAY)) != 0)
505 info->insn_type = dis_dref;
507 (*info->fprintf_func) (info->stream, "%s", op->name);
509 d = op->args;
510 if (d != NULL && *d != '\0')
512 (*info->fprintf_func) (info->stream, "\t");
513 for (; *d != '\0'; d++)
514 print_insn_arg (d, word, memaddr, info);
517 return INSNLEN;
522 /* Handle undefined instructions. */
523 info->insn_type = dis_noninsn;
524 (*info->fprintf_func) (info->stream, "0x%x", word);
525 return INSNLEN;
528 /* In an environment where we do not know the symbol type of the
529 instruction we are forced to assume that the low order bit of the
530 instructions' address may mark it as a mips16 instruction. If we
531 are single stepping, or the pc is within the disassembled function,
532 this works. Otherwise, we need a clue. Sometimes. */
534 static int
535 _print_insn_mips (memaddr, info, endianness)
536 bfd_vma memaddr;
537 struct disassemble_info *info;
538 enum bfd_endian endianness;
540 bfd_byte buffer[INSNLEN];
541 int status;
543 #if 1
544 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
545 /* Only a few tools will work this way. */
546 if (memaddr & 0x01)
547 return print_insn_mips16 (memaddr, info);
548 #endif
550 #if SYMTAB_AVAILABLE
551 if (info->mach == 16
552 || (info->flavour == bfd_target_elf_flavour
553 && info->symbols != NULL
554 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
555 == STO_MIPS16)))
556 return print_insn_mips16 (memaddr, info);
557 #endif
559 /* Use mips64_reg_names for new ABI. */
560 reg_names = mips32_reg_names;
562 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
564 Elf_Internal_Ehdr *header;
566 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
567 if (is_newabi (header))
568 reg_names = mips64_reg_names;
571 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
572 if (status == 0)
574 unsigned long insn;
576 if (endianness == BFD_ENDIAN_BIG)
577 insn = (unsigned long) bfd_getb32 (buffer);
578 else
579 insn = (unsigned long) bfd_getl32 (buffer);
581 return print_insn_mips (memaddr, insn, info);
583 else
585 (*info->memory_error_func) (status, memaddr, info);
586 return -1;
591 print_insn_big_mips (memaddr, info)
592 bfd_vma memaddr;
593 struct disassemble_info *info;
595 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
599 print_insn_little_mips (memaddr, info)
600 bfd_vma memaddr;
601 struct disassemble_info *info;
603 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
606 /* Disassemble mips16 instructions. */
608 static int
609 print_insn_mips16 (memaddr, info)
610 bfd_vma memaddr;
611 struct disassemble_info *info;
613 int status;
614 bfd_byte buffer[2];
615 int length;
616 int insn;
617 boolean use_extend;
618 int extend = 0;
619 const struct mips_opcode *op, *opend;
621 info->bytes_per_chunk = 2;
622 info->display_endian = info->endian;
623 info->insn_info_valid = 1;
624 info->branch_delay_insns = 0;
625 info->data_size = 0;
626 info->insn_type = dis_nonbranch;
627 info->target = 0;
628 info->target2 = 0;
630 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
631 if (status != 0)
633 (*info->memory_error_func) (status, memaddr, info);
634 return -1;
637 length = 2;
639 if (info->endian == BFD_ENDIAN_BIG)
640 insn = bfd_getb16 (buffer);
641 else
642 insn = bfd_getl16 (buffer);
644 /* Handle the extend opcode specially. */
645 use_extend = false;
646 if ((insn & 0xf800) == 0xf000)
648 use_extend = true;
649 extend = insn & 0x7ff;
651 memaddr += 2;
653 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
654 if (status != 0)
656 (*info->fprintf_func) (info->stream, "extend 0x%x",
657 (unsigned int) extend);
658 (*info->memory_error_func) (status, memaddr, info);
659 return -1;
662 if (info->endian == BFD_ENDIAN_BIG)
663 insn = bfd_getb16 (buffer);
664 else
665 insn = bfd_getl16 (buffer);
667 /* Check for an extend opcode followed by an extend opcode. */
668 if ((insn & 0xf800) == 0xf000)
670 (*info->fprintf_func) (info->stream, "extend 0x%x",
671 (unsigned int) extend);
672 info->insn_type = dis_noninsn;
673 return length;
676 length += 2;
679 /* FIXME: Should probably use a hash table on the major opcode here. */
681 opend = mips16_opcodes + bfd_mips16_num_opcodes;
682 for (op = mips16_opcodes; op < opend; op++)
684 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
686 const char *s;
688 if (strchr (op->args, 'a') != NULL)
690 if (use_extend)
692 (*info->fprintf_func) (info->stream, "extend 0x%x",
693 (unsigned int) extend);
694 info->insn_type = dis_noninsn;
695 return length - 2;
698 use_extend = false;
700 memaddr += 2;
702 status = (*info->read_memory_func) (memaddr, buffer, 2,
703 info);
704 if (status == 0)
706 use_extend = true;
707 if (info->endian == BFD_ENDIAN_BIG)
708 extend = bfd_getb16 (buffer);
709 else
710 extend = bfd_getl16 (buffer);
711 length += 2;
715 (*info->fprintf_func) (info->stream, "%s", op->name);
716 if (op->args[0] != '\0')
717 (*info->fprintf_func) (info->stream, "\t");
719 for (s = op->args; *s != '\0'; s++)
721 if (*s == ','
722 && s[1] == 'w'
723 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
724 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
726 /* Skip the register and the comma. */
727 ++s;
728 continue;
730 if (*s == ','
731 && s[1] == 'v'
732 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
733 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
735 /* Skip the register and the comma. */
736 ++s;
737 continue;
739 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
740 info);
743 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
745 info->branch_delay_insns = 1;
746 if (info->insn_type != dis_jsr)
747 info->insn_type = dis_branch;
750 return length;
754 if (use_extend)
755 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
756 (*info->fprintf_func) (info->stream, "0x%x", insn);
757 info->insn_type = dis_noninsn;
759 return length;
762 /* Disassemble an operand for a mips16 instruction. */
764 static void
765 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
766 char type;
767 const struct mips_opcode *op;
768 int l;
769 boolean use_extend;
770 int extend;
771 bfd_vma memaddr;
772 struct disassemble_info *info;
774 switch (type)
776 case ',':
777 case '(':
778 case ')':
779 (*info->fprintf_func) (info->stream, "%c", type);
780 break;
782 case 'y':
783 case 'w':
784 (*info->fprintf_func) (info->stream, "%s",
785 mips16_reg_names[((l >> MIPS16OP_SH_RY)
786 & MIPS16OP_MASK_RY)]);
787 break;
789 case 'x':
790 case 'v':
791 (*info->fprintf_func) (info->stream, "%s",
792 mips16_reg_names[((l >> MIPS16OP_SH_RX)
793 & MIPS16OP_MASK_RX)]);
794 break;
796 case 'z':
797 (*info->fprintf_func) (info->stream, "%s",
798 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
799 & MIPS16OP_MASK_RZ)]);
800 break;
802 case 'Z':
803 (*info->fprintf_func) (info->stream, "%s",
804 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
805 & MIPS16OP_MASK_MOVE32Z)]);
806 break;
808 case '0':
809 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
810 break;
812 case 'S':
813 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
814 break;
816 case 'P':
817 (*info->fprintf_func) (info->stream, "$pc");
818 break;
820 case 'R':
821 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
822 break;
824 case 'X':
825 (*info->fprintf_func) (info->stream, "%s",
826 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
827 & MIPS16OP_MASK_REGR32)]);
828 break;
830 case 'Y':
831 (*info->fprintf_func) (info->stream, "%s",
832 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
833 break;
835 case '<':
836 case '>':
837 case '[':
838 case ']':
839 case '4':
840 case '5':
841 case 'H':
842 case 'W':
843 case 'D':
844 case 'j':
845 case '6':
846 case '8':
847 case 'V':
848 case 'C':
849 case 'U':
850 case 'k':
851 case 'K':
852 case 'p':
853 case 'q':
854 case 'A':
855 case 'B':
856 case 'E':
858 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
860 shift = 0;
861 signedp = 0;
862 extbits = 16;
863 pcrel = 0;
864 extu = 0;
865 branch = 0;
866 switch (type)
868 case '<':
869 nbits = 3;
870 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
871 extbits = 5;
872 extu = 1;
873 break;
874 case '>':
875 nbits = 3;
876 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
877 extbits = 5;
878 extu = 1;
879 break;
880 case '[':
881 nbits = 3;
882 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
883 extbits = 6;
884 extu = 1;
885 break;
886 case ']':
887 nbits = 3;
888 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
889 extbits = 6;
890 extu = 1;
891 break;
892 case '4':
893 nbits = 4;
894 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
895 signedp = 1;
896 extbits = 15;
897 break;
898 case '5':
899 nbits = 5;
900 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
901 info->insn_type = dis_dref;
902 info->data_size = 1;
903 break;
904 case 'H':
905 nbits = 5;
906 shift = 1;
907 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
908 info->insn_type = dis_dref;
909 info->data_size = 2;
910 break;
911 case 'W':
912 nbits = 5;
913 shift = 2;
914 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
915 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
916 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
918 info->insn_type = dis_dref;
919 info->data_size = 4;
921 break;
922 case 'D':
923 nbits = 5;
924 shift = 3;
925 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
926 info->insn_type = dis_dref;
927 info->data_size = 8;
928 break;
929 case 'j':
930 nbits = 5;
931 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
932 signedp = 1;
933 break;
934 case '6':
935 nbits = 6;
936 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
937 break;
938 case '8':
939 nbits = 8;
940 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
941 break;
942 case 'V':
943 nbits = 8;
944 shift = 2;
945 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
946 /* FIXME: This might be lw, or it might be addiu to $sp or
947 $pc. We assume it's load. */
948 info->insn_type = dis_dref;
949 info->data_size = 4;
950 break;
951 case 'C':
952 nbits = 8;
953 shift = 3;
954 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
955 info->insn_type = dis_dref;
956 info->data_size = 8;
957 break;
958 case 'U':
959 nbits = 8;
960 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
961 extu = 1;
962 break;
963 case 'k':
964 nbits = 8;
965 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
966 signedp = 1;
967 break;
968 case 'K':
969 nbits = 8;
970 shift = 3;
971 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
972 signedp = 1;
973 break;
974 case 'p':
975 nbits = 8;
976 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
977 signedp = 1;
978 pcrel = 1;
979 branch = 1;
980 info->insn_type = dis_condbranch;
981 break;
982 case 'q':
983 nbits = 11;
984 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
985 signedp = 1;
986 pcrel = 1;
987 branch = 1;
988 info->insn_type = dis_branch;
989 break;
990 case 'A':
991 nbits = 8;
992 shift = 2;
993 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
994 pcrel = 1;
995 /* FIXME: This can be lw or la. We assume it is lw. */
996 info->insn_type = dis_dref;
997 info->data_size = 4;
998 break;
999 case 'B':
1000 nbits = 5;
1001 shift = 3;
1002 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1003 pcrel = 1;
1004 info->insn_type = dis_dref;
1005 info->data_size = 8;
1006 break;
1007 case 'E':
1008 nbits = 5;
1009 shift = 2;
1010 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1011 pcrel = 1;
1012 break;
1013 default:
1014 abort ();
1017 if (! use_extend)
1019 if (signedp && immed >= (1 << (nbits - 1)))
1020 immed -= 1 << nbits;
1021 immed <<= shift;
1022 if ((type == '<' || type == '>' || type == '[' || type == ']')
1023 && immed == 0)
1024 immed = 8;
1026 else
1028 if (extbits == 16)
1029 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1030 else if (extbits == 15)
1031 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1032 else
1033 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1034 immed &= (1 << extbits) - 1;
1035 if (! extu && immed >= (1 << (extbits - 1)))
1036 immed -= 1 << extbits;
1039 if (! pcrel)
1040 (*info->fprintf_func) (info->stream, "%d", immed);
1041 else
1043 bfd_vma baseaddr;
1045 if (branch)
1047 immed *= 2;
1048 baseaddr = memaddr + 2;
1050 else if (use_extend)
1051 baseaddr = memaddr - 2;
1052 else
1054 int status;
1055 bfd_byte buffer[2];
1057 baseaddr = memaddr;
1059 /* If this instruction is in the delay slot of a jr
1060 instruction, the base address is the address of the
1061 jr instruction. If it is in the delay slot of jalr
1062 instruction, the base address is the address of the
1063 jalr instruction. This test is unreliable: we have
1064 no way of knowing whether the previous word is
1065 instruction or data. */
1066 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1067 info);
1068 if (status == 0
1069 && (((info->endian == BFD_ENDIAN_BIG
1070 ? bfd_getb16 (buffer)
1071 : bfd_getl16 (buffer))
1072 & 0xf800) == 0x1800))
1073 baseaddr = memaddr - 4;
1074 else
1076 status = (*info->read_memory_func) (memaddr - 2, buffer,
1077 2, info);
1078 if (status == 0
1079 && (((info->endian == BFD_ENDIAN_BIG
1080 ? bfd_getb16 (buffer)
1081 : bfd_getl16 (buffer))
1082 & 0xf81f) == 0xe800))
1083 baseaddr = memaddr - 2;
1086 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1087 (*info->print_address_func) (info->target, info);
1090 break;
1092 case 'a':
1093 if (! use_extend)
1094 extend = 0;
1095 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1096 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1097 (*info->print_address_func) (info->target, info);
1098 info->insn_type = dis_jsr;
1099 info->branch_delay_insns = 1;
1100 break;
1102 case 'l':
1103 case 'L':
1105 int need_comma, amask, smask;
1107 need_comma = 0;
1109 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1111 amask = (l >> 3) & 7;
1113 if (amask > 0 && amask < 5)
1115 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1116 if (amask > 1)
1117 (*info->fprintf_func) (info->stream, "-%s",
1118 mips32_reg_names[amask + 3]);
1119 need_comma = 1;
1122 smask = (l >> 1) & 3;
1123 if (smask == 3)
1125 (*info->fprintf_func) (info->stream, "%s??",
1126 need_comma ? "," : "");
1127 need_comma = 1;
1129 else if (smask > 0)
1131 (*info->fprintf_func) (info->stream, "%s%s",
1132 need_comma ? "," : "",
1133 mips32_reg_names[16]);
1134 if (smask > 1)
1135 (*info->fprintf_func) (info->stream, "-%s",
1136 mips32_reg_names[smask + 15]);
1137 need_comma = 1;
1140 if (l & 1)
1142 (*info->fprintf_func) (info->stream, "%s%s",
1143 need_comma ? "," : "",
1144 mips32_reg_names[31]);
1145 need_comma = 1;
1148 if (amask == 5 || amask == 6)
1150 (*info->fprintf_func) (info->stream, "%s$f0",
1151 need_comma ? "," : "");
1152 if (amask == 6)
1153 (*info->fprintf_func) (info->stream, "-$f1");
1156 break;
1158 default:
1159 /* xgettext:c-format */
1160 (*info->fprintf_func)
1161 (info->stream,
1162 _("# internal disassembler error, unrecognised modifier (%c)"),
1163 type);
1164 abort ();