Add MIPS32 as a seperate MIPS architecture
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (c) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
4 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5
6 This file is part of GDB, GAS, and the GNU binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
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
38 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
39 static 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
46 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
47 struct disassemble_info *));
48 static 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. */
53 #define STD_REGISTER_NAMES \
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
67 static CONST char * CONST std_reg_names[] = STD_REGISTER_NAMES;
68
69 /* The mips16 register names. */
70 static const char * const mips16_reg_names[] =
71 {
72 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
73 };
74
75 /* Scalar register names. set_mips_isa_type() decides which register name
76 table to use. */
77 static CONST char * CONST *reg_names = NULL;
78 \f
79 /* subroutine */
80 static void
81 print_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)
140 (((pc & ~ (bfd_vma) 0x0fffffff)
141 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
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
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
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
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",
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);
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
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
265 case 'H':
266 (*info->fprintf_func) (info->stream, "%d",
267 (l >> OP_SH_SEL) & OP_MASK_SEL);
268 break;
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
284 static void
285 set_mips_isa_type (mach, isa, cputype)
286 int mach;
287 int *isa;
288 int *cputype;
289 {
290 int target_processor = CPU_UNKNOWN;
291 int mips_isa = ISA_UNKNOWN;
292
293 /* Use standard MIPS register names by default. */
294 reg_names = std_reg_names;
295
296 switch (mach)
297 {
298 case bfd_mach_mips3000:
299 target_processor = CPU_R3000;
300 mips_isa = ISA_MIPS1;
301 break;
302 case bfd_mach_mips3900:
303 target_processor = CPU_R3900;
304 mips_isa = ISA_MIPS1;
305 break;
306 case bfd_mach_mips4000:
307 target_processor = CPU_R4000;
308 mips_isa = ISA_MIPS3;
309 break;
310 case bfd_mach_mips4010:
311 target_processor = CPU_R4010;
312 mips_isa = ISA_MIPS2;
313 break;
314 case bfd_mach_mips4100:
315 target_processor = CPU_VR4100;
316 mips_isa = ISA_MIPS3;
317 break;
318 case bfd_mach_mips4111:
319 target_processor = CPU_VR4100; /* FIXME: Shouldn't this be CPU_R4111 ??? */
320 mips_isa = ISA_MIPS3;
321 break;
322 case bfd_mach_mips4300:
323 target_processor = CPU_R4300;
324 mips_isa = ISA_MIPS3;
325 break;
326 case bfd_mach_mips4400:
327 target_processor = CPU_R4400;
328 mips_isa = ISA_MIPS3;
329 break;
330 case bfd_mach_mips4600:
331 target_processor = CPU_R4600;
332 mips_isa = ISA_MIPS3;
333 break;
334 case bfd_mach_mips4650:
335 target_processor = CPU_R4650;
336 mips_isa = ISA_MIPS3;
337 break;
338 case bfd_mach_mips5000:
339 target_processor = CPU_R5000;
340 mips_isa = ISA_MIPS4;
341 break;
342 case bfd_mach_mips6000:
343 target_processor = CPU_R6000;
344 mips_isa = ISA_MIPS2;
345 break;
346 case bfd_mach_mips8000:
347 target_processor = CPU_R8000;
348 mips_isa = ISA_MIPS4;
349 break;
350 case bfd_mach_mips10000:
351 target_processor = CPU_R10000;
352 mips_isa = ISA_MIPS4;
353 break;
354 case bfd_mach_mips16:
355 target_processor = CPU_MIPS16;
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;
365 break;
366 default:
367 target_processor = CPU_R3000;
368 mips_isa = ISA_MIPS3;
369 break;
370 }
371
372 *isa = mips_isa;
373 *cputype = target_processor;
374 }
375
376 #endif /* SYMTAB_AVAILABLE */
377
378 /* Print the mips instruction at address MEMADDR in debugged memory,
379 on using INFO. Returns length of the instruction, in bytes, which is
380 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
381 this is little-endian code. */
382
383 static int
384 _print_insn_mips (memaddr, word, info)
385 bfd_vma memaddr;
386 unsigned long int word;
387 struct disassemble_info *info;
388 {
389 register const struct mips_opcode *op;
390 int target_processor, mips_isa;
391 static boolean init = 0;
392 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
393
394 /* Build a hash table to shorten the search time. */
395 if (! init)
396 {
397 unsigned int i;
398
399 for (i = 0; i <= OP_MASK_OP; i++)
400 {
401 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
402 {
403 if (op->pinfo == INSN_MACRO)
404 continue;
405 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
406 {
407 mips_hash[i] = op;
408 break;
409 }
410 }
411 }
412
413 init = 1;
414 }
415
416 #if ! SYMTAB_AVAILABLE
417 /* This is running out on a target machine, not in a host tool.
418 FIXME: Where does mips_target_info come from? */
419 target_processor = mips_target_info.processor;
420 mips_isa = mips_target_info.isa;
421 #else
422 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
423 #endif
424
425 info->bytes_per_chunk = 4;
426 info->display_endian = info->endian;
427
428 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
429 if (op != NULL)
430 {
431 for (; op < &mips_opcodes[NUMOPCODES]; op++)
432 {
433 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
434 {
435 register const char *d;
436
437 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
438 continue;
439
440 (*info->fprintf_func) (info->stream, "%s", op->name);
441
442 d = op->args;
443 if (d != NULL && *d != '\0')
444 {
445 (*info->fprintf_func) (info->stream, "\t");
446 for (; *d != '\0'; d++)
447 print_insn_arg (d, word, memaddr, info);
448 }
449
450 return 4;
451 }
452 }
453 }
454
455 /* Handle undefined instructions. */
456 (*info->fprintf_func) (info->stream, "0x%x", word);
457 return 4;
458 }
459
460
461 /* In an environment where we do not know the symbol type of the
462 instruction we are forced to assume that the low order bit of the
463 instructions' address may mark it as a mips16 instruction. If we
464 are single stepping, or the pc is within the disassembled function,
465 this works. Otherwise, we need a clue. Sometimes. */
466
467 int
468 print_insn_big_mips (memaddr, info)
469 bfd_vma memaddr;
470 struct disassemble_info *info;
471 {
472 bfd_byte buffer[4];
473 int status;
474
475 #if 1
476 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
477 /* Only a few tools will work this way. */
478 if (memaddr & 0x01)
479 return print_insn_mips16 (memaddr, info);
480 #endif
481
482 #if SYMTAB_AVAILABLE
483 if (info->mach == 16
484 || (info->flavour == bfd_target_elf_flavour
485 && info->symbols != NULL
486 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
487 == STO_MIPS16)))
488 return print_insn_mips16 (memaddr, info);
489 #endif
490
491 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
492 if (status == 0)
493 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
494 info);
495 else
496 {
497 (*info->memory_error_func) (status, memaddr, info);
498 return -1;
499 }
500 }
501
502 int
503 print_insn_little_mips (memaddr, info)
504 bfd_vma memaddr;
505 struct disassemble_info *info;
506 {
507 bfd_byte buffer[4];
508 int status;
509
510
511 #if 1
512 if (memaddr & 0x01)
513 return print_insn_mips16 (memaddr, info);
514 #endif
515
516 #if SYMTAB_AVAILABLE
517 if (info->mach == 16
518 || (info->flavour == bfd_target_elf_flavour
519 && info->symbols != NULL
520 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
521 == STO_MIPS16)))
522 return print_insn_mips16 (memaddr, info);
523 #endif
524
525 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
526 if (status == 0)
527 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
528 info);
529 else
530 {
531 (*info->memory_error_func) (status, memaddr, info);
532 return -1;
533 }
534 }
535 \f
536 /* Disassemble mips16 instructions. */
537
538 static int
539 print_insn_mips16 (memaddr, info)
540 bfd_vma memaddr;
541 struct disassemble_info *info;
542 {
543 int status;
544 bfd_byte buffer[2];
545 int length;
546 int insn;
547 boolean use_extend;
548 int extend = 0;
549 const struct mips_opcode *op, *opend;
550
551 info->bytes_per_chunk = 2;
552 info->display_endian = info->endian;
553
554 info->insn_info_valid = 1;
555 info->branch_delay_insns = 0;
556 info->data_size = 0;
557 info->insn_type = dis_nonbranch;
558 info->target = 0;
559 info->target2 = 0;
560
561 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
562 if (status != 0)
563 {
564 (*info->memory_error_func) (status, memaddr, info);
565 return -1;
566 }
567
568 length = 2;
569
570 if (info->endian == BFD_ENDIAN_BIG)
571 insn = bfd_getb16 (buffer);
572 else
573 insn = bfd_getl16 (buffer);
574
575 /* Handle the extend opcode specially. */
576 use_extend = false;
577 if ((insn & 0xf800) == 0xf000)
578 {
579 use_extend = true;
580 extend = insn & 0x7ff;
581
582 memaddr += 2;
583
584 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
585 if (status != 0)
586 {
587 (*info->fprintf_func) (info->stream, "extend 0x%x",
588 (unsigned int) extend);
589 (*info->memory_error_func) (status, memaddr, info);
590 return -1;
591 }
592
593 if (info->endian == BFD_ENDIAN_BIG)
594 insn = bfd_getb16 (buffer);
595 else
596 insn = bfd_getl16 (buffer);
597
598 /* Check for an extend opcode followed by an extend opcode. */
599 if ((insn & 0xf800) == 0xf000)
600 {
601 (*info->fprintf_func) (info->stream, "extend 0x%x",
602 (unsigned int) extend);
603 info->insn_type = dis_noninsn;
604 return length;
605 }
606
607 length += 2;
608 }
609
610 /* FIXME: Should probably use a hash table on the major opcode here. */
611
612 opend = mips16_opcodes + bfd_mips16_num_opcodes;
613 for (op = mips16_opcodes; op < opend; op++)
614 {
615 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
616 {
617 const char *s;
618
619 if (strchr (op->args, 'a') != NULL)
620 {
621 if (use_extend)
622 {
623 (*info->fprintf_func) (info->stream, "extend 0x%x",
624 (unsigned int) extend);
625 info->insn_type = dis_noninsn;
626 return length - 2;
627 }
628
629 use_extend = false;
630
631 memaddr += 2;
632
633 status = (*info->read_memory_func) (memaddr, buffer, 2,
634 info);
635 if (status == 0)
636 {
637 use_extend = true;
638 if (info->endian == BFD_ENDIAN_BIG)
639 extend = bfd_getb16 (buffer);
640 else
641 extend = bfd_getl16 (buffer);
642 length += 2;
643 }
644 }
645
646 (*info->fprintf_func) (info->stream, "%s", op->name);
647 if (op->args[0] != '\0')
648 (*info->fprintf_func) (info->stream, "\t");
649
650 for (s = op->args; *s != '\0'; s++)
651 {
652 if (*s == ','
653 && s[1] == 'w'
654 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
655 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
656 {
657 /* Skip the register and the comma. */
658 ++s;
659 continue;
660 }
661 if (*s == ','
662 && s[1] == 'v'
663 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
664 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
665 {
666 /* Skip the register and the comma. */
667 ++s;
668 continue;
669 }
670 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
671 info);
672 }
673
674 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
675 {
676 info->branch_delay_insns = 1;
677 if (info->insn_type != dis_jsr)
678 info->insn_type = dis_branch;
679 }
680
681 return length;
682 }
683 }
684
685 if (use_extend)
686 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
687 (*info->fprintf_func) (info->stream, "0x%x", insn);
688 info->insn_type = dis_noninsn;
689
690 return length;
691 }
692
693 /* Disassemble an operand for a mips16 instruction. */
694
695 static void
696 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
697 int type;
698 const struct mips_opcode *op;
699 int l;
700 boolean use_extend;
701 int extend;
702 bfd_vma memaddr;
703 struct disassemble_info *info;
704 {
705 switch (type)
706 {
707 case ',':
708 case '(':
709 case ')':
710 (*info->fprintf_func) (info->stream, "%c", type);
711 break;
712
713 case 'y':
714 case 'w':
715 (*info->fprintf_func) (info->stream, "$%s",
716 mips16_reg_names[((l >> MIPS16OP_SH_RY)
717 & MIPS16OP_MASK_RY)]);
718 break;
719
720 case 'x':
721 case 'v':
722 (*info->fprintf_func) (info->stream, "$%s",
723 mips16_reg_names[((l >> MIPS16OP_SH_RX)
724 & MIPS16OP_MASK_RX)]);
725 break;
726
727 case 'z':
728 (*info->fprintf_func) (info->stream, "$%s",
729 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
730 & MIPS16OP_MASK_RZ)]);
731 break;
732
733 case 'Z':
734 (*info->fprintf_func) (info->stream, "$%s",
735 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
736 & MIPS16OP_MASK_MOVE32Z)]);
737 break;
738
739 case '0':
740 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
741 break;
742
743 case 'S':
744 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
745 break;
746
747 case 'P':
748 (*info->fprintf_func) (info->stream, "$pc");
749 break;
750
751 case 'R':
752 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
753 break;
754
755 case 'X':
756 (*info->fprintf_func) (info->stream, "$%s",
757 reg_names[((l >> MIPS16OP_SH_REGR32)
758 & MIPS16OP_MASK_REGR32)]);
759 break;
760
761 case 'Y':
762 (*info->fprintf_func) (info->stream, "$%s",
763 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
764 break;
765
766 case '<':
767 case '>':
768 case '[':
769 case ']':
770 case '4':
771 case '5':
772 case 'H':
773 case 'W':
774 case 'D':
775 case 'j':
776 case '6':
777 case '8':
778 case 'V':
779 case 'C':
780 case 'U':
781 case 'k':
782 case 'K':
783 case 'p':
784 case 'q':
785 case 'A':
786 case 'B':
787 case 'E':
788 {
789 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
790
791 shift = 0;
792 signedp = 0;
793 extbits = 16;
794 pcrel = 0;
795 extu = 0;
796 branch = 0;
797 switch (type)
798 {
799 case '<':
800 nbits = 3;
801 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
802 extbits = 5;
803 extu = 1;
804 break;
805 case '>':
806 nbits = 3;
807 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
808 extbits = 5;
809 extu = 1;
810 break;
811 case '[':
812 nbits = 3;
813 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
814 extbits = 6;
815 extu = 1;
816 break;
817 case ']':
818 nbits = 3;
819 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
820 extbits = 6;
821 extu = 1;
822 break;
823 case '4':
824 nbits = 4;
825 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
826 signedp = 1;
827 extbits = 15;
828 break;
829 case '5':
830 nbits = 5;
831 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
832 info->insn_type = dis_dref;
833 info->data_size = 1;
834 break;
835 case 'H':
836 nbits = 5;
837 shift = 1;
838 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
839 info->insn_type = dis_dref;
840 info->data_size = 2;
841 break;
842 case 'W':
843 nbits = 5;
844 shift = 2;
845 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
846 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
847 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
848 {
849 info->insn_type = dis_dref;
850 info->data_size = 4;
851 }
852 break;
853 case 'D':
854 nbits = 5;
855 shift = 3;
856 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
857 info->insn_type = dis_dref;
858 info->data_size = 8;
859 break;
860 case 'j':
861 nbits = 5;
862 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
863 signedp = 1;
864 break;
865 case '6':
866 nbits = 6;
867 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
868 break;
869 case '8':
870 nbits = 8;
871 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
872 break;
873 case 'V':
874 nbits = 8;
875 shift = 2;
876 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
877 /* FIXME: This might be lw, or it might be addiu to $sp or
878 $pc. We assume it's load. */
879 info->insn_type = dis_dref;
880 info->data_size = 4;
881 break;
882 case 'C':
883 nbits = 8;
884 shift = 3;
885 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
886 info->insn_type = dis_dref;
887 info->data_size = 8;
888 break;
889 case 'U':
890 nbits = 8;
891 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
892 extu = 1;
893 break;
894 case 'k':
895 nbits = 8;
896 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
897 signedp = 1;
898 break;
899 case 'K':
900 nbits = 8;
901 shift = 3;
902 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
903 signedp = 1;
904 break;
905 case 'p':
906 nbits = 8;
907 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
908 signedp = 1;
909 pcrel = 1;
910 branch = 1;
911 info->insn_type = dis_condbranch;
912 break;
913 case 'q':
914 nbits = 11;
915 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
916 signedp = 1;
917 pcrel = 1;
918 branch = 1;
919 info->insn_type = dis_branch;
920 break;
921 case 'A':
922 nbits = 8;
923 shift = 2;
924 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
925 pcrel = 1;
926 /* FIXME: This can be lw or la. We assume it is lw. */
927 info->insn_type = dis_dref;
928 info->data_size = 4;
929 break;
930 case 'B':
931 nbits = 5;
932 shift = 3;
933 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
934 pcrel = 1;
935 info->insn_type = dis_dref;
936 info->data_size = 8;
937 break;
938 case 'E':
939 nbits = 5;
940 shift = 2;
941 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
942 pcrel = 1;
943 break;
944 default:
945 abort ();
946 }
947
948 if (! use_extend)
949 {
950 if (signedp && immed >= (1 << (nbits - 1)))
951 immed -= 1 << nbits;
952 immed <<= shift;
953 if ((type == '<' || type == '>' || type == '[' || type == ']')
954 && immed == 0)
955 immed = 8;
956 }
957 else
958 {
959 if (extbits == 16)
960 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
961 else if (extbits == 15)
962 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
963 else
964 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
965 immed &= (1 << extbits) - 1;
966 if (! extu && immed >= (1 << (extbits - 1)))
967 immed -= 1 << extbits;
968 }
969
970 if (! pcrel)
971 (*info->fprintf_func) (info->stream, "%d", immed);
972 else
973 {
974 bfd_vma baseaddr;
975 bfd_vma val;
976
977 if (branch)
978 {
979 immed *= 2;
980 baseaddr = memaddr + 2;
981 }
982 else if (use_extend)
983 baseaddr = memaddr - 2;
984 else
985 {
986 int status;
987 bfd_byte buffer[2];
988
989 baseaddr = memaddr;
990
991 /* If this instruction is in the delay slot of a jr
992 instruction, the base address is the address of the
993 jr instruction. If it is in the delay slot of jalr
994 instruction, the base address is the address of the
995 jalr instruction. This test is unreliable: we have
996 no way of knowing whether the previous word is
997 instruction or data. */
998 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
999 info);
1000 if (status == 0
1001 && (((info->endian == BFD_ENDIAN_BIG
1002 ? bfd_getb16 (buffer)
1003 : bfd_getl16 (buffer))
1004 & 0xf800) == 0x1800))
1005 baseaddr = memaddr - 4;
1006 else
1007 {
1008 status = (*info->read_memory_func) (memaddr - 2, buffer,
1009 2, info);
1010 if (status == 0
1011 && (((info->endian == BFD_ENDIAN_BIG
1012 ? bfd_getb16 (buffer)
1013 : bfd_getl16 (buffer))
1014 & 0xf81f) == 0xe800))
1015 baseaddr = memaddr - 2;
1016 }
1017 }
1018 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1019 (*info->print_address_func) (val, info);
1020 info->target = val;
1021 }
1022 }
1023 break;
1024
1025 case 'a':
1026 if (! use_extend)
1027 extend = 0;
1028 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1029 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1030 info->insn_type = dis_jsr;
1031 info->target = (memaddr & 0xf0000000) | l;
1032 info->branch_delay_insns = 1;
1033 break;
1034
1035 case 'l':
1036 case 'L':
1037 {
1038 int need_comma, amask, smask;
1039
1040 need_comma = 0;
1041
1042 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1043
1044 amask = (l >> 3) & 7;
1045
1046 if (amask > 0 && amask < 5)
1047 {
1048 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1049 if (amask > 1)
1050 (*info->fprintf_func) (info->stream, "-$%s",
1051 reg_names[amask + 3]);
1052 need_comma = 1;
1053 }
1054
1055 smask = (l >> 1) & 3;
1056 if (smask == 3)
1057 {
1058 (*info->fprintf_func) (info->stream, "%s??",
1059 need_comma ? "," : "");
1060 need_comma = 1;
1061 }
1062 else if (smask > 0)
1063 {
1064 (*info->fprintf_func) (info->stream, "%s$%s",
1065 need_comma ? "," : "",
1066 reg_names[16]);
1067 if (smask > 1)
1068 (*info->fprintf_func) (info->stream, "-$%s",
1069 reg_names[smask + 15]);
1070 need_comma = 1;
1071 }
1072
1073 if (l & 1)
1074 {
1075 (*info->fprintf_func) (info->stream, "%s$%s",
1076 need_comma ? "," : "",
1077 reg_names[31]);
1078 need_comma = 1;
1079 }
1080
1081 if (amask == 5 || amask == 6)
1082 {
1083 (*info->fprintf_func) (info->stream, "%s$f0",
1084 need_comma ? "," : "");
1085 if (amask == 6)
1086 (*info->fprintf_func) (info->stream, "-$f1");
1087 }
1088 }
1089 break;
1090
1091 default:
1092 abort ();
1093 }
1094 }
This page took 0.052618 seconds and 5 git commands to generate.