Expect the srec_test to fail for ARM targets because the -oformat linker
[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;
c6c98b38
NC
374 case bfd_mach_mips_sb1:
375 target_processor = CPU_SB1;
376 mips_isa = ISA_MIPS64;
377 break;
156c2f8b
NC
378 default:
379 target_processor = CPU_R3000;
e7af610e 380 mips_isa = ISA_MIPS3;
156c2f8b 381 break;
252b5132
RH
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
395static 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;
2bd7f1f3 448
8027df89 449 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor, 0))
252b5132
RH
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
479int
480print_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
514int
515print_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
550static int
551print_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
707static void
708print_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.102638 seconds and 4 git commands to generate.