/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 | INSN_MIPS16;
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 | INSN_MIPS16;
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_MIPS16 | INSN_MIPS3D | INSN_MDMX;
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 /* We always allow to disassemble the jalx instruction. */
530 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor)
531 && strcmp (op->name, "jalx"))
532 continue;
533
534 /* Figure out instruction type and branch delay information. */
535 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
536 {
537 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
538 info->insn_type = dis_jsr;
539 else
540 info->insn_type = dis_branch;
541 info->branch_delay_insns = 1;
542 }
543 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
544 | INSN_COND_BRANCH_LIKELY)) != 0)
545 {
546 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
547 info->insn_type = dis_condjsr;
548 else
549 info->insn_type = dis_condbranch;
550 info->branch_delay_insns = 1;
551 }
552 else if ((op->pinfo & (INSN_STORE_MEMORY
553 | INSN_LOAD_MEMORY_DELAY)) != 0)
554 info->insn_type = dis_dref;
555
556 (*info->fprintf_func) (info->stream, "%s", op->name);
557
558 d = op->args;
559 if (d != NULL && *d != '\0')
560 {
561 (*info->fprintf_func) (info->stream, "\t");
562 for (; *d != '\0'; d++)
563 print_insn_arg (d, word, memaddr, info);
564 }
565
566 return INSNLEN;
567 }
568 }
569 }
570
571 /* Handle undefined instructions. */
572 info->insn_type = dis_noninsn;
573 (*info->fprintf_func) (info->stream, "0x%x", word);
574 return INSNLEN;
575 }
576 \f
577 /* In an environment where we do not know the symbol type of the
578 instruction we are forced to assume that the low order bit of the
579 instructions' address may mark it as a mips16 instruction. If we
580 are single stepping, or the pc is within the disassembled function,
581 this works. Otherwise, we need a clue. Sometimes. */
582
583 static int
584 _print_insn_mips (memaddr, info, endianness)
585 bfd_vma memaddr;
586 struct disassemble_info *info;
587 enum bfd_endian endianness;
588 {
589 bfd_byte buffer[INSNLEN];
590 int status;
591
592 #if 1
593 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
594 /* Only a few tools will work this way. */
595 if (memaddr & 0x01)
596 return print_insn_mips16 (memaddr, info);
597 #endif
598
599 #if SYMTAB_AVAILABLE
600 if (info->mach == bfd_mach_mips16
601 || (info->flavour == bfd_target_elf_flavour
602 && info->symbols != NULL
603 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
604 == STO_MIPS16)))
605 return print_insn_mips16 (memaddr, info);
606 #endif
607
608 /* Use mips64_reg_names for new ABI. */
609 reg_names = mips32_reg_names;
610
611 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
612 {
613 Elf_Internal_Ehdr *header;
614
615 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
616 if (is_newabi (header))
617 reg_names = mips64_reg_names;
618 }
619
620 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
621 if (status == 0)
622 {
623 unsigned long insn;
624
625 if (endianness == BFD_ENDIAN_BIG)
626 insn = (unsigned long) bfd_getb32 (buffer);
627 else
628 insn = (unsigned long) bfd_getl32 (buffer);
629
630 return print_insn_mips (memaddr, insn, info);
631 }
632 else
633 {
634 (*info->memory_error_func) (status, memaddr, info);
635 return -1;
636 }
637 }
638
639 int
640 print_insn_big_mips (memaddr, info)
641 bfd_vma memaddr;
642 struct disassemble_info *info;
643 {
644 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
645 }
646
647 int
648 print_insn_little_mips (memaddr, info)
649 bfd_vma memaddr;
650 struct disassemble_info *info;
651 {
652 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
653 }
654 \f
655 /* Disassemble mips16 instructions. */
656
657 static int
658 print_insn_mips16 (memaddr, info)
659 bfd_vma memaddr;
660 struct disassemble_info *info;
661 {
662 int status;
663 bfd_byte buffer[2];
664 int length;
665 int insn;
666 boolean use_extend;
667 int extend = 0;
668 const struct mips_opcode *op, *opend;
669
670 info->bytes_per_chunk = 2;
671 info->display_endian = info->endian;
672 info->insn_info_valid = 1;
673 info->branch_delay_insns = 0;
674 info->data_size = 0;
675 info->insn_type = dis_nonbranch;
676 info->target = 0;
677 info->target2 = 0;
678
679 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
680 if (status != 0)
681 {
682 (*info->memory_error_func) (status, memaddr, info);
683 return -1;
684 }
685
686 length = 2;
687
688 if (info->endian == BFD_ENDIAN_BIG)
689 insn = bfd_getb16 (buffer);
690 else
691 insn = bfd_getl16 (buffer);
692
693 /* Handle the extend opcode specially. */
694 use_extend = false;
695 if ((insn & 0xf800) == 0xf000)
696 {
697 use_extend = true;
698 extend = insn & 0x7ff;
699
700 memaddr += 2;
701
702 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
703 if (status != 0)
704 {
705 (*info->fprintf_func) (info->stream, "extend 0x%x",
706 (unsigned int) extend);
707 (*info->memory_error_func) (status, memaddr, info);
708 return -1;
709 }
710
711 if (info->endian == BFD_ENDIAN_BIG)
712 insn = bfd_getb16 (buffer);
713 else
714 insn = bfd_getl16 (buffer);
715
716 /* Check for an extend opcode followed by an extend opcode. */
717 if ((insn & 0xf800) == 0xf000)
718 {
719 (*info->fprintf_func) (info->stream, "extend 0x%x",
720 (unsigned int) extend);
721 info->insn_type = dis_noninsn;
722 return length;
723 }
724
725 length += 2;
726 }
727
728 /* FIXME: Should probably use a hash table on the major opcode here. */
729
730 opend = mips16_opcodes + bfd_mips16_num_opcodes;
731 for (op = mips16_opcodes; op < opend; op++)
732 {
733 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
734 {
735 const char *s;
736
737 if (strchr (op->args, 'a') != NULL)
738 {
739 if (use_extend)
740 {
741 (*info->fprintf_func) (info->stream, "extend 0x%x",
742 (unsigned int) extend);
743 info->insn_type = dis_noninsn;
744 return length - 2;
745 }
746
747 use_extend = false;
748
749 memaddr += 2;
750
751 status = (*info->read_memory_func) (memaddr, buffer, 2,
752 info);
753 if (status == 0)
754 {
755 use_extend = true;
756 if (info->endian == BFD_ENDIAN_BIG)
757 extend = bfd_getb16 (buffer);
758 else
759 extend = bfd_getl16 (buffer);
760 length += 2;
761 }
762 }
763
764 (*info->fprintf_func) (info->stream, "%s", op->name);
765 if (op->args[0] != '\0')
766 (*info->fprintf_func) (info->stream, "\t");
767
768 for (s = op->args; *s != '\0'; s++)
769 {
770 if (*s == ','
771 && s[1] == 'w'
772 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
773 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
774 {
775 /* Skip the register and the comma. */
776 ++s;
777 continue;
778 }
779 if (*s == ','
780 && s[1] == 'v'
781 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
782 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
783 {
784 /* Skip the register and the comma. */
785 ++s;
786 continue;
787 }
788 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
789 info);
790 }
791
792 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
793 {
794 info->branch_delay_insns = 1;
795 if (info->insn_type != dis_jsr)
796 info->insn_type = dis_branch;
797 }
798
799 return length;
800 }
801 }
802
803 if (use_extend)
804 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
805 (*info->fprintf_func) (info->stream, "0x%x", insn);
806 info->insn_type = dis_noninsn;
807
808 return length;
809 }
810
811 /* Disassemble an operand for a mips16 instruction. */
812
813 static void
814 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
815 char type;
816 const struct mips_opcode *op;
817 int l;
818 boolean use_extend;
819 int extend;
820 bfd_vma memaddr;
821 struct disassemble_info *info;
822 {
823 switch (type)
824 {
825 case ',':
826 case '(':
827 case ')':
828 (*info->fprintf_func) (info->stream, "%c", type);
829 break;
830
831 case 'y':
832 case 'w':
833 (*info->fprintf_func) (info->stream, "%s",
834 mips16_reg_names[((l >> MIPS16OP_SH_RY)
835 & MIPS16OP_MASK_RY)]);
836 break;
837
838 case 'x':
839 case 'v':
840 (*info->fprintf_func) (info->stream, "%s",
841 mips16_reg_names[((l >> MIPS16OP_SH_RX)
842 & MIPS16OP_MASK_RX)]);
843 break;
844
845 case 'z':
846 (*info->fprintf_func) (info->stream, "%s",
847 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
848 & MIPS16OP_MASK_RZ)]);
849 break;
850
851 case 'Z':
852 (*info->fprintf_func) (info->stream, "%s",
853 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
854 & MIPS16OP_MASK_MOVE32Z)]);
855 break;
856
857 case '0':
858 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
859 break;
860
861 case 'S':
862 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
863 break;
864
865 case 'P':
866 (*info->fprintf_func) (info->stream, "$pc");
867 break;
868
869 case 'R':
870 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
871 break;
872
873 case 'X':
874 (*info->fprintf_func) (info->stream, "%s",
875 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
876 & MIPS16OP_MASK_REGR32)]);
877 break;
878
879 case 'Y':
880 (*info->fprintf_func) (info->stream, "%s",
881 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
882 break;
883
884 case '<':
885 case '>':
886 case '[':
887 case ']':
888 case '4':
889 case '5':
890 case 'H':
891 case 'W':
892 case 'D':
893 case 'j':
894 case '6':
895 case '8':
896 case 'V':
897 case 'C':
898 case 'U':
899 case 'k':
900 case 'K':
901 case 'p':
902 case 'q':
903 case 'A':
904 case 'B':
905 case 'E':
906 {
907 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
908
909 shift = 0;
910 signedp = 0;
911 extbits = 16;
912 pcrel = 0;
913 extu = 0;
914 branch = 0;
915 switch (type)
916 {
917 case '<':
918 nbits = 3;
919 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
920 extbits = 5;
921 extu = 1;
922 break;
923 case '>':
924 nbits = 3;
925 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
926 extbits = 5;
927 extu = 1;
928 break;
929 case '[':
930 nbits = 3;
931 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
932 extbits = 6;
933 extu = 1;
934 break;
935 case ']':
936 nbits = 3;
937 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
938 extbits = 6;
939 extu = 1;
940 break;
941 case '4':
942 nbits = 4;
943 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
944 signedp = 1;
945 extbits = 15;
946 break;
947 case '5':
948 nbits = 5;
949 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
950 info->insn_type = dis_dref;
951 info->data_size = 1;
952 break;
953 case 'H':
954 nbits = 5;
955 shift = 1;
956 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
957 info->insn_type = dis_dref;
958 info->data_size = 2;
959 break;
960 case 'W':
961 nbits = 5;
962 shift = 2;
963 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
964 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
965 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
966 {
967 info->insn_type = dis_dref;
968 info->data_size = 4;
969 }
970 break;
971 case 'D':
972 nbits = 5;
973 shift = 3;
974 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
975 info->insn_type = dis_dref;
976 info->data_size = 8;
977 break;
978 case 'j':
979 nbits = 5;
980 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
981 signedp = 1;
982 break;
983 case '6':
984 nbits = 6;
985 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
986 break;
987 case '8':
988 nbits = 8;
989 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
990 break;
991 case 'V':
992 nbits = 8;
993 shift = 2;
994 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
995 /* FIXME: This might be lw, or it might be addiu to $sp or
996 $pc. We assume it's load. */
997 info->insn_type = dis_dref;
998 info->data_size = 4;
999 break;
1000 case 'C':
1001 nbits = 8;
1002 shift = 3;
1003 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1004 info->insn_type = dis_dref;
1005 info->data_size = 8;
1006 break;
1007 case 'U':
1008 nbits = 8;
1009 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1010 extu = 1;
1011 break;
1012 case 'k':
1013 nbits = 8;
1014 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1015 signedp = 1;
1016 break;
1017 case 'K':
1018 nbits = 8;
1019 shift = 3;
1020 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1021 signedp = 1;
1022 break;
1023 case 'p':
1024 nbits = 8;
1025 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1026 signedp = 1;
1027 pcrel = 1;
1028 branch = 1;
1029 info->insn_type = dis_condbranch;
1030 break;
1031 case 'q':
1032 nbits = 11;
1033 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1034 signedp = 1;
1035 pcrel = 1;
1036 branch = 1;
1037 info->insn_type = dis_branch;
1038 break;
1039 case 'A':
1040 nbits = 8;
1041 shift = 2;
1042 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1043 pcrel = 1;
1044 /* FIXME: This can be lw or la. We assume it is lw. */
1045 info->insn_type = dis_dref;
1046 info->data_size = 4;
1047 break;
1048 case 'B':
1049 nbits = 5;
1050 shift = 3;
1051 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1052 pcrel = 1;
1053 info->insn_type = dis_dref;
1054 info->data_size = 8;
1055 break;
1056 case 'E':
1057 nbits = 5;
1058 shift = 2;
1059 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1060 pcrel = 1;
1061 break;
1062 default:
1063 abort ();
1064 }
1065
1066 if (! use_extend)
1067 {
1068 if (signedp && immed >= (1 << (nbits - 1)))
1069 immed -= 1 << nbits;
1070 immed <<= shift;
1071 if ((type == '<' || type == '>' || type == '[' || type == ']')
1072 && immed == 0)
1073 immed = 8;
1074 }
1075 else
1076 {
1077 if (extbits == 16)
1078 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1079 else if (extbits == 15)
1080 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1081 else
1082 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1083 immed &= (1 << extbits) - 1;
1084 if (! extu && immed >= (1 << (extbits - 1)))
1085 immed -= 1 << extbits;
1086 }
1087
1088 if (! pcrel)
1089 (*info->fprintf_func) (info->stream, "%d", immed);
1090 else
1091 {
1092 bfd_vma baseaddr;
1093
1094 if (branch)
1095 {
1096 immed *= 2;
1097 baseaddr = memaddr + 2;
1098 }
1099 else if (use_extend)
1100 baseaddr = memaddr - 2;
1101 else
1102 {
1103 int status;
1104 bfd_byte buffer[2];
1105
1106 baseaddr = memaddr;
1107
1108 /* If this instruction is in the delay slot of a jr
1109 instruction, the base address is the address of the
1110 jr instruction. If it is in the delay slot of jalr
1111 instruction, the base address is the address of the
1112 jalr instruction. This test is unreliable: we have
1113 no way of knowing whether the previous word is
1114 instruction or data. */
1115 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1116 info);
1117 if (status == 0
1118 && (((info->endian == BFD_ENDIAN_BIG
1119 ? bfd_getb16 (buffer)
1120 : bfd_getl16 (buffer))
1121 & 0xf800) == 0x1800))
1122 baseaddr = memaddr - 4;
1123 else
1124 {
1125 status = (*info->read_memory_func) (memaddr - 2, buffer,
1126 2, info);
1127 if (status == 0
1128 && (((info->endian == BFD_ENDIAN_BIG
1129 ? bfd_getb16 (buffer)
1130 : bfd_getl16 (buffer))
1131 & 0xf81f) == 0xe800))
1132 baseaddr = memaddr - 2;
1133 }
1134 }
1135 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1136 (*info->print_address_func) (info->target, info);
1137 }
1138 }
1139 break;
1140
1141 case 'a':
1142 if (! use_extend)
1143 extend = 0;
1144 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1145 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1146 (*info->print_address_func) (info->target, info);
1147 info->insn_type = dis_jsr;
1148 info->branch_delay_insns = 1;
1149 break;
1150
1151 case 'l':
1152 case 'L':
1153 {
1154 int need_comma, amask, smask;
1155
1156 need_comma = 0;
1157
1158 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1159
1160 amask = (l >> 3) & 7;
1161
1162 if (amask > 0 && amask < 5)
1163 {
1164 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1165 if (amask > 1)
1166 (*info->fprintf_func) (info->stream, "-%s",
1167 mips32_reg_names[amask + 3]);
1168 need_comma = 1;
1169 }
1170
1171 smask = (l >> 1) & 3;
1172 if (smask == 3)
1173 {
1174 (*info->fprintf_func) (info->stream, "%s??",
1175 need_comma ? "," : "");
1176 need_comma = 1;
1177 }
1178 else if (smask > 0)
1179 {
1180 (*info->fprintf_func) (info->stream, "%s%s",
1181 need_comma ? "," : "",
1182 mips32_reg_names[16]);
1183 if (smask > 1)
1184 (*info->fprintf_func) (info->stream, "-%s",
1185 mips32_reg_names[smask + 15]);
1186 need_comma = 1;
1187 }
1188
1189 if (l & 1)
1190 {
1191 (*info->fprintf_func) (info->stream, "%s%s",
1192 need_comma ? "," : "",
1193 mips32_reg_names[31]);
1194 need_comma = 1;
1195 }
1196
1197 if (amask == 5 || amask == 6)
1198 {
1199 (*info->fprintf_func) (info->stream, "%s$f0",
1200 need_comma ? "," : "");
1201 if (amask == 6)
1202 (*info->fprintf_func) (info->stream, "-$f1");
1203 }
1204 }
1205 break;
1206
1207 default:
1208 /* xgettext:c-format */
1209 (*info->fprintf_func)
1210 (info->stream,
1211 _("# internal disassembler error, unrecognised modifier (%c)"),
1212 type);
1213 abort ();
1214 }
1215 }
This page took 0.066681 seconds and 4 git commands to generate.