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