* eval.c (evaluate_subexp_standard): Pass ``selected_frame'' to
[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
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
RH
286
287 default:
288 /* xgettext:c-format */
289 (*info->fprintf_func) (info->stream,
290 _("# internal error, undefined modifier(%c)"),
291 *d);
292 break;
293 }
294}
295\f
7f6621cd 296/* Figure out the MIPS ISA and CPU based on the machine number. */
252b5132
RH
297
298static void
aa5f19f2 299mips_isa_type (mach, isa, cputype)
252b5132
RH
300 int mach;
301 int *isa;
302 int *cputype;
303{
252b5132
RH
304 switch (mach)
305 {
156c2f8b 306 case bfd_mach_mips3000:
aa5f19f2
NC
307 *cputype = CPU_R3000;
308 *isa = ISA_MIPS1;
156c2f8b
NC
309 break;
310 case bfd_mach_mips3900:
aa5f19f2
NC
311 *cputype = CPU_R3900;
312 *isa = ISA_MIPS1;
156c2f8b
NC
313 break;
314 case bfd_mach_mips4000:
aa5f19f2
NC
315 *cputype = CPU_R4000;
316 *isa = ISA_MIPS3;
156c2f8b
NC
317 break;
318 case bfd_mach_mips4010:
aa5f19f2
NC
319 *cputype = CPU_R4010;
320 *isa = ISA_MIPS2;
156c2f8b
NC
321 break;
322 case bfd_mach_mips4100:
aa5f19f2
NC
323 *cputype = CPU_VR4100;
324 *isa = ISA_MIPS3;
156c2f8b
NC
325 break;
326 case bfd_mach_mips4111:
aa5f19f2
NC
327 *cputype = CPU_R4111;
328 *isa = ISA_MIPS3;
156c2f8b
NC
329 break;
330 case bfd_mach_mips4300:
aa5f19f2
NC
331 *cputype = CPU_R4300;
332 *isa = ISA_MIPS3;
156c2f8b
NC
333 break;
334 case bfd_mach_mips4400:
aa5f19f2
NC
335 *cputype = CPU_R4400;
336 *isa = ISA_MIPS3;
156c2f8b
NC
337 break;
338 case bfd_mach_mips4600:
aa5f19f2
NC
339 *cputype = CPU_R4600;
340 *isa = ISA_MIPS3;
156c2f8b
NC
341 break;
342 case bfd_mach_mips4650:
aa5f19f2
NC
343 *cputype = CPU_R4650;
344 *isa = ISA_MIPS3;
156c2f8b
NC
345 break;
346 case bfd_mach_mips5000:
aa5f19f2
NC
347 *cputype = CPU_R5000;
348 *isa = ISA_MIPS4;
156c2f8b
NC
349 break;
350 case bfd_mach_mips6000:
aa5f19f2
NC
351 *cputype = CPU_R6000;
352 *isa = ISA_MIPS2;
156c2f8b
NC
353 break;
354 case bfd_mach_mips8000:
aa5f19f2
NC
355 *cputype = CPU_R8000;
356 *isa = ISA_MIPS4;
156c2f8b
NC
357 break;
358 case bfd_mach_mips10000:
aa5f19f2
NC
359 *cputype = CPU_R10000;
360 *isa = ISA_MIPS4;
156c2f8b 361 break;
d1cf510e
NC
362 case bfd_mach_mips12000:
363 *cputype = CPU_R12000;
364 *isa = ISA_MIPS4;
365 break;
156c2f8b 366 case bfd_mach_mips16:
aa5f19f2
NC
367 *cputype = CPU_MIPS16;
368 *isa = ISA_MIPS3;
e7af610e 369 break;
84ea6cf2 370 case bfd_mach_mips5:
aa5f19f2
NC
371 *cputype = CPU_MIPS5;
372 *isa = ISA_MIPS5;
84ea6cf2 373 break;
c6c98b38 374 case bfd_mach_mips_sb1:
aa5f19f2 375 *cputype = CPU_SB1;
2228315b 376 *isa = ISA_MIPS64 | INSN_SB1;
c6c98b38 377 break;
0823fbca 378 case bfd_mach_mipsisa32:
eb7b56d0
CD
379 *cputype = CPU_MIPS32;
380 *isa = ISA_MIPS32;
0823fbca
EC
381 break;
382 case bfd_mach_mipsisa64:
eb7b56d0
CD
383 *cputype = CPU_MIPS64;
384 *isa = ISA_MIPS64;
0823fbca
EC
385 break;
386
156c2f8b 387 default:
aa5f19f2
NC
388 *cputype = CPU_R3000;
389 *isa = ISA_MIPS3;
156c2f8b 390 break;
252b5132 391 }
252b5132
RH
392}
393
21d34b1c 394/* Check if the object uses NewABI conventions. */
aa5f19f2
NC
395
396static int
7f6621cd 397is_newabi (header)
21d34b1c 398 Elf_Internal_Ehdr *header;
aa5f19f2 399{
4c563ebf
CD
400 /* There are no old-style ABIs which use 64-bit ELF. */
401 if (header->e_ident[EI_CLASS] == ELFCLASS64)
402 return 1;
403
404 /* If a 32-bit ELF file, N32, EABI32, and EABI64 are new-style ABIs. */
405 if ((header->e_flags & EF_MIPS_ABI2) != 0
406 || (header->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
407 || (header->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
21d34b1c 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 }
7f6621cd 446 }
252b5132
RH
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 461 info->display_endian = info->endian;
9bb28706
CD
462 info->insn_info_valid = 1;
463 info->branch_delay_insns = 0;
def7143b 464 info->data_size = 0;
9bb28706
CD
465 info->insn_type = dis_nonbranch;
466 info->target = 0;
467 info->target2 = 0;
252b5132
RH
468
469 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
470 if (op != NULL)
471 {
472 for (; op < &mips_opcodes[NUMOPCODES]; op++)
473 {
474 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
475 {
476 register const char *d;
2bd7f1f3 477
d98bb281 478 if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
252b5132
RH
479 continue;
480
9bb28706
CD
481 /* Figure out instruction type and branch delay information. */
482 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
483 {
484 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
485 info->insn_type = dis_jsr;
486 else
487 info->insn_type = dis_branch;
488 info->branch_delay_insns = 1;
489 }
490 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
491 | INSN_COND_BRANCH_LIKELY)) != 0)
492 {
493 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
494 info->insn_type = dis_condjsr;
495 else
496 info->insn_type = dis_condbranch;
497 info->branch_delay_insns = 1;
498 }
499 else if ((op->pinfo & (INSN_STORE_MEMORY
500 | INSN_LOAD_MEMORY_DELAY)) != 0)
501 info->insn_type = dis_dref;
502
252b5132
RH
503 (*info->fprintf_func) (info->stream, "%s", op->name);
504
505 d = op->args;
506 if (d != NULL && *d != '\0')
507 {
7f6621cd 508 (*info->fprintf_func) (info->stream, "\t");
252b5132 509 for (; *d != '\0'; d++)
7f6621cd 510 print_insn_arg (d, word, memaddr, info);
252b5132
RH
511 }
512
aa5f19f2 513 return INSNLEN;
252b5132
RH
514 }
515 }
516 }
517
518 /* Handle undefined instructions. */
9bb28706 519 info->insn_type = dis_noninsn;
252b5132 520 (*info->fprintf_func) (info->stream, "0x%x", word);
aa5f19f2 521 return INSNLEN;
252b5132 522}
aa5f19f2 523\f
252b5132
RH
524/* In an environment where we do not know the symbol type of the
525 instruction we are forced to assume that the low order bit of the
526 instructions' address may mark it as a mips16 instruction. If we
527 are single stepping, or the pc is within the disassembled function,
528 this works. Otherwise, we need a clue. Sometimes. */
529
aa5f19f2
NC
530static int
531_print_insn_mips (memaddr, info, endianness)
252b5132
RH
532 bfd_vma memaddr;
533 struct disassemble_info *info;
aa5f19f2 534 enum bfd_endian endianness;
252b5132 535{
aa5f19f2 536 bfd_byte buffer[INSNLEN];
252b5132
RH
537 int status;
538
539#if 1
540 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
541 /* Only a few tools will work this way. */
542 if (memaddr & 0x01)
543 return print_insn_mips16 (memaddr, info);
e93d7199 544#endif
252b5132
RH
545
546#if SYMTAB_AVAILABLE
547 if (info->mach == 16
548 || (info->flavour == bfd_target_elf_flavour
549 && info->symbols != NULL
550 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
551 == STO_MIPS16)))
552 return print_insn_mips16 (memaddr, info);
e93d7199 553#endif
252b5132 554
aa5f19f2 555 /* Use mips64_reg_names for new ABI. */
21d34b1c
TS
556 reg_names = mips32_reg_names;
557
558 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
559 {
560 Elf_Internal_Ehdr *header;
561
7f6621cd
KH
562 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
563 if (is_newabi (header))
21d34b1c
TS
564 reg_names = mips64_reg_names;
565 }
aa5f19f2
NC
566
567 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
252b5132 568 if (status == 0)
aa5f19f2
NC
569 {
570 unsigned long insn;
571
572 if (endianness == BFD_ENDIAN_BIG)
7f6621cd 573 insn = (unsigned long) bfd_getb32 (buffer);
aa5f19f2
NC
574 else
575 insn = (unsigned long) bfd_getl32 (buffer);
576
577 return print_insn_mips (memaddr, insn, info);
578 }
252b5132
RH
579 else
580 {
581 (*info->memory_error_func) (status, memaddr, info);
582 return -1;
583 }
584}
585
586int
aa5f19f2 587print_insn_big_mips (memaddr, info)
252b5132
RH
588 bfd_vma memaddr;
589 struct disassemble_info *info;
590{
aa5f19f2
NC
591 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
592}
252b5132 593
aa5f19f2
NC
594int
595print_insn_little_mips (memaddr, info)
596 bfd_vma memaddr;
597 struct disassemble_info *info;
598{
599 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
252b5132
RH
600}
601\f
602/* Disassemble mips16 instructions. */
603
604static int
605print_insn_mips16 (memaddr, info)
606 bfd_vma memaddr;
607 struct disassemble_info *info;
608{
609 int status;
610 bfd_byte buffer[2];
611 int length;
612 int insn;
613 boolean use_extend;
614 int extend = 0;
615 const struct mips_opcode *op, *opend;
616
617 info->bytes_per_chunk = 2;
618 info->display_endian = info->endian;
252b5132
RH
619 info->insn_info_valid = 1;
620 info->branch_delay_insns = 0;
621 info->data_size = 0;
622 info->insn_type = dis_nonbranch;
623 info->target = 0;
624 info->target2 = 0;
625
626 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
627 if (status != 0)
628 {
629 (*info->memory_error_func) (status, memaddr, info);
630 return -1;
631 }
632
633 length = 2;
634
635 if (info->endian == BFD_ENDIAN_BIG)
636 insn = bfd_getb16 (buffer);
637 else
638 insn = bfd_getl16 (buffer);
639
640 /* Handle the extend opcode specially. */
641 use_extend = false;
642 if ((insn & 0xf800) == 0xf000)
643 {
644 use_extend = true;
645 extend = insn & 0x7ff;
646
647 memaddr += 2;
648
649 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
650 if (status != 0)
651 {
652 (*info->fprintf_func) (info->stream, "extend 0x%x",
653 (unsigned int) extend);
654 (*info->memory_error_func) (status, memaddr, info);
655 return -1;
656 }
657
658 if (info->endian == BFD_ENDIAN_BIG)
659 insn = bfd_getb16 (buffer);
660 else
661 insn = bfd_getl16 (buffer);
662
663 /* Check for an extend opcode followed by an extend opcode. */
664 if ((insn & 0xf800) == 0xf000)
665 {
666 (*info->fprintf_func) (info->stream, "extend 0x%x",
667 (unsigned int) extend);
668 info->insn_type = dis_noninsn;
669 return length;
670 }
671
672 length += 2;
673 }
674
675 /* FIXME: Should probably use a hash table on the major opcode here. */
676
677 opend = mips16_opcodes + bfd_mips16_num_opcodes;
678 for (op = mips16_opcodes; op < opend; op++)
679 {
680 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
681 {
682 const char *s;
683
684 if (strchr (op->args, 'a') != NULL)
685 {
686 if (use_extend)
687 {
688 (*info->fprintf_func) (info->stream, "extend 0x%x",
689 (unsigned int) extend);
690 info->insn_type = dis_noninsn;
691 return length - 2;
692 }
693
694 use_extend = false;
695
696 memaddr += 2;
697
698 status = (*info->read_memory_func) (memaddr, buffer, 2,
699 info);
700 if (status == 0)
701 {
702 use_extend = true;
703 if (info->endian == BFD_ENDIAN_BIG)
704 extend = bfd_getb16 (buffer);
705 else
706 extend = bfd_getl16 (buffer);
707 length += 2;
708 }
709 }
710
711 (*info->fprintf_func) (info->stream, "%s", op->name);
712 if (op->args[0] != '\0')
713 (*info->fprintf_func) (info->stream, "\t");
714
715 for (s = op->args; *s != '\0'; s++)
716 {
717 if (*s == ','
718 && s[1] == 'w'
719 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
720 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
721 {
722 /* Skip the register and the comma. */
723 ++s;
724 continue;
725 }
726 if (*s == ','
727 && s[1] == 'v'
728 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
729 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
730 {
731 /* Skip the register and the comma. */
732 ++s;
733 continue;
734 }
735 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
736 info);
737 }
738
739 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
740 {
741 info->branch_delay_insns = 1;
742 if (info->insn_type != dis_jsr)
743 info->insn_type = dis_branch;
744 }
745
746 return length;
747 }
748 }
749
750 if (use_extend)
751 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
752 (*info->fprintf_func) (info->stream, "0x%x", insn);
753 info->insn_type = dis_noninsn;
754
755 return length;
756}
757
758/* Disassemble an operand for a mips16 instruction. */
759
760static void
761print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
aa5f19f2 762 char type;
252b5132
RH
763 const struct mips_opcode *op;
764 int l;
765 boolean use_extend;
766 int extend;
767 bfd_vma memaddr;
768 struct disassemble_info *info;
769{
770 switch (type)
771 {
772 case ',':
773 case '(':
774 case ')':
775 (*info->fprintf_func) (info->stream, "%c", type);
776 break;
777
778 case 'y':
779 case 'w':
aa5f19f2 780 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
781 mips16_reg_names[((l >> MIPS16OP_SH_RY)
782 & MIPS16OP_MASK_RY)]);
783 break;
784
785 case 'x':
786 case 'v':
aa5f19f2 787 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
788 mips16_reg_names[((l >> MIPS16OP_SH_RX)
789 & MIPS16OP_MASK_RX)]);
790 break;
791
792 case 'z':
aa5f19f2 793 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
794 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
795 & MIPS16OP_MASK_RZ)]);
796 break;
797
798 case 'Z':
aa5f19f2 799 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
800 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
801 & MIPS16OP_MASK_MOVE32Z)]);
802 break;
803
804 case '0':
aa5f19f2 805 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
252b5132
RH
806 break;
807
808 case 'S':
aa5f19f2 809 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
252b5132
RH
810 break;
811
812 case 'P':
813 (*info->fprintf_func) (info->stream, "$pc");
814 break;
815
816 case 'R':
aa5f19f2 817 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
252b5132
RH
818 break;
819
820 case 'X':
aa5f19f2
NC
821 (*info->fprintf_func) (info->stream, "%s",
822 mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
7f6621cd 823 & MIPS16OP_MASK_REGR32)]);
252b5132
RH
824 break;
825
826 case 'Y':
aa5f19f2
NC
827 (*info->fprintf_func) (info->stream, "%s",
828 mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
252b5132
RH
829 break;
830
831 case '<':
832 case '>':
833 case '[':
834 case ']':
835 case '4':
836 case '5':
837 case 'H':
838 case 'W':
839 case 'D':
840 case 'j':
841 case '6':
842 case '8':
843 case 'V':
844 case 'C':
845 case 'U':
846 case 'k':
847 case 'K':
848 case 'p':
849 case 'q':
850 case 'A':
851 case 'B':
852 case 'E':
853 {
854 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
855
856 shift = 0;
857 signedp = 0;
858 extbits = 16;
859 pcrel = 0;
860 extu = 0;
861 branch = 0;
862 switch (type)
863 {
864 case '<':
865 nbits = 3;
866 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
867 extbits = 5;
868 extu = 1;
869 break;
870 case '>':
871 nbits = 3;
872 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
873 extbits = 5;
874 extu = 1;
875 break;
876 case '[':
877 nbits = 3;
878 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
879 extbits = 6;
880 extu = 1;
881 break;
882 case ']':
883 nbits = 3;
884 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
885 extbits = 6;
886 extu = 1;
887 break;
888 case '4':
889 nbits = 4;
890 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
891 signedp = 1;
892 extbits = 15;
893 break;
894 case '5':
895 nbits = 5;
896 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
897 info->insn_type = dis_dref;
898 info->data_size = 1;
899 break;
900 case 'H':
901 nbits = 5;
902 shift = 1;
903 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
904 info->insn_type = dis_dref;
905 info->data_size = 2;
906 break;
907 case 'W':
908 nbits = 5;
909 shift = 2;
910 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
911 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
912 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
913 {
914 info->insn_type = dis_dref;
915 info->data_size = 4;
916 }
917 break;
918 case 'D':
919 nbits = 5;
920 shift = 3;
921 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
922 info->insn_type = dis_dref;
923 info->data_size = 8;
924 break;
925 case 'j':
926 nbits = 5;
927 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
928 signedp = 1;
929 break;
930 case '6':
931 nbits = 6;
932 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
933 break;
934 case '8':
935 nbits = 8;
936 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
937 break;
938 case 'V':
939 nbits = 8;
940 shift = 2;
941 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
942 /* FIXME: This might be lw, or it might be addiu to $sp or
943 $pc. We assume it's load. */
944 info->insn_type = dis_dref;
945 info->data_size = 4;
946 break;
947 case 'C':
948 nbits = 8;
949 shift = 3;
950 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
951 info->insn_type = dis_dref;
952 info->data_size = 8;
953 break;
954 case 'U':
955 nbits = 8;
956 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
957 extu = 1;
958 break;
959 case 'k':
960 nbits = 8;
961 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
962 signedp = 1;
963 break;
964 case 'K':
965 nbits = 8;
966 shift = 3;
967 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
968 signedp = 1;
969 break;
970 case 'p':
971 nbits = 8;
972 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
973 signedp = 1;
974 pcrel = 1;
975 branch = 1;
976 info->insn_type = dis_condbranch;
977 break;
978 case 'q':
979 nbits = 11;
980 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
981 signedp = 1;
982 pcrel = 1;
983 branch = 1;
984 info->insn_type = dis_branch;
985 break;
986 case 'A':
987 nbits = 8;
988 shift = 2;
989 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
990 pcrel = 1;
991 /* FIXME: This can be lw or la. We assume it is lw. */
992 info->insn_type = dis_dref;
993 info->data_size = 4;
994 break;
995 case 'B':
996 nbits = 5;
997 shift = 3;
998 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
999 pcrel = 1;
1000 info->insn_type = dis_dref;
1001 info->data_size = 8;
1002 break;
1003 case 'E':
1004 nbits = 5;
1005 shift = 2;
1006 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1007 pcrel = 1;
1008 break;
1009 default:
1010 abort ();
1011 }
1012
1013 if (! use_extend)
1014 {
1015 if (signedp && immed >= (1 << (nbits - 1)))
1016 immed -= 1 << nbits;
1017 immed <<= shift;
1018 if ((type == '<' || type == '>' || type == '[' || type == ']')
1019 && immed == 0)
1020 immed = 8;
1021 }
1022 else
1023 {
1024 if (extbits == 16)
1025 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1026 else if (extbits == 15)
1027 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1028 else
1029 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1030 immed &= (1 << extbits) - 1;
1031 if (! extu && immed >= (1 << (extbits - 1)))
1032 immed -= 1 << extbits;
1033 }
1034
1035 if (! pcrel)
1036 (*info->fprintf_func) (info->stream, "%d", immed);
1037 else
1038 {
1039 bfd_vma baseaddr;
252b5132
RH
1040
1041 if (branch)
1042 {
1043 immed *= 2;
1044 baseaddr = memaddr + 2;
1045 }
1046 else if (use_extend)
1047 baseaddr = memaddr - 2;
1048 else
1049 {
1050 int status;
1051 bfd_byte buffer[2];
1052
1053 baseaddr = memaddr;
1054
1055 /* If this instruction is in the delay slot of a jr
1056 instruction, the base address is the address of the
1057 jr instruction. If it is in the delay slot of jalr
1058 instruction, the base address is the address of the
1059 jalr instruction. This test is unreliable: we have
1060 no way of knowing whether the previous word is
1061 instruction or data. */
1062 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1063 info);
1064 if (status == 0
1065 && (((info->endian == BFD_ENDIAN_BIG
1066 ? bfd_getb16 (buffer)
1067 : bfd_getl16 (buffer))
1068 & 0xf800) == 0x1800))
1069 baseaddr = memaddr - 4;
1070 else
1071 {
1072 status = (*info->read_memory_func) (memaddr - 2, buffer,
1073 2, info);
1074 if (status == 0
1075 && (((info->endian == BFD_ENDIAN_BIG
1076 ? bfd_getb16 (buffer)
1077 : bfd_getl16 (buffer))
1078 & 0xf81f) == 0xe800))
1079 baseaddr = memaddr - 2;
1080 }
1081 }
9bb28706
CD
1082 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1083 (*info->print_address_func) (info->target, info);
252b5132
RH
1084 }
1085 }
1086 break;
1087
1088 case 'a':
1089 if (! use_extend)
1090 extend = 0;
1091 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
9bb28706
CD
1092 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1093 (*info->print_address_func) (info->target, info);
252b5132 1094 info->insn_type = dis_jsr;
252b5132
RH
1095 info->branch_delay_insns = 1;
1096 break;
1097
1098 case 'l':
1099 case 'L':
1100 {
1101 int need_comma, amask, smask;
1102
1103 need_comma = 0;
1104
1105 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1106
1107 amask = (l >> 3) & 7;
1108
1109 if (amask > 0 && amask < 5)
1110 {
aa5f19f2 1111 (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
252b5132 1112 if (amask > 1)
aa5f19f2
NC
1113 (*info->fprintf_func) (info->stream, "-%s",
1114 mips32_reg_names[amask + 3]);
252b5132
RH
1115 need_comma = 1;
1116 }
1117
1118 smask = (l >> 1) & 3;
1119 if (smask == 3)
1120 {
1121 (*info->fprintf_func) (info->stream, "%s??",
1122 need_comma ? "," : "");
1123 need_comma = 1;
1124 }
1125 else if (smask > 0)
1126 {
aa5f19f2 1127 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1128 need_comma ? "," : "",
aa5f19f2 1129 mips32_reg_names[16]);
252b5132 1130 if (smask > 1)
aa5f19f2
NC
1131 (*info->fprintf_func) (info->stream, "-%s",
1132 mips32_reg_names[smask + 15]);
252b5132
RH
1133 need_comma = 1;
1134 }
1135
1136 if (l & 1)
1137 {
aa5f19f2 1138 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1139 need_comma ? "," : "",
aa5f19f2 1140 mips32_reg_names[31]);
252b5132
RH
1141 need_comma = 1;
1142 }
1143
1144 if (amask == 5 || amask == 6)
1145 {
1146 (*info->fprintf_func) (info->stream, "%s$f0",
1147 need_comma ? "," : "");
1148 if (amask == 6)
1149 (*info->fprintf_func) (info->stream, "-$f1");
1150 }
1151 }
1152 break;
1153
1154 default:
aa5f19f2
NC
1155 /* xgettext:c-format */
1156 (*info->fprintf_func)
1157 (info->stream,
1158 _("# internal disassembler error, unrecognised modifier (%c)"),
1159 type);
252b5132
RH
1160 abort ();
1161 }
1162}
This page took 0.165356 seconds and 4 git commands to generate.