[ gas/ChangeLog ]
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 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 case 'O':
288 (*info->fprintf_func) (info->stream, "%d",
289 (l >> OP_SH_ALN) & OP_MASK_ALN);
290 break;
291
292 case 'Q':
293 {
294 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
295 if ((vsel & 0x10) == 0)
296 {
297 int fmt;
298 vsel &= 0x0f;
299 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
300 if ((vsel & 1) == 0)
301 break;
302 (*info->fprintf_func) (info->stream, "$v%d[%d]",
303 (l >> OP_SH_FT) & OP_MASK_FT,
304 vsel >> 1);
305 }
306 else if ((vsel & 0x08) == 0)
307 {
308 (*info->fprintf_func) (info->stream, "$v%d",
309 (l >> OP_SH_FT) & OP_MASK_FT);
310 }
311 else
312 {
313 (*info->fprintf_func) (info->stream, "0x%x",
314 (l >> OP_SH_FT) & OP_MASK_FT);
315 }
316 }
317 break;
318
319 case 'X':
320 (*info->fprintf_func) (info->stream, "$v%d",
321 (l >> OP_SH_FD) & OP_MASK_FD);
322 break;
323
324 case 'Y':
325 (*info->fprintf_func) (info->stream, "$v%d",
326 (l >> OP_SH_FS) & OP_MASK_FS);
327 break;
328
329 case 'Z':
330 (*info->fprintf_func) (info->stream, "$v%d",
331 (l >> OP_SH_FT) & OP_MASK_FT);
332 break;
333
334 default:
335 /* xgettext:c-format */
336 (*info->fprintf_func) (info->stream,
337 _("# internal error, undefined modifier(%c)"),
338 *d);
339 break;
340 }
341 }
342 \f
343 /* Figure out the MIPS ISA and CPU based on the machine number. */
344
345 static void
346 mips_isa_type (mach, isa, cputype)
347 int mach;
348 int *isa;
349 int *cputype;
350 {
351 switch (mach)
352 {
353 case bfd_mach_mips3000:
354 *cputype = CPU_R3000;
355 *isa = ISA_MIPS1;
356 break;
357 case bfd_mach_mips3900:
358 *cputype = CPU_R3900;
359 *isa = ISA_MIPS1;
360 break;
361 case bfd_mach_mips4000:
362 *cputype = CPU_R4000;
363 *isa = ISA_MIPS3;
364 break;
365 case bfd_mach_mips4010:
366 *cputype = CPU_R4010;
367 *isa = ISA_MIPS2;
368 break;
369 case bfd_mach_mips4100:
370 *cputype = CPU_VR4100;
371 *isa = ISA_MIPS3;
372 break;
373 case bfd_mach_mips4111:
374 *cputype = CPU_R4111;
375 *isa = ISA_MIPS3;
376 break;
377 case bfd_mach_mips4300:
378 *cputype = CPU_R4300;
379 *isa = ISA_MIPS3;
380 break;
381 case bfd_mach_mips4400:
382 *cputype = CPU_R4400;
383 *isa = ISA_MIPS3;
384 break;
385 case bfd_mach_mips4600:
386 *cputype = CPU_R4600;
387 *isa = ISA_MIPS3;
388 break;
389 case bfd_mach_mips4650:
390 *cputype = CPU_R4650;
391 *isa = ISA_MIPS3;
392 break;
393 case bfd_mach_mips5000:
394 *cputype = CPU_R5000;
395 *isa = ISA_MIPS4;
396 break;
397 case bfd_mach_mips6000:
398 *cputype = CPU_R6000;
399 *isa = ISA_MIPS2;
400 break;
401 case bfd_mach_mips8000:
402 *cputype = CPU_R8000;
403 *isa = ISA_MIPS4;
404 break;
405 case bfd_mach_mips10000:
406 *cputype = CPU_R10000;
407 *isa = ISA_MIPS4;
408 break;
409 case bfd_mach_mips12000:
410 *cputype = CPU_R12000;
411 *isa = ISA_MIPS4;
412 break;
413 case bfd_mach_mips16:
414 *cputype = CPU_MIPS16;
415 *isa = ISA_MIPS3;
416 break;
417 case bfd_mach_mips5:
418 *cputype = CPU_MIPS5;
419 *isa = ISA_MIPS5;
420 break;
421 case bfd_mach_mips_sb1:
422 *cputype = CPU_SB1;
423 *isa = ISA_MIPS64 | INSN_MIPS3D | INSN_SB1;
424 break;
425 case bfd_mach_mipsisa32:
426 *cputype = CPU_MIPS32;
427 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
428 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
429 _MIPS32 Architecture For Programmers Volume I: Introduction to the
430 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
431 page 1. */
432 *isa = ISA_MIPS32;
433 break;
434 case bfd_mach_mipsisa64:
435 *cputype = CPU_MIPS64;
436 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
437 *isa = ISA_MIPS64 | INSN_MDMX | INSN_MIPS3D;
438 break;
439
440 default:
441 *cputype = CPU_R3000;
442 *isa = ISA_MIPS3;
443 break;
444 }
445 }
446
447 /* Check if the object uses NewABI conventions. */
448
449 static int
450 is_newabi (header)
451 Elf_Internal_Ehdr *header;
452 {
453 /* There are no old-style ABIs which use 64-bit ELF. */
454 if (header->e_ident[EI_CLASS] == ELFCLASS64)
455 return 1;
456
457 /* If a 32-bit ELF file, n32 is a new-style ABI. */
458 if ((header->e_flags & EF_MIPS_ABI2) != 0)
459 return 1;
460
461 return 0;
462 }
463 \f
464 /* Print the mips instruction at address MEMADDR in debugged memory,
465 on using INFO. Returns length of the instruction, in bytes, which is
466 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
467 this is little-endian code. */
468
469 static int
470 print_insn_mips (memaddr, word, info)
471 bfd_vma memaddr;
472 unsigned long int word;
473 struct disassemble_info *info;
474 {
475 register const struct mips_opcode *op;
476 int target_processor, mips_isa;
477 static boolean init = 0;
478 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
479
480 /* Build a hash table to shorten the search time. */
481 if (! init)
482 {
483 unsigned int i;
484
485 for (i = 0; i <= OP_MASK_OP; i++)
486 {
487 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
488 {
489 if (op->pinfo == INSN_MACRO)
490 continue;
491 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
492 {
493 mips_hash[i] = op;
494 break;
495 }
496 }
497 }
498
499 init = 1;
500 }
501
502 #if ! SYMTAB_AVAILABLE
503 /* This is running out on a target machine, not in a host tool.
504 FIXME: Where does mips_target_info come from? */
505 target_processor = mips_target_info.processor;
506 mips_isa = mips_target_info.isa;
507 #else
508 mips_isa_type (info->mach, &mips_isa, &target_processor);
509 #endif
510
511 info->bytes_per_chunk = INSNLEN;
512 info->display_endian = info->endian;
513 info->insn_info_valid = 1;
514 info->branch_delay_insns = 0;
515 info->data_size = 0;
516 info->insn_type = dis_nonbranch;
517 info->target = 0;
518 info->target2 = 0;
519
520 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
521 if (op != NULL)
522 {
523 for (; op < &mips_opcodes[NUMOPCODES]; op++)
524 {
525 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
526 {
527 register const char *d;
528
529 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
530 continue;
531
532 /* Figure out instruction type and branch delay information. */
533 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
534 {
535 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
536 info->insn_type = dis_jsr;
537 else
538 info->insn_type = dis_branch;
539 info->branch_delay_insns = 1;
540 }
541 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
542 | INSN_COND_BRANCH_LIKELY)) != 0)
543 {
544 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
545 info->insn_type = dis_condjsr;
546 else
547 info->insn_type = dis_condbranch;
548 info->branch_delay_insns = 1;
549 }
550 else if ((op->pinfo & (INSN_STORE_MEMORY
551 | INSN_LOAD_MEMORY_DELAY)) != 0)
552 info->insn_type = dis_dref;
553
554 (*info->fprintf_func) (info->stream, "%s", op->name);
555
556 d = op->args;
557 if (d != NULL && *d != '\0')
558 {
559 (*info->fprintf_func) (info->stream, "\t");
560 for (; *d != '\0'; d++)
561 print_insn_arg (d, word, memaddr, info);
562 }
563
564 return INSNLEN;
565 }
566 }
567 }
568
569 /* Handle undefined instructions. */
570 info->insn_type = dis_noninsn;
571 (*info->fprintf_func) (info->stream, "0x%x", word);
572 return INSNLEN;
573 }
574 \f
575 /* In an environment where we do not know the symbol type of the
576 instruction we are forced to assume that the low order bit of the
577 instructions' address may mark it as a mips16 instruction. If we
578 are single stepping, or the pc is within the disassembled function,
579 this works. Otherwise, we need a clue. Sometimes. */
580
581 static int
582 _print_insn_mips (memaddr, info, endianness)
583 bfd_vma memaddr;
584 struct disassemble_info *info;
585 enum bfd_endian endianness;
586 {
587 bfd_byte buffer[INSNLEN];
588 int status;
589
590 #if 1
591 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
592 /* Only a few tools will work this way. */
593 if (memaddr & 0x01)
594 return print_insn_mips16 (memaddr, info);
595 #endif
596
597 #if SYMTAB_AVAILABLE
598 if (info->mach == 16
599 || (info->flavour == bfd_target_elf_flavour
600 && info->symbols != NULL
601 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
602 == STO_MIPS16)))
603 return print_insn_mips16 (memaddr, info);
604 #endif
605
606 /* Use mips64_reg_names for new ABI. */
607 reg_names = mips32_reg_names;
608
609 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
610 {
611 Elf_Internal_Ehdr *header;
612
613 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
614 if (is_newabi (header))
615 reg_names = mips64_reg_names;
616 }
617
618 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
619 if (status == 0)
620 {
621 unsigned long insn;
622
623 if (endianness == BFD_ENDIAN_BIG)
624 insn = (unsigned long) bfd_getb32 (buffer);
625 else
626 insn = (unsigned long) bfd_getl32 (buffer);
627
628 return print_insn_mips (memaddr, insn, info);
629 }
630 else
631 {
632 (*info->memory_error_func) (status, memaddr, info);
633 return -1;
634 }
635 }
636
637 int
638 print_insn_big_mips (memaddr, info)
639 bfd_vma memaddr;
640 struct disassemble_info *info;
641 {
642 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
643 }
644
645 int
646 print_insn_little_mips (memaddr, info)
647 bfd_vma memaddr;
648 struct disassemble_info *info;
649 {
650 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
651 }
652 \f
653 /* Disassemble mips16 instructions. */
654
655 static int
656 print_insn_mips16 (memaddr, info)
657 bfd_vma memaddr;
658 struct disassemble_info *info;
659 {
660 int status;
661 bfd_byte buffer[2];
662 int length;
663 int insn;
664 boolean use_extend;
665 int extend = 0;
666 const struct mips_opcode *op, *opend;
667
668 info->bytes_per_chunk = 2;
669 info->display_endian = info->endian;
670 info->insn_info_valid = 1;
671 info->branch_delay_insns = 0;
672 info->data_size = 0;
673 info->insn_type = dis_nonbranch;
674 info->target = 0;
675 info->target2 = 0;
676
677 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
678 if (status != 0)
679 {
680 (*info->memory_error_func) (status, memaddr, info);
681 return -1;
682 }
683
684 length = 2;
685
686 if (info->endian == BFD_ENDIAN_BIG)
687 insn = bfd_getb16 (buffer);
688 else
689 insn = bfd_getl16 (buffer);
690
691 /* Handle the extend opcode specially. */
692 use_extend = false;
693 if ((insn & 0xf800) == 0xf000)
694 {
695 use_extend = true;
696 extend = insn & 0x7ff;
697
698 memaddr += 2;
699
700 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
701 if (status != 0)
702 {
703 (*info->fprintf_func) (info->stream, "extend 0x%x",
704 (unsigned int) extend);
705 (*info->memory_error_func) (status, memaddr, info);
706 return -1;
707 }
708
709 if (info->endian == BFD_ENDIAN_BIG)
710 insn = bfd_getb16 (buffer);
711 else
712 insn = bfd_getl16 (buffer);
713
714 /* Check for an extend opcode followed by an extend opcode. */
715 if ((insn & 0xf800) == 0xf000)
716 {
717 (*info->fprintf_func) (info->stream, "extend 0x%x",
718 (unsigned int) extend);
719 info->insn_type = dis_noninsn;
720 return length;
721 }
722
723 length += 2;
724 }
725
726 /* FIXME: Should probably use a hash table on the major opcode here. */
727
728 opend = mips16_opcodes + bfd_mips16_num_opcodes;
729 for (op = mips16_opcodes; op < opend; op++)
730 {
731 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
732 {
733 const char *s;
734
735 if (strchr (op->args, 'a') != NULL)
736 {
737 if (use_extend)
738 {
739 (*info->fprintf_func) (info->stream, "extend 0x%x",
740 (unsigned int) extend);
741 info->insn_type = dis_noninsn;
742 return length - 2;
743 }
744
745 use_extend = false;
746
747 memaddr += 2;
748
749 status = (*info->read_memory_func) (memaddr, buffer, 2,
750 info);
751 if (status == 0)
752 {
753 use_extend = true;
754 if (info->endian == BFD_ENDIAN_BIG)
755 extend = bfd_getb16 (buffer);
756 else
757 extend = bfd_getl16 (buffer);
758 length += 2;
759 }
760 }
761
762 (*info->fprintf_func) (info->stream, "%s", op->name);
763 if (op->args[0] != '\0')
764 (*info->fprintf_func) (info->stream, "\t");
765
766 for (s = op->args; *s != '\0'; s++)
767 {
768 if (*s == ','
769 && s[1] == 'w'
770 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
771 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
772 {
773 /* Skip the register and the comma. */
774 ++s;
775 continue;
776 }
777 if (*s == ','
778 && s[1] == 'v'
779 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
780 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
781 {
782 /* Skip the register and the comma. */
783 ++s;
784 continue;
785 }
786 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
787 info);
788 }
789
790 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
791 {
792 info->branch_delay_insns = 1;
793 if (info->insn_type != dis_jsr)
794 info->insn_type = dis_branch;
795 }
796
797 return length;
798 }
799 }
800
801 if (use_extend)
802 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
803 (*info->fprintf_func) (info->stream, "0x%x", insn);
804 info->insn_type = dis_noninsn;
805
806 return length;
807 }
808
809 /* Disassemble an operand for a mips16 instruction. */
810
811 static void
812 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
813 char type;
814 const struct mips_opcode *op;
815 int l;
816 boolean use_extend;
817 int extend;
818 bfd_vma memaddr;
819 struct disassemble_info *info;
820 {
821 switch (type)
822 {
823 case ',':
824 case '(':
825 case ')':
826 (*info->fprintf_func) (info->stream, "%c", type);
827 break;
828
829 case 'y':
830 case 'w':
831 (*info->fprintf_func) (info->stream, "%s",
832 mips16_reg_names[((l >> MIPS16OP_SH_RY)
833 & MIPS16OP_MASK_RY)]);
834 break;
835
836 case 'x':
837 case 'v':
838 (*info->fprintf_func) (info->stream, "%s",
839 mips16_reg_names[((l >> MIPS16OP_SH_RX)
840 & MIPS16OP_MASK_RX)]);
841 break;
842
843 case 'z':
844 (*info->fprintf_func) (info->stream, "%s",
845 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
846 & MIPS16OP_MASK_RZ)]);
847 break;
848
849 case 'Z':
850 (*info->fprintf_func) (info->stream, "%s",
851 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
852 & MIPS16OP_MASK_MOVE32Z)]);
853 break;
854
855 case '0':
856 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
857 break;
858
859 case 'S':
860 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
861 break;
862
863 case 'P':
864 (*info->fprintf_func) (info->stream, "$pc");
865 break;
866
867 case 'R':
868 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
869 break;
870
871 case 'X':
872 (*info->fprintf_func) (info->stream, "%s",
873 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
874 & MIPS16OP_MASK_REGR32)]);
875 break;
876
877 case 'Y':
878 (*info->fprintf_func) (info->stream, "%s",
879 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
880 break;
881
882 case '<':
883 case '>':
884 case '[':
885 case ']':
886 case '4':
887 case '5':
888 case 'H':
889 case 'W':
890 case 'D':
891 case 'j':
892 case '6':
893 case '8':
894 case 'V':
895 case 'C':
896 case 'U':
897 case 'k':
898 case 'K':
899 case 'p':
900 case 'q':
901 case 'A':
902 case 'B':
903 case 'E':
904 {
905 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
906
907 shift = 0;
908 signedp = 0;
909 extbits = 16;
910 pcrel = 0;
911 extu = 0;
912 branch = 0;
913 switch (type)
914 {
915 case '<':
916 nbits = 3;
917 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
918 extbits = 5;
919 extu = 1;
920 break;
921 case '>':
922 nbits = 3;
923 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
924 extbits = 5;
925 extu = 1;
926 break;
927 case '[':
928 nbits = 3;
929 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
930 extbits = 6;
931 extu = 1;
932 break;
933 case ']':
934 nbits = 3;
935 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
936 extbits = 6;
937 extu = 1;
938 break;
939 case '4':
940 nbits = 4;
941 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
942 signedp = 1;
943 extbits = 15;
944 break;
945 case '5':
946 nbits = 5;
947 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
948 info->insn_type = dis_dref;
949 info->data_size = 1;
950 break;
951 case 'H':
952 nbits = 5;
953 shift = 1;
954 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
955 info->insn_type = dis_dref;
956 info->data_size = 2;
957 break;
958 case 'W':
959 nbits = 5;
960 shift = 2;
961 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
962 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
963 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
964 {
965 info->insn_type = dis_dref;
966 info->data_size = 4;
967 }
968 break;
969 case 'D':
970 nbits = 5;
971 shift = 3;
972 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
973 info->insn_type = dis_dref;
974 info->data_size = 8;
975 break;
976 case 'j':
977 nbits = 5;
978 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
979 signedp = 1;
980 break;
981 case '6':
982 nbits = 6;
983 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
984 break;
985 case '8':
986 nbits = 8;
987 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
988 break;
989 case 'V':
990 nbits = 8;
991 shift = 2;
992 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
993 /* FIXME: This might be lw, or it might be addiu to $sp or
994 $pc. We assume it's load. */
995 info->insn_type = dis_dref;
996 info->data_size = 4;
997 break;
998 case 'C':
999 nbits = 8;
1000 shift = 3;
1001 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1002 info->insn_type = dis_dref;
1003 info->data_size = 8;
1004 break;
1005 case 'U':
1006 nbits = 8;
1007 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1008 extu = 1;
1009 break;
1010 case 'k':
1011 nbits = 8;
1012 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1013 signedp = 1;
1014 break;
1015 case 'K':
1016 nbits = 8;
1017 shift = 3;
1018 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1019 signedp = 1;
1020 break;
1021 case 'p':
1022 nbits = 8;
1023 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1024 signedp = 1;
1025 pcrel = 1;
1026 branch = 1;
1027 info->insn_type = dis_condbranch;
1028 break;
1029 case 'q':
1030 nbits = 11;
1031 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1032 signedp = 1;
1033 pcrel = 1;
1034 branch = 1;
1035 info->insn_type = dis_branch;
1036 break;
1037 case 'A':
1038 nbits = 8;
1039 shift = 2;
1040 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1041 pcrel = 1;
1042 /* FIXME: This can be lw or la. We assume it is lw. */
1043 info->insn_type = dis_dref;
1044 info->data_size = 4;
1045 break;
1046 case 'B':
1047 nbits = 5;
1048 shift = 3;
1049 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1050 pcrel = 1;
1051 info->insn_type = dis_dref;
1052 info->data_size = 8;
1053 break;
1054 case 'E':
1055 nbits = 5;
1056 shift = 2;
1057 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1058 pcrel = 1;
1059 break;
1060 default:
1061 abort ();
1062 }
1063
1064 if (! use_extend)
1065 {
1066 if (signedp && immed >= (1 << (nbits - 1)))
1067 immed -= 1 << nbits;
1068 immed <<= shift;
1069 if ((type == '<' || type == '>' || type == '[' || type == ']')
1070 && immed == 0)
1071 immed = 8;
1072 }
1073 else
1074 {
1075 if (extbits == 16)
1076 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1077 else if (extbits == 15)
1078 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1079 else
1080 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1081 immed &= (1 << extbits) - 1;
1082 if (! extu && immed >= (1 << (extbits - 1)))
1083 immed -= 1 << extbits;
1084 }
1085
1086 if (! pcrel)
1087 (*info->fprintf_func) (info->stream, "%d", immed);
1088 else
1089 {
1090 bfd_vma baseaddr;
1091
1092 if (branch)
1093 {
1094 immed *= 2;
1095 baseaddr = memaddr + 2;
1096 }
1097 else if (use_extend)
1098 baseaddr = memaddr - 2;
1099 else
1100 {
1101 int status;
1102 bfd_byte buffer[2];
1103
1104 baseaddr = memaddr;
1105
1106 /* If this instruction is in the delay slot of a jr
1107 instruction, the base address is the address of the
1108 jr instruction. If it is in the delay slot of jalr
1109 instruction, the base address is the address of the
1110 jalr instruction. This test is unreliable: we have
1111 no way of knowing whether the previous word is
1112 instruction or data. */
1113 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1114 info);
1115 if (status == 0
1116 && (((info->endian == BFD_ENDIAN_BIG
1117 ? bfd_getb16 (buffer)
1118 : bfd_getl16 (buffer))
1119 & 0xf800) == 0x1800))
1120 baseaddr = memaddr - 4;
1121 else
1122 {
1123 status = (*info->read_memory_func) (memaddr - 2, buffer,
1124 2, info);
1125 if (status == 0
1126 && (((info->endian == BFD_ENDIAN_BIG
1127 ? bfd_getb16 (buffer)
1128 : bfd_getl16 (buffer))
1129 & 0xf81f) == 0xe800))
1130 baseaddr = memaddr - 2;
1131 }
1132 }
1133 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1134 (*info->print_address_func) (info->target, info);
1135 }
1136 }
1137 break;
1138
1139 case 'a':
1140 if (! use_extend)
1141 extend = 0;
1142 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1143 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1144 (*info->print_address_func) (info->target, info);
1145 info->insn_type = dis_jsr;
1146 info->branch_delay_insns = 1;
1147 break;
1148
1149 case 'l':
1150 case 'L':
1151 {
1152 int need_comma, amask, smask;
1153
1154 need_comma = 0;
1155
1156 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1157
1158 amask = (l >> 3) & 7;
1159
1160 if (amask > 0 && amask < 5)
1161 {
1162 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1163 if (amask > 1)
1164 (*info->fprintf_func) (info->stream, "-%s",
1165 mips32_reg_names[amask + 3]);
1166 need_comma = 1;
1167 }
1168
1169 smask = (l >> 1) & 3;
1170 if (smask == 3)
1171 {
1172 (*info->fprintf_func) (info->stream, "%s??",
1173 need_comma ? "," : "");
1174 need_comma = 1;
1175 }
1176 else if (smask > 0)
1177 {
1178 (*info->fprintf_func) (info->stream, "%s%s",
1179 need_comma ? "," : "",
1180 mips32_reg_names[16]);
1181 if (smask > 1)
1182 (*info->fprintf_func) (info->stream, "-%s",
1183 mips32_reg_names[smask + 15]);
1184 need_comma = 1;
1185 }
1186
1187 if (l & 1)
1188 {
1189 (*info->fprintf_func) (info->stream, "%s%s",
1190 need_comma ? "," : "",
1191 mips32_reg_names[31]);
1192 need_comma = 1;
1193 }
1194
1195 if (amask == 5 || amask == 6)
1196 {
1197 (*info->fprintf_func) (info->stream, "%s$f0",
1198 need_comma ? "," : "");
1199 if (amask == 6)
1200 (*info->fprintf_func) (info->stream, "-$f1");
1201 }
1202 }
1203 break;
1204
1205 default:
1206 /* xgettext:c-format */
1207 (*info->fprintf_func)
1208 (info->stream,
1209 _("# internal disassembler error, unrecognised modifier (%c)"),
1210 type);
1211 abort ();
1212 }
1213 }
This page took 0.05774 seconds and 5 git commands to generate.