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