1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
5 This file is part of GDB, GAS, and the GNU binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "opcode/mips.h"
26 /* FIXME: These are needed to figure out if this is a mips16 symbol or
27 not. It would be better to think of a cleaner way to do this. */
31 static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
32 static void print_mips16_insn_arg
33 PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
34 struct disassemble_info *));
36 /* Mips instructions are never longer than this many bytes. */
39 static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
40 struct disassemble_info *));
41 static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
42 struct disassemble_info *));
45 /* FIXME: This should be shared with gdb somehow. */
46 #define REGISTER_NAMES \
47 { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
48 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
49 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
50 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
51 "sr", "lo", "hi", "bad", "cause","pc", \
52 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
53 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
54 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
55 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
56 "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
60 static CONST char * CONST reg_names[] = REGISTER_NAMES;
62 /* The mips16 register names. */
63 static const char * const mips16_reg_names[] =
65 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
70 print_insn_arg (d, l, pc, info)
72 register unsigned long int l;
74 struct disassemble_info *info;
83 (*info->fprintf_func) (info->stream, "%c", *d);
90 (*info->fprintf_func) (info->stream, "$%s",
91 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
96 (*info->fprintf_func) (info->stream, "$%s",
97 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
102 (*info->fprintf_func) (info->stream, "0x%x",
103 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
106 case 'j': /* same as i, but sign-extended */
108 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
111 (*info->fprintf_func) (info->stream, "%d",
116 (*info->fprintf_func) (info->stream, "0x%x",
117 (unsigned int) ((l >> OP_SH_PREFX)
122 (*info->fprintf_func) (info->stream, "0x%x",
123 (unsigned int) ((l >> OP_SH_CACHE)
128 (*info->print_address_func)
129 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
134 /* sign extend the displacement */
135 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
138 (*info->print_address_func)
139 ((delta << 2) + pc + 4,
144 (*info->fprintf_func) (info->stream, "$%s",
145 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
149 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
153 (*info->fprintf_func) (info->stream, "0x%x",
154 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
158 (*info->fprintf_func) (info->stream, "0x%x",
159 (l >> OP_SH_CODE) & OP_MASK_CODE);
163 (*info->fprintf_func) (info->stream, "0x%x",
164 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
168 (*info->fprintf_func) (info->stream, "0x%x",
169 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
174 (*info->fprintf_func) (info->stream, "$f%d",
175 (l >> OP_SH_FS) & OP_MASK_FS);
180 (*info->fprintf_func) (info->stream, "$f%d",
181 (l >> OP_SH_FT) & OP_MASK_FT);
185 (*info->fprintf_func) (info->stream, "$f%d",
186 (l >> OP_SH_FD) & OP_MASK_FD);
190 (*info->fprintf_func) (info->stream, "$f%d",
191 (l >> OP_SH_FR) & OP_MASK_FR);
195 (*info->fprintf_func) (info->stream, "$%d",
196 (l >> OP_SH_RT) & OP_MASK_RT);
200 (*info->fprintf_func) (info->stream, "$%d",
201 (l >> OP_SH_RD) & OP_MASK_RD);
205 (*info->fprintf_func) (info->stream, "$fcc%d",
206 (l >> OP_SH_BCC) & OP_MASK_BCC);
210 (*info->fprintf_func) (info->stream, "$fcc%d",
211 (l >> OP_SH_CCC) & OP_MASK_CCC);
215 (*info->fprintf_func) (info->stream,
216 "# internal error, undefined modifier(%c)", *d);
221 /* Print the mips instruction at address MEMADDR in debugged memory,
222 on using INFO. Returns length of the instruction, in bytes, which is
223 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
224 this is little-endian code. */
227 _print_insn_mips (memaddr, word, info)
229 unsigned long int word;
230 struct disassemble_info *info;
232 register const struct mips_opcode *op;
233 static boolean init = 0;
234 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
236 /* Build a hash table to shorten the search time. */
241 for (i = 0; i <= OP_MASK_OP; i++)
243 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
245 if (op->pinfo == INSN_MACRO)
247 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
258 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
261 for (; op < &mips_opcodes[NUMOPCODES]; op++)
263 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
265 register const char *d;
267 (*info->fprintf_func) (info->stream, "%s", op->name);
270 if (d != NULL && *d != '\0')
272 (*info->fprintf_func) (info->stream, "\t");
273 for (; *d != '\0'; d++)
274 print_insn_arg (d, word, memaddr, info);
282 /* Handle undefined instructions. */
283 (*info->fprintf_func) (info->stream, "0x%x", word);
288 print_insn_big_mips (memaddr, info)
290 struct disassemble_info *info;
296 || (info->flavour == bfd_target_elf_flavour
297 && info->symbol != NULL
298 && (((elf_symbol_type *) info->symbol)->internal_elf_sym.st_other
300 return print_insn_mips16 (memaddr, info);
302 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
304 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
308 (*info->memory_error_func) (status, memaddr, info);
314 print_insn_little_mips (memaddr, info)
316 struct disassemble_info *info;
322 || (info->flavour == bfd_target_elf_flavour
323 && info->symbol != NULL
324 && (((elf_symbol_type *) info->symbol)->internal_elf_sym.st_other
326 return print_insn_mips16 (memaddr, info);
328 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
330 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
334 (*info->memory_error_func) (status, memaddr, info);
339 /* Disassemble mips16 instructions. */
342 print_insn_mips16 (memaddr, info)
344 struct disassemble_info *info;
352 const struct mips_opcode *op, *opend;
354 info->insn_info_valid = 1;
355 info->branch_delay_insns = 0;
357 info->insn_type = dis_nonbranch;
361 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
364 (*info->memory_error_func) (status, memaddr, info);
370 if (info->endian == BFD_ENDIAN_BIG)
371 insn = bfd_getb16 (buffer);
373 insn = bfd_getl16 (buffer);
375 /* Handle the extend opcode specially. */
377 if ((insn & 0xf800) == 0xf000)
380 extend = insn & 0x7ff;
384 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
387 (*info->fprintf_func) (info->stream, "extend 0x%x",
388 (unsigned int) extend);
389 (*info->memory_error_func) (status, memaddr, info);
393 if (info->endian == BFD_ENDIAN_BIG)
394 insn = bfd_getb16 (buffer);
396 insn = bfd_getl16 (buffer);
398 /* Check for an extend opcode followed by an extend opcode. */
399 if ((insn & 0xf800) == 0xf000)
401 (*info->fprintf_func) (info->stream, "extend 0x%x",
402 (unsigned int) extend);
403 info->insn_type = dis_noninsn;
410 /* FIXME: Should probably use a hash table on the major opcode here. */
412 opend = mips16_opcodes + bfd_mips16_num_opcodes;
413 for (op = mips16_opcodes; op < opend; op++)
415 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
419 if (strchr (op->args, 'a') != NULL)
423 (*info->fprintf_func) (info->stream, "extend 0x%x",
424 (unsigned int) extend);
425 info->insn_type = dis_noninsn;
433 status = (*info->read_memory_func) (memaddr, buffer, 2,
438 if (info->endian == BFD_ENDIAN_BIG)
439 extend = bfd_getb16 (buffer);
441 extend = bfd_getl16 (buffer);
446 (*info->fprintf_func) (info->stream, "%s", op->name);
447 if (op->args[0] != '\0')
448 (*info->fprintf_func) (info->stream, "\t");
450 for (s = op->args; *s != '\0'; s++)
454 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
455 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
457 /* Skip the register and the comma. */
463 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
464 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
466 /* Skip the register and the comma. */
470 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
474 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
476 info->branch_delay_insns = 1;
477 if (info->insn_type != dis_jsr)
478 info->insn_type = dis_branch;
486 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
487 (*info->fprintf_func) (info->stream, "0x%x", insn);
488 info->insn_type = dis_noninsn;
493 /* Disassemble an operand for a mips16 instruction. */
496 print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
498 const struct mips_opcode *op;
503 struct disassemble_info *info;
510 (*info->fprintf_func) (info->stream, "%c", type);
515 (*info->fprintf_func) (info->stream, "$%s",
516 mips16_reg_names[((l >> MIPS16OP_SH_RY)
517 & MIPS16OP_MASK_RY)]);
522 (*info->fprintf_func) (info->stream, "$%s",
523 mips16_reg_names[((l >> MIPS16OP_SH_RX)
524 & MIPS16OP_MASK_RX)]);
528 (*info->fprintf_func) (info->stream, "$%s",
529 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
530 & MIPS16OP_MASK_RZ)]);
534 (*info->fprintf_func) (info->stream, "$%s",
535 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
536 & MIPS16OP_MASK_MOVE32Z)]);
540 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
544 (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
548 (*info->fprintf_func) (info->stream, "$pc");
552 (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
556 (*info->fprintf_func) (info->stream, "$%s",
557 reg_names[((l >> MIPS16OP_SH_REGR32)
558 & MIPS16OP_MASK_REGR32)]);
562 (*info->fprintf_func) (info->stream, "$%s",
563 reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
589 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
601 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
607 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
613 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
619 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
625 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
631 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
632 info->insn_type = dis_dref;
638 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
639 info->insn_type = dis_dref;
645 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
646 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
647 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
649 info->insn_type = dis_dref;
656 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
657 info->insn_type = dis_dref;
662 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
667 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
671 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
676 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
677 /* FIXME: This might be lw, or it might be addiu to $sp or
678 $pc. We assume it's load. */
679 info->insn_type = dis_dref;
685 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
686 info->insn_type = dis_dref;
691 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
696 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
702 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
707 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
711 info->insn_type = dis_condbranch;
715 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
719 info->insn_type = dis_branch;
724 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
726 /* FIXME: This can be lw or la. We assume it is lw. */
727 info->insn_type = dis_dref;
733 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
735 info->insn_type = dis_dref;
741 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
750 if (signedp && immed >= (1 << (nbits - 1)))
753 if ((type == '<' || type == '>' || type == '[' || type == '[')
760 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
761 else if (extbits == 15)
762 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
764 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
765 immed &= (1 << extbits) - 1;
766 if (! extu && immed >= (1 << (extbits - 1)))
767 immed -= 1 << extbits;
771 (*info->fprintf_func) (info->stream, "%d", immed);
780 baseaddr = memaddr + 2;
791 /* If this instruction is in the delay slot of a jr
792 instruction, the base address is the address of the
793 jr instruction. If it is in the delay slot of jalr
794 instruction, the base address is the address of the
795 jalr instruction. This test is unreliable: we have
796 no way of knowing whether the previous word is
797 instruction or data. */
798 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
801 && (((info->endian == BFD_ENDIAN_BIG
802 ? bfd_getb16 (buffer)
803 : bfd_getl16 (buffer))
804 & 0xf800) == 0x1800))
805 baseaddr = memaddr - 4;
808 status = (*info->read_memory_func) (memaddr - 2, buffer,
811 && (((info->endian == BFD_ENDIAN_BIG
812 ? bfd_getb16 (buffer)
813 : bfd_getl16 (buffer))
814 & 0xf81f) == 0xe800))
815 baseaddr = memaddr - 2;
818 val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
819 (*info->print_address_func) (val, info);
828 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
829 (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
830 info->insn_type = dis_jsr;
831 info->target = (memaddr & 0xf0000000) | l;
832 info->branch_delay_insns = 1;
838 int need_comma, amask, smask;
842 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
844 amask = (l >> 3) & 7;
845 if (amask == 5 || amask == 6)
847 (*info->fprintf_func) (info->stream, "??");
850 else if (amask > 0 && amask < 7)
852 (*info->fprintf_func) (info->stream, "%s", reg_names[4]);
854 (*info->fprintf_func) (info->stream, "-%s",
855 reg_names[amask + 3]);
859 smask = (l >> 1) & 3;
862 (*info->fprintf_func) (info->stream, "%s??",
863 need_comma ? "," : "");
868 (*info->fprintf_func) (info->stream, "%s%s",
869 need_comma ? "," : "",
872 (*info->fprintf_func) (info->stream, "-%s",
873 reg_names[smask + 15]);
878 (*info->fprintf_func) (info->stream, "%s%s",
879 need_comma ? "," : "",