* Makefile.in: Change mkscript rule into one for ./mkscript
[deliverable/binutils-gdb.git] / gdb / sparc-pinsn.c
CommitLineData
7d9884b9
JG
1/* Print SPARC instructions for GDB, the GNU Debugger.
2 Copyright 1989, 1991 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB, the GNU disassembler.
5
99a7de40 6This program is free software; you can redistribute it and/or modify
dd3b648e 7it under the terms of the GNU General Public License as published by
99a7de40
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
dd3b648e 10
99a7de40 11This program is distributed in the hope that it will be useful,
dd3b648e
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
99a7de40
JG
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e
RP
19
20#include <stdio.h>
21
22#include "defs.h"
dd3b648e 23#include "symtab.h"
7e258d18 24#include "opcode/sparc.h"
dd3b648e
RP
25#include "gdbcore.h"
26#include "string.h"
27#include "target.h"
28
dd3b648e
RP
29extern char *reg_names[];
30#define freg_names (&reg_names[4 * 8])
31
32union sparc_insn
33 {
34 unsigned long int code;
35 struct
36 {
1a4d253c
JG
37 unsigned int anop:2;
38#define op ldst.anop
39 unsigned int anrd:5;
40#define rd ldst.anrd
dd3b648e 41 unsigned int op3:6;
1a4d253c
JG
42 unsigned int anrs1:5;
43#define rs1 ldst.anrs1
dd3b648e 44 unsigned int i:1;
1a4d253c
JG
45 unsigned int anasi:8;
46#define asi ldst.anasi
47 unsigned int anrs2:5;
48#define rs2 ldst.anrs2
dd3b648e
RP
49#define shcnt rs2
50 } ldst;
51 struct
52 {
1a4d253c 53 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
dd3b648e
RP
54 unsigned int IMM13:13;
55#define imm13 IMM13.IMM13
56 } IMM13;
57 struct
58 {
1a4d253c 59 unsigned int anop:2;
dd3b648e
RP
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 {
1a4d253c
JG
69 unsigned int anop:2;
70 unsigned int adisp30:30;
71#define disp30 call.adisp30
dd3b648e
RP
72 } call;
73 };
74
75/* Nonzero if INSN is the opcode for a delayed branch. */
76static int
77is_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
4a074bea
PB
92static int opcodes_sorted = 0;
93extern void qsort ();
4a074bea 94
32c298e0
JG
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. */
dd3b648e
RP
102int
103print_insn (memaddr, stream)
104 CORE_ADDR memaddr;
105 FILE *stream;
106{
107 union sparc_insn insn;
108
109 register unsigned int i;
110
4a074bea
PB
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 }
4a074bea 118
dd3b648e
RP
119 read_memory (memaddr, &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
32c298e0 135 /* Do we have an `add' or `or' instruction where rs1 is the same
dd3b648e 136 as rsd, and which has the i bit set? */
32c298e0
JG
137 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
138 /* (or) (add) */
dd3b648e
RP
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':
4a074bea
PB
199 case 'v': /* double/even */
200 case 'V': /* quad/multiple of 4 */
dd3b648e
RP
201 freg (insn.rs1);
202 break;
203
204 case 'f':
4a074bea
PB
205 case 'B': /* double/even */
206 case 'R': /* quad/multiple of 4 */
dd3b648e
RP
207 freg (insn.rs2);
208 break;
209
210 case 'g':
4a074bea
PB
211 case 'H': /* double/even */
212 case 'J': /* quad/multiple of 4 */
dd3b648e
RP
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
aab77d5f 245 FIXME: No longer true/relavant ???
dd3b648e
RP
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}
4a074bea 373
4a074bea
PB
374/* Compare opcodes A and B. */
375
376static int
377compare_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. */
32c298e0 442 return i;
4a074bea 443 else
32c298e0
JG
444 fprintf (stderr,
445 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
446 op0->name, op1->name);
4a074bea
PB
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.067827 seconds and 4 git commands to generate.