Fix MIPS disassembler so that it produces reassemblable code.
[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 int print_insn_mips16
49 PARAMS ((bfd_vma, struct disassemble_info *));
50 static void print_mips16_insn_arg
51 PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
52 struct disassemble_info *));
53 \f
54 /* FIXME: These should be shared with gdb somehow. */
55
56 /* The mips16 register names. */
57 static const char * const mips16_reg_names[] =
58 {
59 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
60 };
61
62 static const char * const mips32_reg_names[] =
63 {
64 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
65 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
66 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
67 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
68 "sr", "lo", "hi", "bad", "cause", "pc",
69 "fv0", "$f1", "fv1", "$f3", "ft0", "$f5", "ft1", "$f7",
70 "ft2", "$f9", "ft3", "$f11", "fa0", "$f13", "fa1", "$f15",
71 "ft4", "f17", "ft5", "f19", "fs0", "f21", "fs1", "f23",
72 "fs2", "$f25", "fs3", "$f27", "fs4", "$f29", "fs5", "$f31",
73 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
74 "epc", "prid"
75 };
76
77 static const char * const mips64_reg_names[] =
78 {
79 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
80 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
81 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
82 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
83 "sr", "lo", "hi", "bad", "cause", "pc",
84 "fv0", "$f1", "fv1", "$f3", "ft0", "ft1", "ft2", "ft3",
85 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
86 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
87 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
88 "fsr", "fir", "fp", "inx", "rand", "tlblo", "ctxt", "tlbhi",
89 "epc", "prid"
90 };
91
92 /* Scalar register names. _print_insn_mips() decides which register name
93 table to use. */
94 static const char * const *reg_names = NULL;
95 \f
96 /* Print insn arguments for 32/64-bit code */
97
98 static void
99 print_insn_arg (d, l, pc, info)
100 const char *d;
101 register unsigned long int l;
102 bfd_vma pc;
103 struct disassemble_info *info;
104 {
105 int delta;
106
107 switch (*d)
108 {
109 case ',':
110 case '(':
111 case ')':
112 (*info->fprintf_func) (info->stream, "%c", *d);
113 break;
114
115 case 's':
116 case 'b':
117 case 'r':
118 case 'v':
119 (*info->fprintf_func) (info->stream, "%s",
120 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
121 break;
122
123 case 't':
124 case 'w':
125 (*info->fprintf_func) (info->stream, "%s",
126 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
127 break;
128
129 case 'i':
130 case 'u':
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
133 break;
134
135 case 'j': /* same as i, but sign-extended */
136 case 'o':
137 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
138 if (delta & 0x8000)
139 delta |= ~0xffff;
140 (*info->fprintf_func) (info->stream, "%d",
141 delta);
142 break;
143
144 case 'h':
145 (*info->fprintf_func) (info->stream, "0x%x",
146 (unsigned int) ((l >> OP_SH_PREFX)
147 & OP_MASK_PREFX));
148 break;
149
150 case 'k':
151 (*info->fprintf_func) (info->stream, "0x%x",
152 (unsigned int) ((l >> OP_SH_CACHE)
153 & OP_MASK_CACHE));
154 break;
155
156 case 'a':
157 (*info->print_address_func)
158 ((((pc + 4) & ~ (bfd_vma) 0x0fffffff)
159 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
160 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->print_address_func)
169 ((delta << 2) + pc + INSNLEN,
170 info);
171 break;
172
173 case 'd':
174 (*info->fprintf_func) (info->stream, "%s",
175 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
176 break;
177
178 case 'U':
179 {
180 /* First check for both rd and rt being equal. */
181 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
182 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
183 (*info->fprintf_func) (info->stream, "%s",
184 reg_names[reg]);
185 else
186 {
187 /* If one is zero use the other. */
188 if (reg == 0)
189 (*info->fprintf_func) (info->stream, "%s",
190 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
191 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
192 (*info->fprintf_func) (info->stream, "%s",
193 reg_names[reg]);
194 else /* Bogus, result depends on processor. */
195 (*info->fprintf_func) (info->stream, "%s or %s",
196 reg_names[reg],
197 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
198 }
199 }
200 break;
201
202 case 'z':
203 (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
204 break;
205
206 case '<':
207 (*info->fprintf_func) (info->stream, "0x%x",
208 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
209 break;
210
211 case 'c':
212 (*info->fprintf_func) (info->stream, "0x%x",
213 (l >> OP_SH_CODE) & OP_MASK_CODE);
214 break;
215
216 case 'q':
217 (*info->fprintf_func) (info->stream, "0x%x",
218 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
219 break;
220
221 case 'C':
222 (*info->fprintf_func) (info->stream, "0x%x",
223 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
224 break;
225
226 case 'B':
227 (*info->fprintf_func) (info->stream, "0x%x",
228 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
229 break;
230
231 case 'J':
232 (*info->fprintf_func) (info->stream, "0x%x",
233 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
234 break;
235
236 case 'S':
237 case 'V':
238 (*info->fprintf_func) (info->stream, "$f%d",
239 (l >> OP_SH_FS) & OP_MASK_FS);
240 break;
241
242 case 'T':
243 case 'W':
244 (*info->fprintf_func) (info->stream, "$f%d",
245 (l >> OP_SH_FT) & OP_MASK_FT);
246 break;
247
248 case 'D':
249 (*info->fprintf_func) (info->stream, "$f%d",
250 (l >> OP_SH_FD) & OP_MASK_FD);
251 break;
252
253 case 'R':
254 (*info->fprintf_func) (info->stream, "$f%d",
255 (l >> OP_SH_FR) & OP_MASK_FR);
256 break;
257
258 case 'E':
259 (*info->fprintf_func) (info->stream, "%s",
260 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
261 break;
262
263 case 'G':
264 (*info->fprintf_func) (info->stream, "%s",
265 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
266 break;
267
268 case 'N':
269 (*info->fprintf_func) (info->stream, "$fcc%d",
270 (l >> OP_SH_BCC) & OP_MASK_BCC);
271 break;
272
273 case 'M':
274 (*info->fprintf_func) (info->stream, "$fcc%d",
275 (l >> OP_SH_CCC) & OP_MASK_CCC);
276 break;
277
278 case 'P':
279 (*info->fprintf_func) (info->stream, "%d",
280 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
281 break;
282
283 case 'H':
284 (*info->fprintf_func) (info->stream, "%d",
285 (l >> OP_SH_SEL) & OP_MASK_SEL);
286 break;
287
288 default:
289 /* xgettext:c-format */
290 (*info->fprintf_func) (info->stream,
291 _("# internal error, undefined modifier(%c)"),
292 *d);
293 break;
294 }
295 }
296 \f
297 /* Figure out the MIPS ISA and CPU based on the machine number. */
298
299 static void
300 mips_isa_type (mach, isa, cputype)
301 int mach;
302 int *isa;
303 int *cputype;
304 {
305 switch (mach)
306 {
307 case bfd_mach_mips3000:
308 *cputype = CPU_R3000;
309 *isa = ISA_MIPS1;
310 break;
311 case bfd_mach_mips3900:
312 *cputype = CPU_R3900;
313 *isa = ISA_MIPS1;
314 break;
315 case bfd_mach_mips4000:
316 *cputype = CPU_R4000;
317 *isa = ISA_MIPS3;
318 break;
319 case bfd_mach_mips4010:
320 *cputype = CPU_R4010;
321 *isa = ISA_MIPS2;
322 break;
323 case bfd_mach_mips4100:
324 *cputype = CPU_VR4100;
325 *isa = ISA_MIPS3;
326 break;
327 case bfd_mach_mips4111:
328 *cputype = CPU_R4111;
329 *isa = ISA_MIPS3;
330 break;
331 case bfd_mach_mips4300:
332 *cputype = CPU_R4300;
333 *isa = ISA_MIPS3;
334 break;
335 case bfd_mach_mips4400:
336 *cputype = CPU_R4400;
337 *isa = ISA_MIPS3;
338 break;
339 case bfd_mach_mips4600:
340 *cputype = CPU_R4600;
341 *isa = ISA_MIPS3;
342 break;
343 case bfd_mach_mips4650:
344 *cputype = CPU_R4650;
345 *isa = ISA_MIPS3;
346 break;
347 case bfd_mach_mips5000:
348 *cputype = CPU_R5000;
349 *isa = ISA_MIPS4;
350 break;
351 case bfd_mach_mips6000:
352 *cputype = CPU_R6000;
353 *isa = ISA_MIPS2;
354 break;
355 case bfd_mach_mips8000:
356 *cputype = CPU_R8000;
357 *isa = ISA_MIPS4;
358 break;
359 case bfd_mach_mips10000:
360 *cputype = CPU_R10000;
361 *isa = ISA_MIPS4;
362 break;
363 case bfd_mach_mips16:
364 *cputype = CPU_MIPS16;
365 *isa = ISA_MIPS3;
366 break;
367 case bfd_mach_mips32:
368 *cputype = CPU_MIPS32;
369 *isa = ISA_MIPS32;
370 break;
371 case bfd_mach_mips32_4k:
372 *cputype = CPU_MIPS32_4K;
373 *isa = ISA_MIPS32;
374 break;
375 case bfd_mach_mips5:
376 *cputype = CPU_MIPS5;
377 *isa = ISA_MIPS5;
378 break;
379 case bfd_mach_mips64:
380 *cputype = CPU_MIPS64;
381 *isa = ISA_MIPS64;
382 break;
383 case bfd_mach_mips_sb1:
384 *cputype = CPU_SB1;
385 *isa = ISA_MIPS64;
386 break;
387 default:
388 *cputype = CPU_R3000;
389 *isa = ISA_MIPS3;
390 break;
391 }
392 }
393
394 /* Figure out ISA from disassemble_info data */
395
396 static int
397 get_mips_isa (info)
398 struct disassemble_info *info;
399 {
400 int isa;
401 int cpu;
402
403 mips_isa_type (info->mach, &isa, &cpu);
404 return isa;
405 }
406 \f
407 /* Print the mips instruction at address MEMADDR in debugged memory,
408 on using INFO. Returns length of the instruction, in bytes, which is
409 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
410 this is little-endian code. */
411
412 static int
413 print_insn_mips (memaddr, word, info)
414 bfd_vma memaddr;
415 unsigned long int word;
416 struct disassemble_info *info;
417 {
418 register const struct mips_opcode *op;
419 int target_processor, mips_isa;
420 static boolean init = 0;
421 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
422
423 /* Build a hash table to shorten the search time. */
424 if (! init)
425 {
426 unsigned int i;
427
428 for (i = 0; i <= OP_MASK_OP; i++)
429 {
430 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
431 {
432 if (op->pinfo == INSN_MACRO)
433 continue;
434 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
435 {
436 mips_hash[i] = op;
437 break;
438 }
439 }
440 }
441
442 init = 1;
443 }
444
445 #if ! SYMTAB_AVAILABLE
446 /* This is running out on a target machine, not in a host tool.
447 FIXME: Where does mips_target_info come from? */
448 target_processor = mips_target_info.processor;
449 mips_isa = mips_target_info.isa;
450 #else
451 mips_isa_type (info->mach, &mips_isa, &target_processor);
452 #endif
453
454 info->bytes_per_chunk = INSNLEN;
455 info->display_endian = info->endian;
456
457 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
458 if (op != NULL)
459 {
460 for (; op < &mips_opcodes[NUMOPCODES]; op++)
461 {
462 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
463 {
464 register const char *d;
465
466 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
467 continue;
468
469 (*info->fprintf_func) (info->stream, "%s", op->name);
470
471 d = op->args;
472 if (d != NULL && *d != '\0')
473 {
474 (*info->fprintf_func) (info->stream, "\t");
475 for (; *d != '\0'; d++)
476 print_insn_arg (d, word, memaddr, info);
477 }
478
479 return INSNLEN;
480 }
481 }
482 }
483
484 /* Handle undefined instructions. */
485 (*info->fprintf_func) (info->stream, "0x%x", word);
486 return INSNLEN;
487 }
488 \f
489 /* In an environment where we do not know the symbol type of the
490 instruction we are forced to assume that the low order bit of the
491 instructions' address may mark it as a mips16 instruction. If we
492 are single stepping, or the pc is within the disassembled function,
493 this works. Otherwise, we need a clue. Sometimes. */
494
495 static int
496 _print_insn_mips (memaddr, info, endianness)
497 bfd_vma memaddr;
498 struct disassemble_info *info;
499 enum bfd_endian endianness;
500 {
501 bfd_byte buffer[INSNLEN];
502 int status;
503
504 #if 1
505 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
506 /* Only a few tools will work this way. */
507 if (memaddr & 0x01)
508 return print_insn_mips16 (memaddr, info);
509 #endif
510
511 #if SYMTAB_AVAILABLE
512 if (info->mach == 16
513 || (info->flavour == bfd_target_elf_flavour
514 && info->symbols != NULL
515 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
516 == STO_MIPS16)))
517 return print_insn_mips16 (memaddr, info);
518 #endif
519
520 /* Use mips64_reg_names for new ABI. */
521 if (info->flavour == bfd_target_elf_flavour
522 && info->symbols != NULL
523 && (((get_mips_isa(info) | INSN_ISA_MASK) & ISA_MIPS2) != 0)
524 && ((elf_elfheader (bfd_asymbol_bfd(*(info->symbols)))->e_flags
525 & EF_MIPS_ABI2) != 0))
526 reg_names = mips64_reg_names;
527 else
528 reg_names = mips32_reg_names;
529
530 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
531 if (status == 0)
532 {
533 unsigned long insn;
534
535 if (endianness == BFD_ENDIAN_BIG)
536 insn = (unsigned long) bfd_getb32 (buffer);
537 else
538 insn = (unsigned long) bfd_getl32 (buffer);
539
540 return print_insn_mips (memaddr, insn, info);
541 }
542 else
543 {
544 (*info->memory_error_func) (status, memaddr, info);
545 return -1;
546 }
547 }
548
549 int
550 print_insn_big_mips (memaddr, info)
551 bfd_vma memaddr;
552 struct disassemble_info *info;
553 {
554 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
555 }
556
557 int
558 print_insn_little_mips (memaddr, info)
559 bfd_vma memaddr;
560 struct disassemble_info *info;
561 {
562 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
563 }
564 \f
565 /* Disassemble mips16 instructions. */
566
567 static int
568 print_insn_mips16 (memaddr, info)
569 bfd_vma memaddr;
570 struct disassemble_info *info;
571 {
572 int status;
573 bfd_byte buffer[2];
574 int length;
575 int insn;
576 boolean use_extend;
577 int extend = 0;
578 const struct mips_opcode *op, *opend;
579
580 info->bytes_per_chunk = 2;
581 info->display_endian = info->endian;
582 info->insn_info_valid = 1;
583 info->branch_delay_insns = 0;
584 info->data_size = 0;
585 info->insn_type = dis_nonbranch;
586 info->target = 0;
587 info->target2 = 0;
588
589 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
590 if (status != 0)
591 {
592 (*info->memory_error_func) (status, memaddr, info);
593 return -1;
594 }
595
596 length = 2;
597
598 if (info->endian == BFD_ENDIAN_BIG)
599 insn = bfd_getb16 (buffer);
600 else
601 insn = bfd_getl16 (buffer);
602
603 /* Handle the extend opcode specially. */
604 use_extend = false;
605 if ((insn & 0xf800) == 0xf000)
606 {
607 use_extend = true;
608 extend = insn & 0x7ff;
609
610 memaddr += 2;
611
612 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
613 if (status != 0)
614 {
615 (*info->fprintf_func) (info->stream, "extend 0x%x",
616 (unsigned int) extend);
617 (*info->memory_error_func) (status, memaddr, info);
618 return -1;
619 }
620
621 if (info->endian == BFD_ENDIAN_BIG)
622 insn = bfd_getb16 (buffer);
623 else
624 insn = bfd_getl16 (buffer);
625
626 /* Check for an extend opcode followed by an extend opcode. */
627 if ((insn & 0xf800) == 0xf000)
628 {
629 (*info->fprintf_func) (info->stream, "extend 0x%x",
630 (unsigned int) extend);
631 info->insn_type = dis_noninsn;
632 return length;
633 }
634
635 length += 2;
636 }
637
638 /* FIXME: Should probably use a hash table on the major opcode here. */
639
640 opend = mips16_opcodes + bfd_mips16_num_opcodes;
641 for (op = mips16_opcodes; op < opend; op++)
642 {
643 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
644 {
645 const char *s;
646
647 if (strchr (op->args, 'a') != NULL)
648 {
649 if (use_extend)
650 {
651 (*info->fprintf_func) (info->stream, "extend 0x%x",
652 (unsigned int) extend);
653 info->insn_type = dis_noninsn;
654 return length - 2;
655 }
656
657 use_extend = false;
658
659 memaddr += 2;
660
661 status = (*info->read_memory_func) (memaddr, buffer, 2,
662 info);
663 if (status == 0)
664 {
665 use_extend = true;
666 if (info->endian == BFD_ENDIAN_BIG)
667 extend = bfd_getb16 (buffer);
668 else
669 extend = bfd_getl16 (buffer);
670 length += 2;
671 }
672 }
673
674 (*info->fprintf_func) (info->stream, "%s", op->name);
675 if (op->args[0] != '\0')
676 (*info->fprintf_func) (info->stream, "\t");
677
678 for (s = op->args; *s != '\0'; s++)
679 {
680 if (*s == ','
681 && s[1] == 'w'
682 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
683 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
684 {
685 /* Skip the register and the comma. */
686 ++s;
687 continue;
688 }
689 if (*s == ','
690 && s[1] == 'v'
691 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
692 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
693 {
694 /* Skip the register and the comma. */
695 ++s;
696 continue;
697 }
698 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
699 info);
700 }
701
702 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
703 {
704 info->branch_delay_insns = 1;
705 if (info->insn_type != dis_jsr)
706 info->insn_type = dis_branch;
707 }
708
709 return length;
710 }
711 }
712
713 if (use_extend)
714 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
715 (*info->fprintf_func) (info->stream, "0x%x", insn);
716 info->insn_type = dis_noninsn;
717
718 return length;
719 }
720
721 /* Disassemble an operand for a mips16 instruction. */
722
723 static void
724 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
725 char type;
726 const struct mips_opcode *op;
727 int l;
728 boolean use_extend;
729 int extend;
730 bfd_vma memaddr;
731 struct disassemble_info *info;
732 {
733 switch (type)
734 {
735 case ',':
736 case '(':
737 case ')':
738 (*info->fprintf_func) (info->stream, "%c", type);
739 break;
740
741 case 'y':
742 case 'w':
743 (*info->fprintf_func) (info->stream, "%s",
744 mips16_reg_names[((l >> MIPS16OP_SH_RY)
745 & MIPS16OP_MASK_RY)]);
746 break;
747
748 case 'x':
749 case 'v':
750 (*info->fprintf_func) (info->stream, "%s",
751 mips16_reg_names[((l >> MIPS16OP_SH_RX)
752 & MIPS16OP_MASK_RX)]);
753 break;
754
755 case 'z':
756 (*info->fprintf_func) (info->stream, "%s",
757 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
758 & MIPS16OP_MASK_RZ)]);
759 break;
760
761 case 'Z':
762 (*info->fprintf_func) (info->stream, "%s",
763 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
764 & MIPS16OP_MASK_MOVE32Z)]);
765 break;
766
767 case '0':
768 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
769 break;
770
771 case 'S':
772 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
773 break;
774
775 case 'P':
776 (*info->fprintf_func) (info->stream, "$pc");
777 break;
778
779 case 'R':
780 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
781 break;
782
783 case 'X':
784 (*info->fprintf_func) (info->stream, "%s",
785 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
786 & MIPS16OP_MASK_REGR32)]);
787 break;
788
789 case 'Y':
790 (*info->fprintf_func) (info->stream, "%s",
791 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
792 break;
793
794 case '<':
795 case '>':
796 case '[':
797 case ']':
798 case '4':
799 case '5':
800 case 'H':
801 case 'W':
802 case 'D':
803 case 'j':
804 case '6':
805 case '8':
806 case 'V':
807 case 'C':
808 case 'U':
809 case 'k':
810 case 'K':
811 case 'p':
812 case 'q':
813 case 'A':
814 case 'B':
815 case 'E':
816 {
817 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
818
819 shift = 0;
820 signedp = 0;
821 extbits = 16;
822 pcrel = 0;
823 extu = 0;
824 branch = 0;
825 switch (type)
826 {
827 case '<':
828 nbits = 3;
829 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
830 extbits = 5;
831 extu = 1;
832 break;
833 case '>':
834 nbits = 3;
835 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
836 extbits = 5;
837 extu = 1;
838 break;
839 case '[':
840 nbits = 3;
841 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
842 extbits = 6;
843 extu = 1;
844 break;
845 case ']':
846 nbits = 3;
847 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
848 extbits = 6;
849 extu = 1;
850 break;
851 case '4':
852 nbits = 4;
853 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
854 signedp = 1;
855 extbits = 15;
856 break;
857 case '5':
858 nbits = 5;
859 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
860 info->insn_type = dis_dref;
861 info->data_size = 1;
862 break;
863 case 'H':
864 nbits = 5;
865 shift = 1;
866 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
867 info->insn_type = dis_dref;
868 info->data_size = 2;
869 break;
870 case 'W':
871 nbits = 5;
872 shift = 2;
873 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
874 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
875 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
876 {
877 info->insn_type = dis_dref;
878 info->data_size = 4;
879 }
880 break;
881 case 'D':
882 nbits = 5;
883 shift = 3;
884 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
885 info->insn_type = dis_dref;
886 info->data_size = 8;
887 break;
888 case 'j':
889 nbits = 5;
890 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
891 signedp = 1;
892 break;
893 case '6':
894 nbits = 6;
895 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
896 break;
897 case '8':
898 nbits = 8;
899 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
900 break;
901 case 'V':
902 nbits = 8;
903 shift = 2;
904 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
905 /* FIXME: This might be lw, or it might be addiu to $sp or
906 $pc. We assume it's load. */
907 info->insn_type = dis_dref;
908 info->data_size = 4;
909 break;
910 case 'C':
911 nbits = 8;
912 shift = 3;
913 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
914 info->insn_type = dis_dref;
915 info->data_size = 8;
916 break;
917 case 'U':
918 nbits = 8;
919 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
920 extu = 1;
921 break;
922 case 'k':
923 nbits = 8;
924 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
925 signedp = 1;
926 break;
927 case 'K':
928 nbits = 8;
929 shift = 3;
930 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
931 signedp = 1;
932 break;
933 case 'p':
934 nbits = 8;
935 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
936 signedp = 1;
937 pcrel = 1;
938 branch = 1;
939 info->insn_type = dis_condbranch;
940 break;
941 case 'q':
942 nbits = 11;
943 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
944 signedp = 1;
945 pcrel = 1;
946 branch = 1;
947 info->insn_type = dis_branch;
948 break;
949 case 'A':
950 nbits = 8;
951 shift = 2;
952 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
953 pcrel = 1;
954 /* FIXME: This can be lw or la. We assume it is lw. */
955 info->insn_type = dis_dref;
956 info->data_size = 4;
957 break;
958 case 'B':
959 nbits = 5;
960 shift = 3;
961 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
962 pcrel = 1;
963 info->insn_type = dis_dref;
964 info->data_size = 8;
965 break;
966 case 'E':
967 nbits = 5;
968 shift = 2;
969 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
970 pcrel = 1;
971 break;
972 default:
973 abort ();
974 }
975
976 if (! use_extend)
977 {
978 if (signedp && immed >= (1 << (nbits - 1)))
979 immed -= 1 << nbits;
980 immed <<= shift;
981 if ((type == '<' || type == '>' || type == '[' || type == ']')
982 && immed == 0)
983 immed = 8;
984 }
985 else
986 {
987 if (extbits == 16)
988 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
989 else if (extbits == 15)
990 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
991 else
992 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
993 immed &= (1 << extbits) - 1;
994 if (! extu && immed >= (1 << (extbits - 1)))
995 immed -= 1 << extbits;
996 }
997
998 if (! pcrel)
999 (*info->fprintf_func) (info->stream, "%d", immed);
1000 else
1001 {
1002 bfd_vma baseaddr;
1003 bfd_vma val;
1004
1005 if (branch)
1006 {
1007 immed *= 2;
1008 baseaddr = memaddr + 2;
1009 }
1010 else if (use_extend)
1011 baseaddr = memaddr - 2;
1012 else
1013 {
1014 int status;
1015 bfd_byte buffer[2];
1016
1017 baseaddr = memaddr;
1018
1019 /* If this instruction is in the delay slot of a jr
1020 instruction, the base address is the address of the
1021 jr instruction. If it is in the delay slot of jalr
1022 instruction, the base address is the address of the
1023 jalr instruction. This test is unreliable: we have
1024 no way of knowing whether the previous word is
1025 instruction or data. */
1026 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1027 info);
1028 if (status == 0
1029 && (((info->endian == BFD_ENDIAN_BIG
1030 ? bfd_getb16 (buffer)
1031 : bfd_getl16 (buffer))
1032 & 0xf800) == 0x1800))
1033 baseaddr = memaddr - 4;
1034 else
1035 {
1036 status = (*info->read_memory_func) (memaddr - 2, buffer,
1037 2, info);
1038 if (status == 0
1039 && (((info->endian == BFD_ENDIAN_BIG
1040 ? bfd_getb16 (buffer)
1041 : bfd_getl16 (buffer))
1042 & 0xf81f) == 0xe800))
1043 baseaddr = memaddr - 2;
1044 }
1045 }
1046 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1047 (*info->print_address_func) (val, info);
1048 info->target = val;
1049 }
1050 }
1051 break;
1052
1053 case 'a':
1054 if (! use_extend)
1055 extend = 0;
1056 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1057 (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
1058 info->insn_type = dis_jsr;
1059 info->target = ((memaddr + 4) & 0xf0000000) | l;
1060 info->branch_delay_insns = 1;
1061 break;
1062
1063 case 'l':
1064 case 'L':
1065 {
1066 int need_comma, amask, smask;
1067
1068 need_comma = 0;
1069
1070 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1071
1072 amask = (l >> 3) & 7;
1073
1074 if (amask > 0 && amask < 5)
1075 {
1076 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1077 if (amask > 1)
1078 (*info->fprintf_func) (info->stream, "-%s",
1079 mips32_reg_names[amask + 3]);
1080 need_comma = 1;
1081 }
1082
1083 smask = (l >> 1) & 3;
1084 if (smask == 3)
1085 {
1086 (*info->fprintf_func) (info->stream, "%s??",
1087 need_comma ? "," : "");
1088 need_comma = 1;
1089 }
1090 else if (smask > 0)
1091 {
1092 (*info->fprintf_func) (info->stream, "%s%s",
1093 need_comma ? "," : "",
1094 mips32_reg_names[16]);
1095 if (smask > 1)
1096 (*info->fprintf_func) (info->stream, "-%s",
1097 mips32_reg_names[smask + 15]);
1098 need_comma = 1;
1099 }
1100
1101 if (l & 1)
1102 {
1103 (*info->fprintf_func) (info->stream, "%s%s",
1104 need_comma ? "," : "",
1105 mips32_reg_names[31]);
1106 need_comma = 1;
1107 }
1108
1109 if (amask == 5 || amask == 6)
1110 {
1111 (*info->fprintf_func) (info->stream, "%s$f0",
1112 need_comma ? "," : "");
1113 if (amask == 6)
1114 (*info->fprintf_func) (info->stream, "-$f1");
1115 }
1116 }
1117 break;
1118
1119 default:
1120 /* xgettext:c-format */
1121 (*info->fprintf_func)
1122 (info->stream,
1123 _("# internal disassembler error, unrecognised modifier (%c)"),
1124 type);
1125 abort ();
1126 }
1127 }
This page took 0.057197 seconds and 5 git commands to generate.