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