* mn10300-dis.c (disassemble): Handle register lists.
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
d0ba1cea
ILT
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).
4
5This file is part of GDB.
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
ILT
24#include "opcode/mips.h"
25
d0ba1cea
ILT
26/* Mips instructions are never longer than this many bytes. */
27#define MAXLEN 4
d0ba1cea
ILT
28\f
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",\
41 "epc", "prid"\
42 }
43
44static CONST char * CONST reg_names[] = REGISTER_NAMES;
45\f
46/* subroutine */
5d0734a7
JK
47static void
48print_insn_arg (d, l, pc, info)
547998d2 49 const char *d;
5d0734a7 50 register unsigned long int l;
d0ba1cea 51 bfd_vma pc;
5d0734a7 52 struct disassemble_info *info;
d0ba1cea 53{
fde326fb
ILT
54 int delta;
55
d0ba1cea
ILT
56 switch (*d)
57 {
58 case ',':
59 case '(':
60 case ')':
5d0734a7 61 (*info->fprintf_func) (info->stream, "%c", *d);
d0ba1cea
ILT
62 break;
63
64 case 's':
fde326fb
ILT
65 case 'b':
66 case 'r':
67 case 'v':
5d0734a7
JK
68 (*info->fprintf_func) (info->stream, "$%s",
69 reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
d0ba1cea
ILT
70 break;
71
72 case 't':
fde326fb 73 case 'w':
5d0734a7
JK
74 (*info->fprintf_func) (info->stream, "$%s",
75 reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
d0ba1cea
ILT
76 break;
77
78 case 'i':
fde326fb 79 case 'u':
30b1724c 80 (*info->fprintf_func) (info->stream, "0x%x",
5d0734a7 81 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
d0ba1cea
ILT
82 break;
83
84 case 'j': /* same as i, but sign-extended */
fde326fb
ILT
85 case 'o':
86 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
87 if (delta & 0x8000)
88 delta |= ~0xffff;
5d0734a7 89 (*info->fprintf_func) (info->stream, "%d",
fde326fb 90 delta);
d0ba1cea
ILT
91 break;
92
30b1724c
ILT
93 case 'h':
94 (*info->fprintf_func) (info->stream, "0x%x",
95 (unsigned int) ((l >> OP_SH_PREFX)
96 & OP_MASK_PREFX));
97 break;
98
99 case 'k':
100 (*info->fprintf_func) (info->stream, "0x%x",
101 (unsigned int) ((l >> OP_SH_CACHE)
102 & OP_MASK_CACHE));
103 break;
104
d0ba1cea 105 case 'a':
fde326fb
ILT
106 (*info->print_address_func)
107 (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
108 info);
d0ba1cea
ILT
109 break;
110
fde326fb
ILT
111 case 'p':
112 /* sign extend the displacement */
113 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
114 if (delta & 0x8000)
115 delta |= ~0xffff;
116 (*info->print_address_func)
117 ((delta << 2) + pc + 4,
118 info);
d0ba1cea
ILT
119 break;
120
121 case 'd':
5d0734a7
JK
122 (*info->fprintf_func) (info->stream, "$%s",
123 reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
d0ba1cea
ILT
124 break;
125
547998d2
ILT
126 case 'z':
127 (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
128 break;
129
fde326fb 130 case '<':
5d0734a7
JK
131 (*info->fprintf_func) (info->stream, "0x%x",
132 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
d0ba1cea
ILT
133 break;
134
fde326fb 135 case 'c':
5d0734a7
JK
136 (*info->fprintf_func) (info->stream, "0x%x",
137 (l >> OP_SH_CODE) & OP_MASK_CODE);
d0ba1cea
ILT
138 break;
139
fde326fb
ILT
140 case 'C':
141 (*info->fprintf_func) (info->stream, "0x%x",
142 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
143 break;
144
145 case 'B':
146 (*info->fprintf_func) (info->stream, "0x%x",
147 (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
148 break;
149
d0ba1cea 150 case 'S':
fde326fb 151 case 'V':
5d0734a7
JK
152 (*info->fprintf_func) (info->stream, "$f%d",
153 (l >> OP_SH_FS) & OP_MASK_FS);
d0ba1cea
ILT
154 break;
155
156 case 'T':
fde326fb 157 case 'W':
5d0734a7
JK
158 (*info->fprintf_func) (info->stream, "$f%d",
159 (l >> OP_SH_FT) & OP_MASK_FT);
d0ba1cea
ILT
160 break;
161
162 case 'D':
5d0734a7
JK
163 (*info->fprintf_func) (info->stream, "$f%d",
164 (l >> OP_SH_FD) & OP_MASK_FD);
d0ba1cea
ILT
165 break;
166
30b1724c
ILT
167 case 'R':
168 (*info->fprintf_func) (info->stream, "$f%d",
169 (l >> OP_SH_FR) & OP_MASK_FR);
170 break;
171
fde326fb
ILT
172 case 'E':
173 (*info->fprintf_func) (info->stream, "$%d",
174 (l >> OP_SH_RT) & OP_MASK_RT);
175 break;
176
177 case 'G':
178 (*info->fprintf_func) (info->stream, "$%d",
179 (l >> OP_SH_RD) & OP_MASK_RD);
180 break;
181
30b1724c
ILT
182 case 'N':
183 (*info->fprintf_func) (info->stream, "$fcc%d",
184 (l >> OP_SH_BCC) & OP_MASK_BCC);
185 break;
186
187 case 'M':
188 (*info->fprintf_func) (info->stream, "$fcc%d",
189 (l >> OP_SH_CCC) & OP_MASK_CCC);
190 break;
191
d0ba1cea 192 default:
5d0734a7
JK
193 (*info->fprintf_func) (info->stream,
194 "# internal error, undefined modifier(%c)", *d);
d0ba1cea
ILT
195 break;
196 }
197}
198\f
199/* Print the mips instruction at address MEMADDR in debugged memory,
5d0734a7 200 on using INFO. Returns length of the instruction, in bytes, which is
d0ba1cea
ILT
201 always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
202 this is little-endian code. */
203
30b1724c 204static int
5d0734a7 205_print_insn_mips (memaddr, word, info)
d0ba1cea 206 bfd_vma memaddr;
5d0734a7
JK
207 struct disassemble_info *info;
208 unsigned long int word;
d0ba1cea 209{
30b1724c
ILT
210 register const struct mips_opcode *op;
211 static boolean init = 0;
212 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
d0ba1cea 213
30b1724c
ILT
214 /* Build a hash table to shorten the search time. */
215 if (! init)
d0ba1cea 216 {
30b1724c
ILT
217 unsigned int i;
218
219 for (i = 0; i <= OP_MASK_OP; i++)
fde326fb 220 {
30b1724c
ILT
221 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
222 {
223 if (op->pinfo == INSN_MACRO)
224 continue;
225 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
226 {
227 mips_hash[i] = op;
228 break;
229 }
230 }
231 }
232
233 init = 1;
d0ba1cea
ILT
234 }
235
30b1724c
ILT
236 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
237 if (op != NULL)
d0ba1cea 238 {
30b1724c
ILT
239 for (; op < &mips_opcodes[NUMOPCODES]; op++)
240 {
241 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
242 {
243 register const char *d;
244
245 (*info->fprintf_func) (info->stream, "%s", op->name);
246
247 d = op->args;
248 if (d != NULL)
249 {
250 (*info->fprintf_func) (info->stream, " ");
251 for (; *d != '\0'; d++)
252 print_insn_arg (d, word, memaddr, info);
253 }
254
255 return 4;
256 }
257 }
d0ba1cea
ILT
258 }
259
30b1724c
ILT
260 /* Handle undefined instructions. */
261 (*info->fprintf_func) (info->stream, "0x%x", word);
d0ba1cea
ILT
262 return 4;
263}
5d0734a7
JK
264
265int
266print_insn_big_mips (memaddr, info)
267 bfd_vma memaddr;
268 struct disassemble_info *info;
269{
270 bfd_byte buffer[4];
271 int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
272 if (status == 0)
30b1724c 273 return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer), info);
5d0734a7
JK
274 else
275 {
276 (*info->memory_error_func) (status, memaddr, info);
277 return -1;
278 }
279}
280
281int
282print_insn_little_mips (memaddr, info)
283 bfd_vma memaddr;
284 struct disassemble_info *info;
285{
286 bfd_byte buffer[4];
287 int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
288 if (status == 0)
30b1724c 289 return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer), info);
5d0734a7
JK
290 else
291 {
292 (*info->memory_error_func) (status, memaddr, info);
293 return -1;
294 }
295}
This page took 0.149639 seconds and 4 git commands to generate.