* expprint.c (print_subexp): Add missing ']'.
[deliverable/binutils-gdb.git] / gdb / sparc-pinsn.c
1 /* Print SPARC instructions for GDB, the GNU Debugger.
2 Copyright 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB, the GNU disassembler.
5
6 This program 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 2 of the License, or
9 (at your option) any later version.
10
11 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "opcode/sparc.h"
23 #include "gdbcore.h"
24 #include "string.h"
25 #include "target.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 anop:2;
36 #define op ldst.anop
37 unsigned int anrd:5;
38 #define rd ldst.anrd
39 unsigned int op3:6;
40 unsigned int anrs1:5;
41 #define rs1 ldst.anrs1
42 unsigned int i:1;
43 unsigned int anasi:8;
44 #define asi ldst.anasi
45 unsigned int anrs2:5;
46 #define rs2 ldst.anrs2
47 #define shcnt rs2
48 } ldst;
49 struct
50 {
51 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
52 unsigned int IMM13:13;
53 #define imm13 IMM13.IMM13
54 } IMM13;
55 struct
56 {
57 unsigned int anop: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 anop:2;
68 unsigned int adisp30:30;
69 #define disp30 call.adisp30
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 return (opcode->flags & F_DELAYED);
86 }
87 return 0;
88 }
89
90 static int opcodes_sorted = 0;
91 extern void qsort ();
92
93 /* Print one instruction from MEMADDR on STREAM.
94
95 We suffix the instruction with a comment that gives the absolute
96 address involved, as well as its symbolic form, if the instruction
97 is preceded by a findable `sethi' and it either adds an immediate
98 displacement to that register, or it is an `add' or `or' instruction
99 on that register. */
100 int
101 print_insn (memaddr, stream)
102 CORE_ADDR memaddr;
103 FILE *stream;
104 {
105 union sparc_insn insn;
106
107 register unsigned int i;
108
109 if (!opcodes_sorted)
110 {
111 static int compare_opcodes ();
112 qsort ((char *) sparc_opcodes, NUMOPCODES,
113 sizeof (sparc_opcodes[0]), compare_opcodes);
114 opcodes_sorted = 1;
115 }
116
117 read_memory (memaddr, (char *) &insn, sizeof (insn));
118
119 for (i = 0; i < NUMOPCODES; ++i)
120 {
121 const struct sparc_opcode *opcode = &sparc_opcodes[i];
122 if ((opcode->match & insn.code) == opcode->match
123 && (opcode->lose & insn.code) == 0)
124 {
125 /* Nonzero means that we have found an instruction which has
126 the effect of adding or or'ing the imm13 field to rs1. */
127 int imm_added_to_rs1 = 0;
128
129 /* Nonzero means that we have found a plus sign in the args
130 field of the opcode table. */
131 int found_plus = 0;
132
133 /* Do we have an `add' or `or' instruction where rs1 is the same
134 as rsd, and which has the i bit set? */
135 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
136 /* (or) (add) */
137 && insn.rs1 == insn.rd)
138 imm_added_to_rs1 = 1;
139
140 if (insn.rs1 != insn.rd
141 && strchr (opcode->args, 'r') != 0)
142 /* Can't do simple format if source and dest are different. */
143 continue;
144
145 fputs_filtered (opcode->name, stream);
146
147 {
148 register const char *s;
149
150 if (opcode->args[0] != ',')
151 fputs_filtered (" ", stream);
152 for (s = opcode->args; *s != '\0'; ++s)
153 {
154 if (*s == ',')
155 {
156 fputs_filtered (",", stream);
157 ++s;
158 if (*s == 'a')
159 {
160 fputs_filtered ("a", stream);
161 ++s;
162 }
163 fputs_filtered (" ", stream);
164 }
165
166 switch (*s)
167 {
168 case '+':
169 found_plus = 1;
170
171 /* note fall-through */
172 default:
173 fprintf_filtered (stream, "%c", *s);
174 break;
175
176 case '#':
177 fputs_filtered ("0", stream);
178 break;
179
180 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
181 case '1':
182 case 'r':
183 reg (insn.rs1);
184 break;
185
186 case '2':
187 reg (insn.rs2);
188 break;
189
190 case 'd':
191 reg (insn.rd);
192 break;
193 #undef reg
194
195 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
196 case 'e':
197 case 'v': /* double/even */
198 case 'V': /* quad/multiple of 4 */
199 freg (insn.rs1);
200 break;
201
202 case 'f':
203 case 'B': /* double/even */
204 case 'R': /* quad/multiple of 4 */
205 freg (insn.rs2);
206 break;
207
208 case 'g':
209 case 'H': /* double/even */
210 case 'J': /* quad/multiple of 4 */
211 freg (insn.rd);
212 break;
213 #undef freg
214
215 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
216 case 'b':
217 creg (insn.rs1);
218 break;
219
220 case 'c':
221 creg (insn.rs2);
222 break;
223
224 case 'D':
225 creg (insn.rd);
226 break;
227 #undef creg
228
229 case 'h':
230 fprintf_filtered (stream, "%%hi(%#x)",
231 (int) insn.imm22 << 10);
232 break;
233
234 case 'i':
235 {
236 /* We cannot trust the compiler to sign-extend
237 when extracting the bitfield, hence the shifts. */
238 int imm = ((int) insn.imm13 << 19) >> 19;
239
240 /* Check to see whether we have a 1+i, and take
241 note of that fact.
242
243 FIXME: No longer true/relavant ???
244 Note: because of the way we sort the table,
245 we will be matching 1+i rather than i+1,
246 so it is OK to assume that i is after +,
247 not before it. */
248 if (found_plus)
249 imm_added_to_rs1 = 1;
250
251 if (imm <= 9)
252 fprintf_filtered (stream, "%d", imm);
253 else
254 fprintf_filtered (stream, "%#x", imm);
255 }
256 break;
257
258 case 'L':
259 print_address ((CORE_ADDR) memaddr + insn.disp30 * 4,
260 stream);
261 break;
262
263 case 'l':
264 if ((insn.code >> 22) == 0)
265 /* Special case for `unimp'. Don't try to turn
266 it's operand into a function offset. */
267 fprintf_filtered (stream, "%#x",
268 (int) (((int) insn.disp22 << 10) >> 10));
269 else
270 /* We cannot trust the compiler to sign-extend
271 when extracting the bitfield, hence the shifts. */
272 print_address ((CORE_ADDR)
273 (memaddr
274 + (((int) insn.disp22 << 10) >> 10) * 4),
275 stream);
276 break;
277
278 case 'A':
279 fprintf_filtered (stream, "(%d)", (int) insn.asi);
280 break;
281
282 case 'C':
283 fputs_filtered ("%csr", stream);
284 break;
285
286 case 'F':
287 fputs_filtered ("%fsr", stream);
288 break;
289
290 case 'p':
291 fputs_filtered ("%psr", stream);
292 break;
293
294 case 'q':
295 fputs_filtered ("%fq", stream);
296 break;
297
298 case 'Q':
299 fputs_filtered ("%cq", stream);
300 break;
301
302 case 't':
303 fputs_filtered ("%tbr", stream);
304 break;
305
306 case 'w':
307 fputs_filtered ("%wim", stream);
308 break;
309
310 case 'y':
311 fputs_filtered ("%y", stream);
312 break;
313 }
314 }
315 }
316
317 /* If we are adding or or'ing something to rs1, then
318 check to see whether the previous instruction was
319 a sethi to the same register as in the sethi.
320 If so, attempt to print the result of the add or
321 or (in this context add and or do the same thing)
322 and its symbolic value. */
323 if (imm_added_to_rs1)
324 {
325 union sparc_insn prev_insn;
326 int errcode;
327
328 errcode = target_read_memory (memaddr - 4,
329 (char *)&prev_insn, sizeof (prev_insn));
330
331 if (errcode == 0)
332 {
333 /* If it is a delayed branch, we need to look at the
334 instruction before the delayed branch. This handles
335 sequences such as
336
337 sethi %o1, %hi(_foo), %o1
338 call _printf
339 or %o1, %lo(_foo), %o1
340 */
341
342 if (is_delayed_branch (prev_insn))
343 errcode = target_read_memory
344 (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn));
345 }
346
347 /* If there was a problem reading memory, then assume
348 the previous instruction was not sethi. */
349 if (errcode == 0)
350 {
351 /* Is it sethi to the same register? */
352 if ((prev_insn.code & 0xc1c00000) == 0x01000000
353 && prev_insn.rd == insn.rs1)
354 {
355 fprintf_filtered (stream, "\t! ");
356 /* We cannot trust the compiler to sign-extend
357 when extracting the bitfield, hence the shifts. */
358 print_address (((int) prev_insn.imm22 << 10)
359 | (insn.imm13 << 19) >> 19, stream);
360 }
361 }
362 }
363
364 return sizeof (insn);
365 }
366 }
367
368 printf_filtered ("%#8x", insn.code);
369 return sizeof (insn);
370 }
371
372 /* Compare opcodes A and B. */
373
374 static int
375 compare_opcodes (a, b)
376 char *a, *b;
377 {
378 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
379 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
380 unsigned long int match0 = op0->match, match1 = op1->match;
381 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
382 register unsigned int i;
383
384 /* If a bit is set in both match and lose, there is something
385 wrong with the opcode table. */
386 if (match0 & lose0)
387 {
388 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
389 op0->name, match0, lose0);
390 op0->lose &= ~op0->match;
391 lose0 = op0->lose;
392 }
393
394 if (match1 & lose1)
395 {
396 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
397 op1->name, match1, lose1);
398 op1->lose &= ~op1->match;
399 lose1 = op1->lose;
400 }
401
402 /* Because the bits that are variable in one opcode are constant in
403 another, it is important to order the opcodes in the right order. */
404 for (i = 0; i < 32; ++i)
405 {
406 unsigned long int x = 1 << i;
407 int x0 = (match0 & x) != 0;
408 int x1 = (match1 & x) != 0;
409
410 if (x0 != x1)
411 return x1 - x0;
412 }
413
414 for (i = 0; i < 32; ++i)
415 {
416 unsigned long int x = 1 << i;
417 int x0 = (lose0 & x) != 0;
418 int x1 = (lose1 & x) != 0;
419
420 if (x0 != x1)
421 return x1 - x0;
422 }
423
424 /* They are functionally equal. So as long as the opcode table is
425 valid, we can put whichever one first we want, on aesthetic grounds. */
426
427 /* Our first aesthetic ground is that aliases defer to real insns. */
428 {
429 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
430 if (alias_diff != 0)
431 /* Put the one that isn't an alias first. */
432 return alias_diff;
433 }
434
435 /* Except for aliases, two "identical" instructions had
436 better have the same opcode. This is a sanity check on the table. */
437 i = strcmp (op0->name, op1->name);
438 if (i)
439 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
440 return i;
441 else
442 fprintf (stderr,
443 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
444 op0->name, op1->name);
445
446 /* Fewer arguments are preferred. */
447 {
448 int length_diff = strlen (op0->args) - strlen (op1->args);
449 if (length_diff != 0)
450 /* Put the one with fewer arguments first. */
451 return length_diff;
452 }
453
454 /* Put 1+i before i+1. */
455 {
456 char *p0 = (char *) strchr(op0->args, '+');
457 char *p1 = (char *) strchr(op1->args, '+');
458
459 if (p0 && p1)
460 {
461 /* There is a plus in both operands. Note that a plus
462 sign cannot be the first character in args,
463 so the following [-1]'s are valid. */
464 if (p0[-1] == 'i' && p1[1] == 'i')
465 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
466 return 1;
467 if (p0[1] == 'i' && p1[-1] == 'i')
468 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
469 return -1;
470 }
471 }
472
473 /* They are, as far as we can tell, identical.
474 Since qsort may have rearranged the table partially, there is
475 no way to tell which one was first in the opcode table as
476 written, so just say there are equal. */
477 return 0;
478 }
This page took 0.039238 seconds and 4 git commands to generate.