Add MIPS SB1 machine
[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 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;
374 case bfd_mach_mips_sb1:
375 target_processor = CPU_SB1;
376 mips_isa = ISA_MIPS64;
377 break;
378 default:
379 target_processor = CPU_R3000;
380 mips_isa = ISA_MIPS3;
381 break;
382 }
383
384 *isa = mips_isa;
385 *cputype = target_processor;
386 }
387
388 #endif /* SYMTAB_AVAILABLE */
389
390 /* Print the mips instruction at address MEMADDR in debugged memory,
391 on using INFO. Returns length of the instruction, in bytes, which is
392 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
393 this is little-endian code. */
394
395 static int
396 _print_insn_mips (memaddr, word, info)
397 bfd_vma memaddr;
398 unsigned long int word;
399 struct disassemble_info *info;
400 {
401 register const struct mips_opcode *op;
402 int target_processor, mips_isa;
403 static boolean init = 0;
404 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
405
406 /* Build a hash table to shorten the search time. */
407 if (! init)
408 {
409 unsigned int i;
410
411 for (i = 0; i <= OP_MASK_OP; i++)
412 {
413 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
414 {
415 if (op->pinfo == INSN_MACRO)
416 continue;
417 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
418 {
419 mips_hash[i] = op;
420 break;
421 }
422 }
423 }
424
425 init = 1;
426 }
427
428 #if ! SYMTAB_AVAILABLE
429 /* This is running out on a target machine, not in a host tool.
430 FIXME: Where does mips_target_info come from? */
431 target_processor = mips_target_info.processor;
432 mips_isa = mips_target_info.isa;
433 #else
434 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
435 #endif
436
437 info->bytes_per_chunk = 4;
438 info->display_endian = info->endian;
439
440 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
441 if (op != NULL)
442 {
443 for (; op < &mips_opcodes[NUMOPCODES]; op++)
444 {
445 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
446 {
447 register const char *d;
448
449 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
450 continue;
451
452 (*info->fprintf_func) (info->stream, "%s", op->name);
453
454 d = op->args;
455 if (d != NULL && *d != '\0')
456 {
457 (*info->fprintf_func) (info->stream, "\t");
458 for (; *d != '\0'; d++)
459 print_insn_arg (d, word, memaddr, info);
460 }
461
462 return 4;
463 }
464 }
465 }
466
467 /* Handle undefined instructions. */
468 (*info->fprintf_func) (info->stream, "0x%x", word);
469 return 4;
470 }
471
472
473 /* In an environment where we do not know the symbol type of the
474 instruction we are forced to assume that the low order bit of the
475 instructions' address may mark it as a mips16 instruction. If we
476 are single stepping, or the pc is within the disassembled function,
477 this works. Otherwise, we need a clue. Sometimes. */
478
479 int
480 print_insn_big_mips (memaddr, info)
481 bfd_vma memaddr;
482 struct disassemble_info *info;
483 {
484 bfd_byte buffer[4];
485 int status;
486
487 #if 1
488 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
489 /* Only a few tools will work this way. */
490 if (memaddr & 0x01)
491 return print_insn_mips16 (memaddr, info);
492 #endif
493
494 #if SYMTAB_AVAILABLE
495 if (info->mach == 16
496 || (info->flavour == bfd_target_elf_flavour
497 && info->symbols != NULL
498 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
499 == STO_MIPS16)))
500 return print_insn_mips16 (memaddr, info);
501 #endif
502
503 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
504 if (status == 0)
505 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
506 info);
507 else
508 {
509 (*info->memory_error_func) (status, memaddr, info);
510 return -1;
511 }
512 }
513
514 int
515 print_insn_little_mips (memaddr, info)
516 bfd_vma memaddr;
517 struct disassemble_info *info;
518 {
519 bfd_byte buffer[4];
520 int status;
521
522
523 #if 1
524 if (memaddr & 0x01)
525 return print_insn_mips16 (memaddr, info);
526 #endif
527
528 #if SYMTAB_AVAILABLE
529 if (info->mach == 16
530 || (info->flavour == bfd_target_elf_flavour
531 && info->symbols != NULL
532 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
533 == STO_MIPS16)))
534 return print_insn_mips16 (memaddr, info);
535 #endif
536
537 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
538 if (status == 0)
539 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
540 info);
541 else
542 {
543 (*info->memory_error_func) (status, memaddr, info);
544 return -1;
545 }
546 }
547 \f
548 /* Disassemble mips16 instructions. */
549
550 static int
551 print_insn_mips16 (memaddr, info)
552 bfd_vma memaddr;
553 struct disassemble_info *info;
554 {
555 int status;
556 bfd_byte buffer[2];
557 int length;
558 int insn;
559 boolean use_extend;
560 int extend = 0;
561 const struct mips_opcode *op, *opend;
562
563 info->bytes_per_chunk = 2;
564 info->display_endian = info->endian;
565
566 info->insn_info_valid = 1;
567 info->branch_delay_insns = 0;
568 info->data_size = 0;
569 info->insn_type = dis_nonbranch;
570 info->target = 0;
571 info->target2 = 0;
572
573 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
574 if (status != 0)
575 {
576 (*info->memory_error_func) (status, memaddr, info);
577 return -1;
578 }
579
580 length = 2;
581
582 if (info->endian == BFD_ENDIAN_BIG)
583 insn = bfd_getb16 (buffer);
584 else
585 insn = bfd_getl16 (buffer);
586
587 /* Handle the extend opcode specially. */
588 use_extend = false;
589 if ((insn & 0xf800) == 0xf000)
590 {
591 use_extend = true;
592 extend = insn & 0x7ff;
593
594 memaddr += 2;
595
596 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
597 if (status != 0)
598 {
599 (*info->fprintf_func) (info->stream, "extend 0x%x",
600 (unsigned int) extend);
601 (*info->memory_error_func) (status, memaddr, info);
602 return -1;
603 }
604
605 if (info->endian == BFD_ENDIAN_BIG)
606 insn = bfd_getb16 (buffer);
607 else
608 insn = bfd_getl16 (buffer);
609
610 /* Check for an extend opcode followed by an extend opcode. */
611 if ((insn & 0xf800) == 0xf000)
612 {
613 (*info->fprintf_func) (info->stream, "extend 0x%x",
614 (unsigned int) extend);
615 info->insn_type = dis_noninsn;
616 return length;
617 }
618
619 length += 2;
620 }
621
622 /* FIXME: Should probably use a hash table on the major opcode here. */
623
624 opend = mips16_opcodes + bfd_mips16_num_opcodes;
625 for (op = mips16_opcodes; op < opend; op++)
626 {
627 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
628 {
629 const char *s;
630
631 if (strchr (op->args, 'a') != NULL)
632 {
633 if (use_extend)
634 {
635 (*info->fprintf_func) (info->stream, "extend 0x%x",
636 (unsigned int) extend);
637 info->insn_type = dis_noninsn;
638 return length - 2;
639 }
640
641 use_extend = false;
642
643 memaddr += 2;
644
645 status = (*info->read_memory_func) (memaddr, buffer, 2,
646 info);
647 if (status == 0)
648 {
649 use_extend = true;
650 if (info->endian == BFD_ENDIAN_BIG)
651 extend = bfd_getb16 (buffer);
652 else
653 extend = bfd_getl16 (buffer);
654 length += 2;
655 }
656 }
657
658 (*info->fprintf_func) (info->stream, "%s", op->name);
659 if (op->args[0] != '\0')
660 (*info->fprintf_func) (info->stream, "\t");
661
662 for (s = op->args; *s != '\0'; s++)
663 {
664 if (*s == ','
665 && s[1] == 'w'
666 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
667 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
668 {
669 /* Skip the register and the comma. */
670 ++s;
671 continue;
672 }
673 if (*s == ','
674 && s[1] == 'v'
675 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
676 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
677 {
678 /* Skip the register and the comma. */
679 ++s;
680 continue;
681 }
682 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
683 info);
684 }
685
686 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
687 {
688 info->branch_delay_insns = 1;
689 if (info->insn_type != dis_jsr)
690 info->insn_type = dis_branch;
691 }
692
693 return length;
694 }
695 }
696
697 if (use_extend)
698 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
699 (*info->fprintf_func) (info->stream, "0x%x", insn);
700 info->insn_type = dis_noninsn;
701
702 return length;
703 }
704
705 /* Disassemble an operand for a mips16 instruction. */
706
707 static void
708 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
709 int type;
710 const struct mips_opcode *op;
711 int l;
712 boolean use_extend;
713 int extend;
714 bfd_vma memaddr;
715 struct disassemble_info *info;
716 {
717 switch (type)
718 {
719 case ',':
720 case '(':
721 case ')':
722 (*info->fprintf_func) (info->stream, "%c", type);
723 break;
724
725 case 'y':
726 case 'w':
727 (*info->fprintf_func) (info->stream, "$%s",
728 mips16_reg_names[((l >> MIPS16OP_SH_RY)
729 & MIPS16OP_MASK_RY)]);
730 break;
731
732 case 'x':
733 case 'v':
734 (*info->fprintf_func) (info->stream, "$%s",
735 mips16_reg_names[((l >> MIPS16OP_SH_RX)
736 & MIPS16OP_MASK_RX)]);
737 break;
738
739 case 'z':
740 (*info->fprintf_func) (info->stream, "$%s",
741 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
742 & MIPS16OP_MASK_RZ)]);
743 break;
744
745 case 'Z':
746 (*info->fprintf_func) (info->stream, "$%s",
747 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
748 & MIPS16OP_MASK_MOVE32Z)]);
749 break;
750
751 case '0':
752 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
753 break;
754
755 case 'S':
756 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
757 break;
758
759 case 'P':
760 (*info->fprintf_func) (info->stream, "$pc");
761 break;
762
763 case 'R':
764 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
765 break;
766
767 case 'X':
768 (*info->fprintf_func) (info->stream, "$%s",
769 reg_names[((l >> MIPS16OP_SH_REGR32)
770 & MIPS16OP_MASK_REGR32)]);
771 break;
772
773 case 'Y':
774 (*info->fprintf_func) (info->stream, "$%s",
775 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
776 break;
777
778 case '<':
779 case '>':
780 case '[':
781 case ']':
782 case '4':
783 case '5':
784 case 'H':
785 case 'W':
786 case 'D':
787 case 'j':
788 case '6':
789 case '8':
790 case 'V':
791 case 'C':
792 case 'U':
793 case 'k':
794 case 'K':
795 case 'p':
796 case 'q':
797 case 'A':
798 case 'B':
799 case 'E':
800 {
801 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
802
803 shift = 0;
804 signedp = 0;
805 extbits = 16;
806 pcrel = 0;
807 extu = 0;
808 branch = 0;
809 switch (type)
810 {
811 case '<':
812 nbits = 3;
813 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
814 extbits = 5;
815 extu = 1;
816 break;
817 case '>':
818 nbits = 3;
819 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
820 extbits = 5;
821 extu = 1;
822 break;
823 case '[':
824 nbits = 3;
825 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
826 extbits = 6;
827 extu = 1;
828 break;
829 case ']':
830 nbits = 3;
831 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
832 extbits = 6;
833 extu = 1;
834 break;
835 case '4':
836 nbits = 4;
837 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
838 signedp = 1;
839 extbits = 15;
840 break;
841 case '5':
842 nbits = 5;
843 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
844 info->insn_type = dis_dref;
845 info->data_size = 1;
846 break;
847 case 'H':
848 nbits = 5;
849 shift = 1;
850 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
851 info->insn_type = dis_dref;
852 info->data_size = 2;
853 break;
854 case 'W':
855 nbits = 5;
856 shift = 2;
857 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
858 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
859 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
860 {
861 info->insn_type = dis_dref;
862 info->data_size = 4;
863 }
864 break;
865 case 'D':
866 nbits = 5;
867 shift = 3;
868 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
869 info->insn_type = dis_dref;
870 info->data_size = 8;
871 break;
872 case 'j':
873 nbits = 5;
874 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
875 signedp = 1;
876 break;
877 case '6':
878 nbits = 6;
879 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
880 break;
881 case '8':
882 nbits = 8;
883 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
884 break;
885 case 'V':
886 nbits = 8;
887 shift = 2;
888 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
889 /* FIXME: This might be lw, or it might be addiu to $sp or
890 $pc. We assume it's load. */
891 info->insn_type = dis_dref;
892 info->data_size = 4;
893 break;
894 case 'C':
895 nbits = 8;
896 shift = 3;
897 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
898 info->insn_type = dis_dref;
899 info->data_size = 8;
900 break;
901 case 'U':
902 nbits = 8;
903 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
904 extu = 1;
905 break;
906 case 'k':
907 nbits = 8;
908 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
909 signedp = 1;
910 break;
911 case 'K':
912 nbits = 8;
913 shift = 3;
914 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
915 signedp = 1;
916 break;
917 case 'p':
918 nbits = 8;
919 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
920 signedp = 1;
921 pcrel = 1;
922 branch = 1;
923 info->insn_type = dis_condbranch;
924 break;
925 case 'q':
926 nbits = 11;
927 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
928 signedp = 1;
929 pcrel = 1;
930 branch = 1;
931 info->insn_type = dis_branch;
932 break;
933 case 'A':
934 nbits = 8;
935 shift = 2;
936 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
937 pcrel = 1;
938 /* FIXME: This can be lw or la. We assume it is lw. */
939 info->insn_type = dis_dref;
940 info->data_size = 4;
941 break;
942 case 'B':
943 nbits = 5;
944 shift = 3;
945 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
946 pcrel = 1;
947 info->insn_type = dis_dref;
948 info->data_size = 8;
949 break;
950 case 'E':
951 nbits = 5;
952 shift = 2;
953 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
954 pcrel = 1;
955 break;
956 default:
957 abort ();
958 }
959
960 if (! use_extend)
961 {
962 if (signedp && immed >= (1 << (nbits - 1)))
963 immed -= 1 << nbits;
964 immed <<= shift;
965 if ((type == '<' || type == '>' || type == '[' || type == ']')
966 && immed == 0)
967 immed = 8;
968 }
969 else
970 {
971 if (extbits == 16)
972 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
973 else if (extbits == 15)
974 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
975 else
976 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
977 immed &= (1 << extbits) - 1;
978 if (! extu && immed >= (1 << (extbits - 1)))
979 immed -= 1 << extbits;
980 }
981
982 if (! pcrel)
983 (*info->fprintf_func) (info->stream, "%d", immed);
984 else
985 {
986 bfd_vma baseaddr;
987 bfd_vma val;
988
989 if (branch)
990 {
991 immed *= 2;
992 baseaddr = memaddr + 2;
993 }
994 else if (use_extend)
995 baseaddr = memaddr - 2;
996 else
997 {
998 int status;
999 bfd_byte buffer[2];
1000
1001 baseaddr = memaddr;
1002
1003 /* If this instruction is in the delay slot of a jr
1004 instruction, the base address is the address of the
1005 jr instruction. If it is in the delay slot of jalr
1006 instruction, the base address is the address of the
1007 jalr instruction. This test is unreliable: we have
1008 no way of knowing whether the previous word is
1009 instruction or data. */
1010 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1011 info);
1012 if (status == 0
1013 && (((info->endian == BFD_ENDIAN_BIG
1014 ? bfd_getb16 (buffer)
1015 : bfd_getl16 (buffer))
1016 & 0xf800) == 0x1800))
1017 baseaddr = memaddr - 4;
1018 else
1019 {
1020 status = (*info->read_memory_func) (memaddr - 2, buffer,
1021 2, info);
1022 if (status == 0
1023 && (((info->endian == BFD_ENDIAN_BIG
1024 ? bfd_getb16 (buffer)
1025 : bfd_getl16 (buffer))
1026 & 0xf81f) == 0xe800))
1027 baseaddr = memaddr - 2;
1028 }
1029 }
1030 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
1031 (*info->print_address_func) (val, info);
1032 info->target = val;
1033 }
1034 }
1035 break;
1036
1037 case 'a':
1038 if (! use_extend)
1039 extend = 0;
1040 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1041 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
1042 info->insn_type = dis_jsr;
1043 info->target = (memaddr & 0xf0000000) | l;
1044 info->branch_delay_insns = 1;
1045 break;
1046
1047 case 'l':
1048 case 'L':
1049 {
1050 int need_comma, amask, smask;
1051
1052 need_comma = 0;
1053
1054 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1055
1056 amask = (l >> 3) & 7;
1057
1058 if (amask > 0 && amask < 5)
1059 {
1060 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
1061 if (amask > 1)
1062 (*info->fprintf_func) (info->stream, "-$%s",
1063 reg_names[amask + 3]);
1064 need_comma = 1;
1065 }
1066
1067 smask = (l >> 1) & 3;
1068 if (smask == 3)
1069 {
1070 (*info->fprintf_func) (info->stream, "%s??",
1071 need_comma ? "," : "");
1072 need_comma = 1;
1073 }
1074 else if (smask > 0)
1075 {
1076 (*info->fprintf_func) (info->stream, "%s$%s",
1077 need_comma ? "," : "",
1078 reg_names[16]);
1079 if (smask > 1)
1080 (*info->fprintf_func) (info->stream, "-$%s",
1081 reg_names[smask + 15]);
1082 need_comma = 1;
1083 }
1084
1085 if (l & 1)
1086 {
1087 (*info->fprintf_func) (info->stream, "%s$%s",
1088 need_comma ? "," : "",
1089 reg_names[31]);
1090 need_comma = 1;
1091 }
1092
1093 if (amask == 5 || amask == 6)
1094 {
1095 (*info->fprintf_func) (info->stream, "%s$f0",
1096 need_comma ? "," : "");
1097 if (amask == 6)
1098 (*info->fprintf_func) (info->stream, "-$f1");
1099 }
1100 }
1101 break;
1102
1103 default:
1104 abort ();
1105 }
1106 }
This page took 0.076942 seconds and 5 git commands to generate.