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