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