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