1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5 This file is part of GDB.
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 /* Mips instructions are never longer than this many bytes. */
29 /* FIXME: This should be shared with gdb somehow. */
30 #define REGISTER_NAMES \
31 { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
32 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
33 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
34 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
35 "sr", "lo", "hi", "bad", "cause","pc", \
36 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
37 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
38 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
39 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
40 "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
44 static CONST
char * CONST reg_names
[] = REGISTER_NAMES
;
48 print_insn_arg (d
, l
, pc
, info
)
50 register unsigned long int l
;
52 struct disassemble_info
*info
;
61 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
68 (*info
->fprintf_func
) (info
->stream
, "$%s",
69 reg_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
74 (*info
->fprintf_func
) (info
->stream
, "$%s",
75 reg_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
80 (*info
->fprintf_func
) (info
->stream
, "0x%x",
81 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
84 case 'j': /* same as i, but sign-extended */
86 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
89 (*info
->fprintf_func
) (info
->stream
, "%d",
94 (*info
->fprintf_func
) (info
->stream
, "0x%x",
95 (unsigned int) ((l
>> OP_SH_PREFX
)
100 (*info
->fprintf_func
) (info
->stream
, "0x%x",
101 (unsigned int) ((l
>> OP_SH_CACHE
)
106 (*info
->print_address_func
)
107 (((pc
& 0xF0000000) | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2)),
112 /* sign extend the displacement */
113 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
116 (*info
->print_address_func
)
117 ((delta
<< 2) + pc
+ 4,
122 (*info
->fprintf_func
) (info
->stream
, "$%s",
123 reg_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
127 (*info
->fprintf_func
) (info
->stream
, "$%s", reg_names
[0]);
131 (*info
->fprintf_func
) (info
->stream
, "0x%x",
132 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
136 (*info
->fprintf_func
) (info
->stream
, "0x%x",
137 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
141 (*info
->fprintf_func
) (info
->stream
, "0x%x",
142 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
146 (*info
->fprintf_func
) (info
->stream
, "0x%x",
147 (l
>> OP_SH_SYSCALL
) & OP_MASK_SYSCALL
);
152 (*info
->fprintf_func
) (info
->stream
, "$f%d",
153 (l
>> OP_SH_FS
) & OP_MASK_FS
);
158 (*info
->fprintf_func
) (info
->stream
, "$f%d",
159 (l
>> OP_SH_FT
) & OP_MASK_FT
);
163 (*info
->fprintf_func
) (info
->stream
, "$f%d",
164 (l
>> OP_SH_FD
) & OP_MASK_FD
);
168 (*info
->fprintf_func
) (info
->stream
, "$f%d",
169 (l
>> OP_SH_FR
) & OP_MASK_FR
);
173 (*info
->fprintf_func
) (info
->stream
, "$%d",
174 (l
>> OP_SH_RT
) & OP_MASK_RT
);
178 (*info
->fprintf_func
) (info
->stream
, "$%d",
179 (l
>> OP_SH_RD
) & OP_MASK_RD
);
183 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
184 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
188 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
189 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
193 (*info
->fprintf_func
) (info
->stream
,
194 "# internal error, undefined modifier(%c)", *d
);
199 /* Print the mips instruction at address MEMADDR in debugged memory,
200 on using INFO. Returns length of the instruction, in bytes, which is
201 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
202 this is little-endian code. */
205 _print_insn_mips (memaddr
, word
, info
)
207 struct disassemble_info
*info
;
208 unsigned long int word
;
210 register const struct mips_opcode
*op
;
211 static boolean init
= 0;
212 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
214 /* Build a hash table to shorten the search time. */
219 for (i
= 0; i
<= OP_MASK_OP
; i
++)
221 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
223 if (op
->pinfo
== INSN_MACRO
)
225 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
236 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
239 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
241 if (op
->pinfo
!= INSN_MACRO
&& (word
& op
->mask
) == op
->match
)
243 register const char *d
;
245 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
250 (*info
->fprintf_func
) (info
->stream
, " ");
251 for (; *d
!= '\0'; d
++)
252 print_insn_arg (d
, word
, memaddr
, info
);
260 /* Handle undefined instructions. */
261 (*info
->fprintf_func
) (info
->stream
, "0x%x", word
);
266 print_insn_big_mips (memaddr
, info
)
268 struct disassemble_info
*info
;
271 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
273 return _print_insn_mips (memaddr
, (unsigned long) bfd_getb32 (buffer
), info
);
276 (*info
->memory_error_func
) (status
, memaddr
, info
);
282 print_insn_little_mips (memaddr
, info
)
284 struct disassemble_info
*info
;
287 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
289 return _print_insn_mips (memaddr
, (unsigned long) bfd_getl32 (buffer
), info
);
292 (*info
->memory_error_func
) (status
, memaddr
, info
);
This page took 0.040487 seconds and 5 git commands to generate.