* ldlex.l: Use #include "" instead of <> for local header files.
[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 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 is a new-style ABI. */
411 if ((header->e_flags & EF_MIPS_ABI2) != 0)
412 return 1;
413
414 return 0;
415 }
416 \f
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. */
421
422 static int
423 print_insn_mips (memaddr, word, info)
424 bfd_vma memaddr;
425 unsigned long int word;
426 struct disassemble_info *info;
427 {
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];
432
433 /* Build a hash table to shorten the search time. */
434 if (! init)
435 {
436 unsigned int i;
437
438 for (i = 0; i <= OP_MASK_OP; i++)
439 {
440 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
441 {
442 if (op->pinfo == INSN_MACRO)
443 continue;
444 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
445 {
446 mips_hash[i] = op;
447 break;
448 }
449 }
450 }
451
452 init = 1;
453 }
454
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
463
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;
472
473 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
474 if (op != NULL)
475 {
476 for (; op < &mips_opcodes[NUMOPCODES]; op++)
477 {
478 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
479 {
480 register const char *d;
481
482 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
483 continue;
484
485 /* Figure out instruction type and branch delay information. */
486 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
487 {
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;
493 }
494 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
495 | INSN_COND_BRANCH_LIKELY)) != 0)
496 {
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;
502 }
503 else if ((op->pinfo & (INSN_STORE_MEMORY
504 | INSN_LOAD_MEMORY_DELAY)) != 0)
505 info->insn_type = dis_dref;
506
507 (*info->fprintf_func) (info->stream, "%s", op->name);
508
509 d = op->args;
510 if (d != NULL && *d != '\0')
511 {
512 (*info->fprintf_func) (info->stream, "\t");
513 for (; *d != '\0'; d++)
514 print_insn_arg (d, word, memaddr, info);
515 }
516
517 return INSNLEN;
518 }
519 }
520 }
521
522 /* Handle undefined instructions. */
523 info->insn_type = dis_noninsn;
524 (*info->fprintf_func) (info->stream, "0x%x", word);
525 return INSNLEN;
526 }
527 \f
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. */
533
534 static int
535 _print_insn_mips (memaddr, info, endianness)
536 bfd_vma memaddr;
537 struct disassemble_info *info;
538 enum bfd_endian endianness;
539 {
540 bfd_byte buffer[INSNLEN];
541 int status;
542
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
549
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
558
559 /* Use mips64_reg_names for new ABI. */
560 reg_names = mips32_reg_names;
561
562 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
563 {
564 Elf_Internal_Ehdr *header;
565
566 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
567 if (is_newabi (header))
568 reg_names = mips64_reg_names;
569 }
570
571 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
572 if (status == 0)
573 {
574 unsigned long insn;
575
576 if (endianness == BFD_ENDIAN_BIG)
577 insn = (unsigned long) bfd_getb32 (buffer);
578 else
579 insn = (unsigned long) bfd_getl32 (buffer);
580
581 return print_insn_mips (memaddr, insn, info);
582 }
583 else
584 {
585 (*info->memory_error_func) (status, memaddr, info);
586 return -1;
587 }
588 }
589
590 int
591 print_insn_big_mips (memaddr, info)
592 bfd_vma memaddr;
593 struct disassemble_info *info;
594 {
595 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
596 }
597
598 int
599 print_insn_little_mips (memaddr, info)
600 bfd_vma memaddr;
601 struct disassemble_info *info;
602 {
603 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
604 }
605 \f
606 /* Disassemble mips16 instructions. */
607
608 static int
609 print_insn_mips16 (memaddr, info)
610 bfd_vma memaddr;
611 struct disassemble_info *info;
612 {
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;
620
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;
629
630 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
631 if (status != 0)
632 {
633 (*info->memory_error_func) (status, memaddr, info);
634 return -1;
635 }
636
637 length = 2;
638
639 if (info->endian == BFD_ENDIAN_BIG)
640 insn = bfd_getb16 (buffer);
641 else
642 insn = bfd_getl16 (buffer);
643
644 /* Handle the extend opcode specially. */
645 use_extend = false;
646 if ((insn & 0xf800) == 0xf000)
647 {
648 use_extend = true;
649 extend = insn & 0x7ff;
650
651 memaddr += 2;
652
653 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
654 if (status != 0)
655 {
656 (*info->fprintf_func) (info->stream, "extend 0x%x",
657 (unsigned int) extend);
658 (*info->memory_error_func) (status, memaddr, info);
659 return -1;
660 }
661
662 if (info->endian == BFD_ENDIAN_BIG)
663 insn = bfd_getb16 (buffer);
664 else
665 insn = bfd_getl16 (buffer);
666
667 /* Check for an extend opcode followed by an extend opcode. */
668 if ((insn & 0xf800) == 0xf000)
669 {
670 (*info->fprintf_func) (info->stream, "extend 0x%x",
671 (unsigned int) extend);
672 info->insn_type = dis_noninsn;
673 return length;
674 }
675
676 length += 2;
677 }
678
679 /* FIXME: Should probably use a hash table on the major opcode here. */
680
681 opend = mips16_opcodes + bfd_mips16_num_opcodes;
682 for (op = mips16_opcodes; op < opend; op++)
683 {
684 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
685 {
686 const char *s;
687
688 if (strchr (op->args, 'a') != NULL)
689 {
690 if (use_extend)
691 {
692 (*info->fprintf_func) (info->stream, "extend 0x%x",
693 (unsigned int) extend);
694 info->insn_type = dis_noninsn;
695 return length - 2;
696 }
697
698 use_extend = false;
699
700 memaddr += 2;
701
702 status = (*info->read_memory_func) (memaddr, buffer, 2,
703 info);
704 if (status == 0)
705 {
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;
712 }
713 }
714
715 (*info->fprintf_func) (info->stream, "%s", op->name);
716 if (op->args[0] != '\0')
717 (*info->fprintf_func) (info->stream, "\t");
718
719 for (s = op->args; *s != '\0'; s++)
720 {
721 if (*s == ','
722 && s[1] == 'w'
723 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
724 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
725 {
726 /* Skip the register and the comma. */
727 ++s;
728 continue;
729 }
730 if (*s == ','
731 && s[1] == 'v'
732 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
733 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
734 {
735 /* Skip the register and the comma. */
736 ++s;
737 continue;
738 }
739 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
740 info);
741 }
742
743 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
744 {
745 info->branch_delay_insns = 1;
746 if (info->insn_type != dis_jsr)
747 info->insn_type = dis_branch;
748 }
749
750 return length;
751 }
752 }
753
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;
758
759 return length;
760 }
761
762 /* Disassemble an operand for a mips16 instruction. */
763
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;
773 {
774 switch (type)
775 {
776 case ',':
777 case '(':
778 case ')':
779 (*info->fprintf_func) (info->stream, "%c", type);
780 break;
781
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;
788
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;
795
796 case 'z':
797 (*info->fprintf_func) (info->stream, "%s",
798 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
799 & MIPS16OP_MASK_RZ)]);
800 break;
801
802 case 'Z':
803 (*info->fprintf_func) (info->stream, "%s",
804 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
805 & MIPS16OP_MASK_MOVE32Z)]);
806 break;
807
808 case '0':
809 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
810 break;
811
812 case 'S':
813 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
814 break;
815
816 case 'P':
817 (*info->fprintf_func) (info->stream, "$pc");
818 break;
819
820 case 'R':
821 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
822 break;
823
824 case 'X':
825 (*info->fprintf_func) (info->stream, "%s",
826 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
827 & MIPS16OP_MASK_REGR32)]);
828 break;
829
830 case 'Y':
831 (*info->fprintf_func) (info->stream, "%s",
832 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
833 break;
834
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':
857 {
858 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
859
860 shift = 0;
861 signedp = 0;
862 extbits = 16;
863 pcrel = 0;
864 extu = 0;
865 branch = 0;
866 switch (type)
867 {
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)
917 {
918 info->insn_type = dis_dref;
919 info->data_size = 4;
920 }
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 ();
1015 }
1016
1017 if (! use_extend)
1018 {
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;
1025 }
1026 else
1027 {
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;
1037 }
1038
1039 if (! pcrel)
1040 (*info->fprintf_func) (info->stream, "%d", immed);
1041 else
1042 {
1043 bfd_vma baseaddr;
1044
1045 if (branch)
1046 {
1047 immed *= 2;
1048 baseaddr = memaddr + 2;
1049 }
1050 else if (use_extend)
1051 baseaddr = memaddr - 2;
1052 else
1053 {
1054 int status;
1055 bfd_byte buffer[2];
1056
1057 baseaddr = memaddr;
1058
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
1075 {
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;
1084 }
1085 }
1086 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1087 (*info->print_address_func) (info->target, info);
1088 }
1089 }
1090 break;
1091
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;
1101
1102 case 'l':
1103 case 'L':
1104 {
1105 int need_comma, amask, smask;
1106
1107 need_comma = 0;
1108
1109 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1110
1111 amask = (l >> 3) & 7;
1112
1113 if (amask > 0 && amask < 5)
1114 {
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;
1120 }
1121
1122 smask = (l >> 1) & 3;
1123 if (smask == 3)
1124 {
1125 (*info->fprintf_func) (info->stream, "%s??",
1126 need_comma ? "," : "");
1127 need_comma = 1;
1128 }
1129 else if (smask > 0)
1130 {
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;
1138 }
1139
1140 if (l & 1)
1141 {
1142 (*info->fprintf_func) (info->stream, "%s%s",
1143 need_comma ? "," : "",
1144 mips32_reg_names[31]);
1145 need_comma = 1;
1146 }
1147
1148 if (amask == 5 || amask == 6)
1149 {
1150 (*info->fprintf_func) (info->stream, "%s$f0",
1151 need_comma ? "," : "");
1152 if (amask == 6)
1153 (*info->fprintf_func) (info->stream, "-$f1");
1154 }
1155 }
1156 break;
1157
1158 default:
1159 /* xgettext:c-format */
1160 (*info->fprintf_func)
1161 (info->stream,
1162 _("# internal disassembler error, unrecognised modifier (%c)"),
1163 type);
1164 abort ();
1165 }
1166 }
This page took 0.053231 seconds and 4 git commands to generate.