gdb-3.3
[deliverable/binutils-gdb.git] / gdb / sparc-pinsn.c
1 /* Disassembler for the sparc.
2 Copyright (C) 1989 Free Software Foundation, Inc.
3
4 This file is part of GDB, the GNU disassembler.
5
6 GDB is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 GDB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21
22 #include "defs.h"
23 #include "param.h"
24 #include "symtab.h"
25 #include "sparc-opcode.h"
26
27 extern char *reg_names[];
28 #define freg_names (&reg_names[4 * 8])
29
30 union sparc_insn
31 {
32 unsigned long int code;
33 struct
34 {
35 unsigned int OP:2;
36 #define op ldst.OP
37 unsigned int RD:5;
38 #define rd ldst.RD
39 unsigned int op3:6;
40 unsigned int RS1:5;
41 #define rs1 ldst.RS1
42 unsigned int i:1;
43 unsigned int ASI:8;
44 #define asi ldst.ASI
45 unsigned int RS2:5;
46 #define rs2 ldst.RS2
47 #define shcnt rs2
48 } ldst;
49 struct
50 {
51 unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
52 unsigned int IMM13:13;
53 #define imm13 IMM13.IMM13
54 } IMM13;
55 struct
56 {
57 unsigned int OP:2;
58 unsigned int a:1;
59 unsigned int cond:4;
60 unsigned int op2:3;
61 unsigned int DISP22:22;
62 #define disp22 branch.DISP22
63 } branch;
64 #define imm22 disp22
65 struct
66 {
67 unsigned int OP:2;
68 unsigned int DISP30:30;
69 #define disp30 call.DISP30
70 } call;
71 };
72
73 /* Nonzero if INSN is the opcode for a delayed branch. */
74 static int
75 is_delayed_branch (insn)
76 union sparc_insn insn;
77 {
78 unsigned int i;
79
80 for (i = 0; i < NUMOPCODES; ++i)
81 {
82 const struct sparc_opcode *opcode = &sparc_opcodes[i];
83 if ((opcode->match & insn.code) == opcode->match
84 && (opcode->lose & insn.code) == 0
85 && (opcode->delayed))
86 return 1;
87 }
88 return 0;
89 }
90
91 static int opcodes_sorted = 0;
92
93 /* Print one instruction from MEMADDR on STREAM. */
94 int
95 print_insn (memaddr, stream)
96 CORE_ADDR memaddr;
97 FILE *stream;
98 {
99 union sparc_insn insn;
100
101 register unsigned int i;
102
103 if (!opcodes_sorted)
104 {
105 static int compare_opcodes ();
106 qsort ((char *) sparc_opcodes, NUMOPCODES,
107 sizeof (sparc_opcodes[0]), compare_opcodes);
108 opcodes_sorted = 1;
109 }
110
111 read_memory (memaddr, &insn, sizeof (insn));
112
113 for (i = 0; i < NUMOPCODES; ++i)
114 {
115 const struct sparc_opcode *opcode = &sparc_opcodes[i];
116 if ((opcode->match & insn.code) == opcode->match
117 && (opcode->lose & insn.code) == 0)
118 {
119 /* Nonzero means that we have found an instruction which has
120 the effect of adding or or'ing the imm13 field to rs1. */
121 int imm_added_to_rs1 = 0;
122
123 /* Nonzero means that we have found a plus sign in the args
124 field of the opcode table. */
125 int found_plus = 0;
126
127 /* Do we have an 'or' instruction where rs1 is the same
128 as rsd, and which has the i bit set? */
129 if (opcode->match == 0x80102000
130 && insn.rs1 == insn.rd)
131 imm_added_to_rs1 = 1;
132
133 if (index (opcode->args, 'S') != 0)
134 /* Reject the special case for `set'.
135 The real `sethi' will match. */
136 continue;
137 if (insn.rs1 != insn.rd
138 && index (opcode->args, 'r') != 0)
139 /* Can't do simple format if source and dest are different. */
140 continue;
141
142 fputs_filtered (opcode->name, stream);
143
144 {
145 register const char *s;
146
147 if (opcode->args[0] != ',')
148 fputs_filtered (" ", stream);
149 for (s = opcode->args; *s != '\0'; ++s)
150 {
151 if (*s == ',')
152 {
153 fputs_filtered (",", stream);
154 ++s;
155 if (*s == 'a')
156 {
157 fputs_filtered ("a", stream);
158 ++s;
159 }
160 fputs_filtered (" ", stream);
161 }
162
163 switch (*s)
164 {
165 case '+':
166 found_plus = 1;
167
168 /* note fall-through */
169 default:
170 fprintf_filtered (stream, "%c", *s);
171 break;
172
173 case '#':
174 fputs_filtered ("0", stream);
175 break;
176
177 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
178 case '1':
179 case 'r':
180 reg (insn.rs1);
181 break;
182
183 case '2':
184 reg (insn.rs2);
185 break;
186
187 case 'd':
188 reg (insn.rd);
189 break;
190 #undef reg
191
192 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
193 case 'e':
194 freg (insn.rs1);
195 break;
196
197 case 'f':
198 freg (insn.rs2);
199 break;
200
201 case 'g':
202 freg (insn.rd);
203 break;
204 #undef freg
205
206 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
207 case 'b':
208 creg (insn.rs1);
209 break;
210
211 case 'c':
212 creg (insn.rs2);
213 break;
214
215 case 'D':
216 creg (insn.rd);
217 break;
218 #undef creg
219
220 case 'h':
221 fprintf_filtered (stream, "%%hi(%#x)",
222 (int) insn.imm22 << 10);
223 break;
224
225 case 'i':
226 {
227 /* We cannot trust the compiler to sign-extend
228 when extracting the bitfield, hence the shifts. */
229 int imm = ((int) insn.imm13 << 19) >> 19;
230
231 /* Check to see whether we have a 1+i, and take
232 note of that fact.
233
234 Note: because of the way we sort the table,
235 we will be matching 1+i rather than i+1,
236 so it is OK to assume that i is after +,
237 not before it. */
238 if (found_plus)
239 imm_added_to_rs1 = 1;
240
241 if (imm <= 9)
242 fprintf_filtered (stream, "%d", imm);
243 else
244 fprintf_filtered (stream, "%#x", imm);
245 }
246 break;
247
248 case 'L':
249 print_address ((CORE_ADDR) memaddr + insn.disp30 * 4,
250 stream);
251 break;
252
253 case 'l':
254 if ((insn.code >> 22) == 0)
255 /* Special case for `unimp'. Don't try to turn
256 it's operand into a function offset. */
257 fprintf_filtered (stream, "%#x",
258 (int) (((int) insn.disp22 << 10) >> 10));
259 else
260 /* We cannot trust the compiler to sign-extend
261 when extracting the bitfield, hence the shifts. */
262 print_address ((CORE_ADDR)
263 (memaddr
264 + (((int) insn.disp22 << 10) >> 10) * 4),
265 stream);
266 break;
267
268 case 'A':
269 fprintf_filtered (stream, "(%d)", (int) insn.asi);
270 break;
271
272 case 'C':
273 fputs_filtered ("%csr", stream);
274 break;
275
276 case 'F':
277 fputs_filtered ("%fsr", stream);
278 break;
279
280 case 'p':
281 fputs_filtered ("%psr", stream);
282 break;
283
284 case 'q':
285 fputs_filtered ("%fq", stream);
286 break;
287
288 case 'Q':
289 fputs_filtered ("%cq", stream);
290 break;
291
292 case 't':
293 fputs_filtered ("%tbr", stream);
294 break;
295
296 case 'w':
297 fputs_filtered ("%wim", stream);
298 break;
299
300 case 'y':
301 fputs_filtered ("%y", stream);
302 break;
303 }
304 }
305 }
306
307 /* If we are adding or or'ing something to rs1, then
308 check to see whether the previous instruction was
309 a sethi to the same register as in the sethi.
310 If so, attempt to print the result of the add or
311 or (in this context add and or do the same thing)
312 and its symbolic value. */
313 if (imm_added_to_rs1)
314 {
315 union sparc_insn prev_insn;
316 int errcode;
317
318 errcode = read_memory (memaddr - 4,
319 &prev_insn, sizeof (prev_insn));
320
321 if (errcode == 0)
322 {
323 /* If it is a delayed branch, we need to look at the
324 instruction before the delayed branch. This handles
325 sequences such as
326
327 sethi %o1, %hi(_foo), %o1
328 call _printf
329 or %o1, %lo(_foo), %o1
330 */
331
332 if (is_delayed_branch (prev_insn))
333 errcode = read_memory (memaddr - 8,
334 &prev_insn, sizeof (prev_insn));
335 }
336
337 /* If there was a problem reading memory, then assume
338 the previous instruction was not sethi. */
339 if (errcode == 0)
340 {
341 /* Is it sethi to the same register? */
342 if ((prev_insn.code & 0xc1c00000) == 0x01000000
343 && prev_insn.rd == insn.rs1)
344 {
345 fprintf_filtered (stream, "\t! ");
346 /* We cannot trust the compiler to sign-extend
347 when extracting the bitfield, hence the shifts. */
348 print_address (((int) prev_insn.imm22 << 10)
349 | (insn.imm13 << 19) >> 19, stream);
350 }
351 }
352 }
353
354 return sizeof (insn);
355 }
356 }
357
358 fprintf_filtered ("%#8x", insn.code);
359 return sizeof (insn);
360 }
361
362
363 /* Compare opcodes A and B. */
364
365 static int
366 compare_opcodes (a, b)
367 char *a, *b;
368 {
369 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
370 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
371 unsigned long int match0 = op0->match, match1 = op1->match;
372 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
373 register unsigned int i;
374
375 /* If a bit is set in both match and lose, there is something
376 wrong with the opcode table. */
377 if (match0 & lose0)
378 {
379 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8x, %#.8x\n",
380 op0->name, match0, lose0);
381 op0->lose &= ~op0->match;
382 lose0 = op0->lose;
383 }
384
385 if (match1 & lose1)
386 {
387 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8x, %#.8x\n",
388 op1->name, match1, lose1);
389 op1->lose &= ~op1->match;
390 lose1 = op1->lose;
391 }
392
393 /* Because the bits that are variable in one opcode are constant in
394 another, it is important to order the opcodes in the right order. */
395 for (i = 0; i < 32; ++i)
396 {
397 unsigned long int x = 1 << i;
398 int x0 = (match0 & x) != 0;
399 int x1 = (match1 & x) != 0;
400
401 if (x0 != x1)
402 return x1 - x0;
403 }
404
405 for (i = 0; i < 32; ++i)
406 {
407 unsigned long int x = 1 << i;
408 int x0 = (lose0 & x) != 0;
409 int x1 = (lose1 & x) != 0;
410
411 if (x0 != x1)
412 return x1 - x0;
413 }
414
415 /* They are functionally equal. So as long as the opcode table is
416 valid, we can put whichever one first we want, on aesthetic grounds. */
417 {
418 int length_diff = strlen (op0->args) - strlen (op1->args);
419 if (length_diff != 0)
420 /* Put the one with fewer arguments first. */
421 return length_diff;
422 }
423
424 /* Put 1+i before i+1. */
425 {
426 char *p0 = (char *) index(op0->args, '+');
427 char *p1 = (char *) index(op1->args, '+');
428
429 if (p0 && p1)
430 {
431 /* There is a plus in both operands. Note that a plus
432 sign cannot be the first character in args,
433 so the following [-1]'s are valid. */
434 if (p0[-1] == 'i' && p1[1] == 'i')
435 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
436 return 1;
437 if (p0[1] == 'i' && p1[-1] == 'i')
438 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
439 return -1;
440 }
441 }
442
443 /* They are, as far as we can tell, identical.
444 Since qsort may have rearranged the table partially, there is
445 no way to tell which one was first in the opcode table as
446 written, so just say there are equal. */
447 return 0;
448 }
This page took 0.039703 seconds and 5 git commands to generate.