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