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