* Fix for PR 18665, from sky branch.
[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 ')':
f14397f0 90 /* start-sanitize-cygnus */
83af2335
JL
91 case '[':
92 case ']':
f14397f0 93 /* end-sanitize-cygnus */
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
f14397f0 358 /* start-sanitize-cygnus */
83af2335
JL
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;
f14397f0 368 /* end-sanitize-cygnus */
83af2335 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;
f14397f0
GRK
421 /* start-sanitize-vr4xxx */
422 case bfd_mach_mips4121:
423 target_processor = 4121;
424 mips_isa = 3;
425 break;
426 /* end-sanitize-vr4xxx */
83af2335
JL
427 case bfd_mach_mips4300:
428 target_processor = 4300;
429 mips_isa = 3;
430 break;
ffee80df
JL
431 /* start-sanitize-vr4320 */
432 case bfd_mach_mips4320:
433 target_processor = 4320;
434 mips_isa = 3;
435 break;
436 /* end-sanitize-vr4320 */
83af2335
JL
437 case bfd_mach_mips4400:
438 target_processor = 4400;
439 mips_isa = 3;
440 break;
441 case bfd_mach_mips4600:
442 target_processor = 4600;
443 mips_isa = 3;
444 break;
445 case bfd_mach_mips4650:
446 target_processor = 4650;
447 mips_isa = 3;
448 break;
449 /* start-sanitize-tx49 */
450 case bfd_mach_mips4900:
451 target_processor = 4900;
452 mips_isa = 3;
453 break;
454 /* end-sanitize-tx49 */
455 case bfd_mach_mips5000:
456 target_processor = 5000;
457 mips_isa = 4;
458 break;
f14397f0 459 /* start-sanitize-cygnus */
83af2335
JL
460 case bfd_mach_mips5400:
461 target_processor = 5400;
462 mips_isa = 3;
463 break;
f14397f0 464 /* end-sanitize-cygnus */
83af2335
JL
465 /* start-sanitize-r5900 */
466 case bfd_mach_mips5900:
467 target_processor = 5900;
468 mips_isa = 3;
469 break;
470 /* end-sanitize-r5900 */
471 case bfd_mach_mips6000:
472 target_processor = 6000;
473 mips_isa = 2;
474 break;
475 case bfd_mach_mips8000:
476 target_processor = 8000;
477 mips_isa = 4;
478 break;
479 case bfd_mach_mips10000:
480 target_processor = 10000;
481 mips_isa = 4;
482 break;
483 case bfd_mach_mips16:
484 target_processor = 16;
485 mips_isa = 3;
486 break;
487 default:
488 target_processor = 3000;
489 mips_isa = 3;
490 break;
491
492 }
4b035e8e
ILT
493
494 *isa = mips_isa;
495 *cputype = target_processor;
20af0110 496}
4b035e8e
ILT
497
498#endif /* SYMTAB_AVAILABLE */
20af0110 499
8b023c48
JM
500/* Print the mips instruction at address MEMADDR in debugged memory,
501 on using INFO. Returns length of the instruction, in bytes, which is
502 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
503 this is little-endian code. */
504
20af0110
JM
505static int
506_print_insn_mips (memaddr, word, info)
507 bfd_vma memaddr;
508 unsigned long int word;
509 struct disassemble_info *info;
510{
511 register const struct mips_opcode *op;
512 int target_processor, mips_isa;
513 static boolean init = 0;
514 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
515
516 /* Build a hash table to shorten the search time. */
517 if (! init)
518 {
519 unsigned int i;
520
521 for (i = 0; i <= OP_MASK_OP; i++)
522 {
523 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
524 {
525 if (op->pinfo == INSN_MACRO)
526 continue;
527 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
528 {
529 mips_hash[i] = op;
530 break;
531 }
532 }
533 }
534
535 init = 1;
536 }
4b035e8e 537
20af0110 538#if ! SYMTAB_AVAILABLE
4b035e8e
ILT
539 /* This is running out on a target machine, not in a host tool.
540 FIXME: Where does mips_target_info come from? */
541 target_processor = mips_target_info.processor;
542 mips_isa = mips_target_info.isa;
20af0110 543#else
f14397f0 544 set_mips_isa_type (info->mach, &mips_isa, &target_processor);
20af0110 545#endif
83af2335 546
2ea116f4
ILT
547 info->bytes_per_chunk = 4;
548 info->display_endian = info->endian;
549
30b1724c
ILT
550 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
551 if (op != NULL)
d0ba1cea 552 {
30b1724c
ILT
553 for (; op < &mips_opcodes[NUMOPCODES]; op++)
554 {
555 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
556 {
557 register const char *d;
83af2335
JL
558 int insn_isa;
559
560 if ((op->membership & INSN_ISA) == INSN_ISA1)
561 insn_isa = 1;
562 else if ((op->membership & INSN_ISA) == INSN_ISA2)
563 insn_isa = 2;
564 else if ((op->membership & INSN_ISA) == INSN_ISA3)
565 insn_isa = 3;
566 else if ((op->membership & INSN_ISA) == INSN_ISA4)
567 insn_isa = 4;
568 else
569 insn_isa = 15;
570
571 if (insn_isa > mips_isa
572 && (target_processor == 4650
573 && op->membership & INSN_4650) == 0
574 && (target_processor == 4010
575 && op->membership & INSN_4010) == 0
576 && (target_processor == 4100
577 && op->membership & INSN_4100) == 0
f14397f0
GRK
578 /* start-sanitize-vr4xxx */
579 && (target_processor == 4121
580 && op->membership & INSN_4121) == 0
581 /* end-sanitize-vr4xxx */
ffee80df
JL
582 /* start-sanitize-vr4320 */
583 && (target_processor == 4320
584 && op->membership & INSN_4320) == 0
585 /* end-sanitize-vr4320 */
f14397f0 586 /* start-sanitize-cygnus */
83af2335
JL
587 && (target_processor == 5400
588 && op->membership & INSN_5400) == 0
f14397f0 589 /* end-sanitize-cygnus */
83af2335
JL
590 /* start-sanitize-r5900 */
591 && (target_processor == 5900
592 && op->membership & INSN_5900) == 0
593 /* end-sanitize-r5900 */
594 /* start-sanitize-tx49 */
595 && (target_processor == 4900
596 && op->membership & INSN_4900) == 0
597 /* end-sanitize-tx49 */
598 && (target_processor == 3900
599 && op->membership & INSN_3900) == 0)
600 continue;
30b1724c
ILT
601
602 (*info->fprintf_func) (info->stream, "%s", op->name);
603
604 d = op->args;
8d67dc30 605 if (d != NULL && *d != '\0')
30b1724c 606 {
ffee80df
JL
607 /* start-sanitize-r5900 */
608 /* If this is an opcode completer, then do not emit
609 a tab after the opcode. */
1124a4a7 610 if (*d != '&' && *d != ';')
ffee80df
JL
611 /* end-sanitize-r5900 */
612 (*info->fprintf_func) (info->stream, "\t");
30b1724c 613 for (; *d != '\0'; d++)
ffee80df
JL
614 /* start-sanitize-r5900 */
615 /* If this is an escape character, go ahead and print the
616 next character in the arg string verbatim. */
98f699f6 617 if (*d == '#')
ffee80df
JL
618 {
619 d++;
620 (*info->fprintf_func) (info->stream, "%c", *d);
621 }
622 else
623 /* end-sanitize-r5900 */
624 print_insn_arg (d, word, memaddr, info);
30b1724c
ILT
625 }
626
627 return 4;
628 }
629 }
d0ba1cea
ILT
630 }
631
30b1724c
ILT
632 /* Handle undefined instructions. */
633 (*info->fprintf_func) (info->stream, "0x%x", word);
d0ba1cea
ILT
634 return 4;
635}
5d0734a7 636
20af0110 637
4b035e8e
ILT
638/* In an environment where we do not know the symbol type of the
639 instruction we are forced to assume that the low order bit of the
640 instructions' address may mark it as a mips16 instruction. If we
641 are single stepping, or the pc is within the disassembled function,
642 this works. Otherwise, we need a clue. Sometimes. */
20af0110 643
5d0734a7
JK
644int
645print_insn_big_mips (memaddr, info)
646 bfd_vma memaddr;
647 struct disassemble_info *info;
648{
649 bfd_byte buffer[4];
8d67dc30
ILT
650 int status;
651
20af0110 652#if 1
4b035e8e
ILT
653 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
654 /* Only a few tools will work this way. */
8b023c48
JM
655 if (memaddr & 0x01)
656 return print_insn_mips16 (memaddr, info);
20af0110
JM
657#endif
658
659#if SYMTAB_AVAILABLE
8d67dc30
ILT
660 if (info->mach == 16
661 || (info->flavour == bfd_target_elf_flavour
88b38f0c
DE
662 && info->symbols != NULL
663 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
8d67dc30
ILT
664 == STO_MIPS16)))
665 return print_insn_mips16 (memaddr, info);
20af0110 666#endif
8d67dc30
ILT
667
668 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
5d0734a7 669 if (status == 0)
8d67dc30
ILT
670 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
671 info);
5d0734a7
JK
672 else
673 {
674 (*info->memory_error_func) (status, memaddr, info);
675 return -1;
676 }
677}
678
679int
680print_insn_little_mips (memaddr, info)
681 bfd_vma memaddr;
682 struct disassemble_info *info;
683{
684 bfd_byte buffer[4];
8d67dc30
ILT
685 int status;
686
37130f11
DE
687 /* start-sanitize-sky */
688#ifdef ARCH_dvp
88b38f0c
DE
689 {
690 /* bfd_mach_dvp_p is a macro which may evaluate its arguments more than
691 once. Since dvp_mach_type is a function, ensure it's only called
692 once. */
693 int mach = dvp_info_mach_type (info);
694
695 if (bfd_mach_dvp_p (info->mach)
696 || bfd_mach_dvp_p (mach))
697 return print_insn_dvp (memaddr, info);
698 }
37130f11
DE
699#endif
700 /* end-sanitize-sky */
701
20af0110 702#if 1
4b035e8e
ILT
703 if (memaddr & 0x01)
704 return print_insn_mips16 (memaddr, info);
20af0110
JM
705#endif
706
707#if SYMTAB_AVAILABLE
8d67dc30
ILT
708 if (info->mach == 16
709 || (info->flavour == bfd_target_elf_flavour
88b38f0c
DE
710 && info->symbols != NULL
711 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
8d67dc30
ILT
712 == STO_MIPS16)))
713 return print_insn_mips16 (memaddr, info);
20af0110 714#endif
8d67dc30
ILT
715
716 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
5d0734a7 717 if (status == 0)
8d67dc30
ILT
718 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
719 info);
5d0734a7
JK
720 else
721 {
722 (*info->memory_error_func) (status, memaddr, info);
723 return -1;
724 }
725}
8d67dc30
ILT
726\f
727/* Disassemble mips16 instructions. */
728
729static int
730print_insn_mips16 (memaddr, info)
731 bfd_vma memaddr;
732 struct disassemble_info *info;
733{
734 int status;
735 bfd_byte buffer[2];
736 int length;
737 int insn;
738 boolean use_extend;
92976c09 739 int extend = 0;
8d67dc30
ILT
740 const struct mips_opcode *op, *opend;
741
2ea116f4
ILT
742 info->bytes_per_chunk = 2;
743 info->display_endian = info->endian;
744
20d43018
ILT
745 info->insn_info_valid = 1;
746 info->branch_delay_insns = 0;
747 info->data_size = 0;
748 info->insn_type = dis_nonbranch;
749 info->target = 0;
750 info->target2 = 0;
751
8d67dc30
ILT
752 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
753 if (status != 0)
754 {
755 (*info->memory_error_func) (status, memaddr, info);
756 return -1;
757 }
758
759 length = 2;
760
761 if (info->endian == BFD_ENDIAN_BIG)
762 insn = bfd_getb16 (buffer);
763 else
764 insn = bfd_getl16 (buffer);
765
766 /* Handle the extend opcode specially. */
767 use_extend = false;
768 if ((insn & 0xf800) == 0xf000)
769 {
770 use_extend = true;
771 extend = insn & 0x7ff;
772
773 memaddr += 2;
774
775 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
776 if (status != 0)
777 {
778 (*info->fprintf_func) (info->stream, "extend 0x%x",
779 (unsigned int) extend);
780 (*info->memory_error_func) (status, memaddr, info);
781 return -1;
782 }
783
8d67dc30
ILT
784 if (info->endian == BFD_ENDIAN_BIG)
785 insn = bfd_getb16 (buffer);
786 else
787 insn = bfd_getl16 (buffer);
c4f19df2
ILT
788
789 /* Check for an extend opcode followed by an extend opcode. */
790 if ((insn & 0xf800) == 0xf000)
791 {
792 (*info->fprintf_func) (info->stream, "extend 0x%x",
793 (unsigned int) extend);
20d43018 794 info->insn_type = dis_noninsn;
c4f19df2
ILT
795 return length;
796 }
797
798 length += 2;
8d67dc30
ILT
799 }
800
801 /* FIXME: Should probably use a hash table on the major opcode here. */
802
803 opend = mips16_opcodes + bfd_mips16_num_opcodes;
804 for (op = mips16_opcodes; op < opend; op++)
805 {
806 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
807 {
808 const char *s;
809
810 if (strchr (op->args, 'a') != NULL)
811 {
812 if (use_extend)
c4f19df2
ILT
813 {
814 (*info->fprintf_func) (info->stream, "extend 0x%x",
815 (unsigned int) extend);
20d43018 816 info->insn_type = dis_noninsn;
c4f19df2
ILT
817 return length - 2;
818 }
819
8d67dc30
ILT
820 use_extend = false;
821
822 memaddr += 2;
823
824 status = (*info->read_memory_func) (memaddr, buffer, 2,
825 info);
826 if (status == 0)
827 {
828 use_extend = true;
829 if (info->endian == BFD_ENDIAN_BIG)
830 extend = bfd_getb16 (buffer);
831 else
832 extend = bfd_getl16 (buffer);
833 length += 2;
834 }
835 }
836
c4f19df2
ILT
837 (*info->fprintf_func) (info->stream, "%s", op->name);
838 if (op->args[0] != '\0')
839 (*info->fprintf_func) (info->stream, "\t");
8d67dc30
ILT
840
841 for (s = op->args; *s != '\0'; s++)
842 {
843 if (*s == ','
844 && s[1] == 'w'
845 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
846 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
847 {
848 /* Skip the register and the comma. */
849 ++s;
850 continue;
851 }
852 if (*s == ','
853 && s[1] == 'v'
854 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
855 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
856 {
857 /* Skip the register and the comma. */
858 ++s;
859 continue;
860 }
861 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
862 info);
863 }
864
20d43018
ILT
865 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
866 {
867 info->branch_delay_insns = 1;
868 if (info->insn_type != dis_jsr)
869 info->insn_type = dis_branch;
870 }
871
8d67dc30
ILT
872 return length;
873 }
874 }
875
876 if (use_extend)
877 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
878 (*info->fprintf_func) (info->stream, "0x%x", insn);
20d43018 879 info->insn_type = dis_noninsn;
8d67dc30
ILT
880
881 return length;
882}
883
884/* Disassemble an operand for a mips16 instruction. */
885
886static void
887print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
888 int type;
889 const struct mips_opcode *op;
890 int l;
891 boolean use_extend;
892 int extend;
893 bfd_vma memaddr;
894 struct disassemble_info *info;
895{
896 switch (type)
897 {
898 case ',':
899 case '(':
900 case ')':
901 (*info->fprintf_func) (info->stream, "%c", type);
902 break;
903
904 case 'y':
905 case 'w':
906 (*info->fprintf_func) (info->stream, "$%s",
907 mips16_reg_names[((l >> MIPS16OP_SH_RY)
908 & MIPS16OP_MASK_RY)]);
909 break;
910
911 case 'x':
912 case 'v':
913 (*info->fprintf_func) (info->stream, "$%s",
914 mips16_reg_names[((l >> MIPS16OP_SH_RX)
915 & MIPS16OP_MASK_RX)]);
916 break;
917
918 case 'z':
919 (*info->fprintf_func) (info->stream, "$%s",
920 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
921 & MIPS16OP_MASK_RZ)]);
922 break;
923
924 case 'Z':
925 (*info->fprintf_func) (info->stream, "$%s",
926 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
927 & MIPS16OP_MASK_MOVE32Z)]);
928 break;
929
930 case '0':
931 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
932 break;
933
934 case 'S':
935 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
936 break;
937
938 case 'P':
939 (*info->fprintf_func) (info->stream, "$pc");
940 break;
941
942 case 'R':
943 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
944 break;
945
946 case 'X':
947 (*info->fprintf_func) (info->stream, "$%s",
948 reg_names[((l >> MIPS16OP_SH_REGR32)
949 & MIPS16OP_MASK_REGR32)]);
950 break;
951
952 case 'Y':
953 (*info->fprintf_func) (info->stream, "$%s",
954 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
955 break;
956
957 case '<':
958 case '>':
959 case '[':
960 case ']':
961 case '4':
962 case '5':
963 case 'H':
964 case 'W':
965 case 'D':
966 case 'j':
967 case '6':
968 case '8':
969 case 'V':
970 case 'C':
971 case 'U':
972 case 'k':
973 case 'K':
974 case 'p':
975 case 'q':
976 case 'A':
977 case 'B':
978 case 'E':
979 {
980 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
981
982 shift = 0;
983 signedp = 0;
984 extbits = 16;
985 pcrel = 0;
986 extu = 0;
987 branch = 0;
988 switch (type)
989 {
990 case '<':
991 nbits = 3;
992 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
993 extbits = 5;
994 extu = 1;
995 break;
996 case '>':
997 nbits = 3;
998 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
999 extbits = 5;
1000 extu = 1;
1001 break;
1002 case '[':
1003 nbits = 3;
1004 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1005 extbits = 6;
1006 extu = 1;
1007 break;
1008 case ']':
1009 nbits = 3;
1010 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1011 extbits = 6;
1012 extu = 1;
1013 break;
1014 case '4':
1015 nbits = 4;
1016 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1017 signedp = 1;
1018 extbits = 15;
1019 break;
1020 case '5':
1021 nbits = 5;
1022 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
20d43018
ILT
1023 info->insn_type = dis_dref;
1024 info->data_size = 1;
8d67dc30
ILT
1025 break;
1026 case 'H':
1027 nbits = 5;
1028 shift = 1;
1029 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
20d43018
ILT
1030 info->insn_type = dis_dref;
1031 info->data_size = 2;
8d67dc30
ILT
1032 break;
1033 case 'W':
1034 nbits = 5;
1035 shift = 2;
1036 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
20d43018
ILT
1037 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1038 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1039 {
1040 info->insn_type = dis_dref;
1041 info->data_size = 4;
1042 }
8d67dc30
ILT
1043 break;
1044 case 'D':
1045 nbits = 5;
1046 shift = 3;
1047 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
20d43018
ILT
1048 info->insn_type = dis_dref;
1049 info->data_size = 8;
8d67dc30
ILT
1050 break;
1051 case 'j':
1052 nbits = 5;
1053 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1054 signedp = 1;
1055 break;
1056 case '6':
1057 nbits = 6;
1058 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1059 break;
1060 case '8':
1061 nbits = 8;
1062 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1063 break;
1064 case 'V':
1065 nbits = 8;
1066 shift = 2;
1067 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
20d43018
ILT
1068 /* FIXME: This might be lw, or it might be addiu to $sp or
1069 $pc. We assume it's load. */
1070 info->insn_type = dis_dref;
1071 info->data_size = 4;
8d67dc30
ILT
1072 break;
1073 case 'C':
1074 nbits = 8;
1075 shift = 3;
1076 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
20d43018
ILT
1077 info->insn_type = dis_dref;
1078 info->data_size = 8;
8d67dc30
ILT
1079 break;
1080 case 'U':
1081 nbits = 8;
1082 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1083 extu = 1;
1084 break;
1085 case 'k':
1086 nbits = 8;
1087 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1088 signedp = 1;
1089 break;
1090 case 'K':
1091 nbits = 8;
1092 shift = 3;
1093 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1094 signedp = 1;
1095 break;
1096 case 'p':
1097 nbits = 8;
1098 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1099 signedp = 1;
1100 pcrel = 1;
1101 branch = 1;
20d43018 1102 info->insn_type = dis_condbranch;
8d67dc30
ILT
1103 break;
1104 case 'q':
1105 nbits = 11;
1106 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1107 signedp = 1;
1108 pcrel = 1;
1109 branch = 1;
20d43018 1110 info->insn_type = dis_branch;
8d67dc30
ILT
1111 break;
1112 case 'A':
1113 nbits = 8;
1114 shift = 2;
1115 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1116 pcrel = 1;
20d43018
ILT
1117 /* FIXME: This can be lw or la. We assume it is lw. */
1118 info->insn_type = dis_dref;
1119 info->data_size = 4;
8d67dc30
ILT
1120 break;
1121 case 'B':
1122 nbits = 5;
1123 shift = 3;
1124 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1125 pcrel = 1;
20d43018
ILT
1126 info->insn_type = dis_dref;
1127 info->data_size = 8;
8d67dc30
ILT
1128 break;
1129 case 'E':
1130 nbits = 5;
1131 shift = 2;
1132 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1133 pcrel = 1;
1134 break;
1135 default:
1136 abort ();
1137 }
1138
1139 if (! use_extend)
1140 {
1141 if (signedp && immed >= (1 << (nbits - 1)))
1142 immed -= 1 << nbits;
1143 immed <<= shift;
20af0110 1144 if ((type == '<' || type == '>' || type == '[' || type == ']')
8d67dc30
ILT
1145 && immed == 0)
1146 immed = 8;
1147 }
1148 else
1149 {
1150 if (extbits == 16)
1151 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1152 else if (extbits == 15)
1153 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1154 else
1155 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1156 immed &= (1 << extbits) - 1;
1157 if (! extu && immed >= (1 << (extbits - 1)))
1158 immed -= 1 << extbits;
1159 }
1160
1161 if (! pcrel)
1162 (*info->fprintf_func) (info->stream, "%d", immed);
1163 else
1164 {
c4f19df2 1165 bfd_vma baseaddr;
8d67dc30
ILT
1166 bfd_vma val;
1167
1168 if (branch)
c4f19df2
ILT
1169 {
1170 immed *= 2;
1171 baseaddr = memaddr + 2;
1172 }
1173 else if (use_extend)
83af2335 1174 baseaddr = memaddr - 2;
c4f19df2
ILT
1175 else
1176 {
1177 int status;
1178 bfd_byte buffer[2];
1179
1180 baseaddr = memaddr;
1181
1182 /* If this instruction is in the delay slot of a jr
1183 instruction, the base address is the address of the
1184 jr instruction. If it is in the delay slot of jalr
1185 instruction, the base address is the address of the
1186 jalr instruction. This test is unreliable: we have
1187 no way of knowing whether the previous word is
1188 instruction or data. */
1189 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1190 info);
1191 if (status == 0
1192 && (((info->endian == BFD_ENDIAN_BIG
1193 ? bfd_getb16 (buffer)
1194 : bfd_getl16 (buffer))
1195 & 0xf800) == 0x1800))
1196 baseaddr = memaddr - 4;
1197 else
1198 {
1199 status = (*info->read_memory_func) (memaddr - 2, buffer,
1200 2, info);
1201 if (status == 0
1202 && (((info->endian == BFD_ENDIAN_BIG
1203 ? bfd_getb16 (buffer)
1204 : bfd_getl16 (buffer))
1205 & 0xf81f) == 0xe800))
1206 baseaddr = memaddr - 2;
1207 }
1208 }
1209 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
8d67dc30 1210 (*info->print_address_func) (val, info);
20d43018 1211 info->target = val;
8d67dc30
ILT
1212 }
1213 }
1214 break;
1215
1216 case 'a':
1217 if (! use_extend)
1218 extend = 0;
1219 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1220 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
20d43018
ILT
1221 info->insn_type = dis_jsr;
1222 info->target = (memaddr & 0xf0000000) | l;
1223 info->branch_delay_insns = 1;
8d67dc30
ILT
1224 break;
1225
1226 case 'l':
1227 case 'L':
1228 {
1229 int need_comma, amask, smask;
1230
1231 need_comma = 0;
1232
1233 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1234
1235 amask = (l >> 3) & 7;
0d52464c
ILT
1236
1237 if (amask > 0 && amask < 5)
8d67dc30 1238 {
0d52464c 1239 (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
8d67dc30 1240 if (amask > 1)
0d52464c 1241 (*info->fprintf_func) (info->stream, "-$%s",
8d67dc30
ILT
1242 reg_names[amask + 3]);
1243 need_comma = 1;
1244 }
1245
1246 smask = (l >> 1) & 3;
1247 if (smask == 3)
1248 {
1249 (*info->fprintf_func) (info->stream, "%s??",
1250 need_comma ? "," : "");
1251 need_comma = 1;
1252 }
1253 else if (smask > 0)
1254 {
0d52464c 1255 (*info->fprintf_func) (info->stream, "%s$%s",
8d67dc30
ILT
1256 need_comma ? "," : "",
1257 reg_names[16]);
1258 if (smask > 1)
0d52464c 1259 (*info->fprintf_func) (info->stream, "-$%s",
8d67dc30
ILT
1260 reg_names[smask + 15]);
1261 need_comma = 1;
1262 }
1263
1264 if (l & 1)
0d52464c
ILT
1265 {
1266 (*info->fprintf_func) (info->stream, "%s$%s",
1267 need_comma ? "," : "",
1268 reg_names[31]);
1269 need_comma = 1;
1270 }
1271
1272 if (amask == 5 || amask == 6)
1273 {
1274 (*info->fprintf_func) (info->stream, "%s$f0",
1275 need_comma ? "," : "");
1276 if (amask == 6)
1277 (*info->fprintf_func) (info->stream, "-$f1");
1278 }
8d67dc30
ILT
1279 }
1280 break;
1281
1282 default:
1283 abort ();
1284 }
1285}
This page took 0.260837 seconds and 4 git commands to generate.