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