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