* bucomm.h: created to hold prototypes of bucomm.c
[deliverable/binutils-gdb.git] / binutils / sparc-pinsn.c
1 /* disassemble sparc instructions for objdump
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
3
4
5 This file is part of the binutils.
6
7 The binutils are free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 The binutils are distributed in the hope that they will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with the binutils; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /* $Id$ */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include <stdio.h>
26 #include "opcode/sparc.h"
27 #include "objdump.h"
28 extern int print_address();
29
30 static char *reg_names[] =
31 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
32 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
33 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
34 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
35 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
36 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
37 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
38 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
39 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
40
41 #define freg_names (&reg_names[4 * 8])
42
43 union sparc_insn
44 {
45 unsigned long int code;
46 struct
47 {
48 unsigned int _OP:2;
49 #define op ldst._OP
50 unsigned int _RD:5;
51 #define rd ldst._RD
52 unsigned int op3:6;
53 unsigned int _RS1:5;
54 #define rs1 ldst._RS1
55 unsigned int i:1;
56 unsigned int _ASI:8;
57 #define asi ldst._ASI
58 unsigned int _RS2:5;
59 #define rs2 ldst._RS2
60 #define shcnt rs2
61 } ldst;
62 struct
63 {
64 unsigned int _OP:2, _RD:5, op3:6, _RS1:5, i:1;
65 unsigned int IMM13:13;
66 #define imm13 IMM13.IMM13
67 } IMM13;
68 struct
69 {
70 unsigned int _OP:2;
71 unsigned int a:1;
72 unsigned int cond:4;
73 unsigned int op2:3;
74 unsigned int DISP22:22;
75 #define disp22 branch.DISP22
76 } branch;
77 #ifndef NO_V9
78 struct
79 {
80 unsigned int _OP:2, _RD:5, op3:6, _RS1:5;
81 unsigned int DISP14:14;
82 #define disp14 DISP14.DISP14
83 } DISP14;
84 struct
85 {
86 unsigned int _OP:2;
87 unsigned int a:1;
88 unsigned int cond:4;
89 unsigned int op2:3;
90 unsigned int p:1;
91 unsigned int DISP21:21;
92 #define disp21 branch2.DISP21
93 } branch2;
94 #endif /* NO_V9 */
95
96 #define imm22 disp22
97 struct
98 {
99 unsigned int _OP:2;
100 unsigned int _DISP30:30;
101 #define disp30 call._DISP30
102 } call;
103 };
104
105 /* Nonzero if INSN is the opcode for a delayed branch. */
106 static int
107 is_delayed_branch (insn)
108 union sparc_insn insn;
109 {
110 unsigned int i;
111
112 for (i = 0; i < NUMOPCODES; ++i)
113 {
114 const struct sparc_opcode *opcode = &sparc_opcodes[i];
115 if ((opcode->match & insn.code) == opcode->match
116 && (opcode->lose & insn.code) == 0
117 && (opcode->flags&F_DELAYED))
118 return 1;
119 }
120 return 0;
121 }
122
123 static int opcodes_sorted = 0;
124
125 /* Print one instruction from MEMADDR on STREAM. */
126 int
127 print_insn_sparc (memaddr, buffer, stream)
128 bfd_vma memaddr;
129 bfd_byte *buffer;
130 FILE *stream;
131
132 {
133 union sparc_insn insn;
134
135 register unsigned int i;
136
137 if (!opcodes_sorted)
138 {
139 static int compare_opcodes ();
140 qsort ((char *) sparc_opcodes, NUMOPCODES,
141 sizeof (sparc_opcodes[0]), compare_opcodes);
142 opcodes_sorted = 1;
143 }
144
145 memcpy(&insn,buffer, sizeof (insn));
146
147 for (i = 0; i < NUMOPCODES; ++i)
148 {
149 const struct sparc_opcode *opcode = &sparc_opcodes[i];
150 if ((opcode->match & insn.code) == opcode->match
151 && (opcode->lose & insn.code) == 0)
152 {
153 /* Nonzero means that we have found an instruction which has
154 the effect of adding or or'ing the imm13 field to rs1. */
155 int imm_added_to_rs1 = 0;
156
157 /* Nonzero means that we have found a plus sign in the args
158 field of the opcode table. */
159 int found_plus = 0;
160
161 /* Do we have an 'or' instruction where rs1 is the same
162 as rsd, and which has the i bit set? */
163 if (opcode->match == 0x80102000
164 && insn.rs1 == insn.rd)
165 imm_added_to_rs1 = 1;
166
167 if (index (opcode->args, 'S') != 0)
168 /* Reject the special case for `set'.
169 The real `sethi' will match. */
170 continue;
171 if (insn.rs1 != insn.rd
172 && index (opcode->args, 'r') != 0)
173 /* Can't do simple format if source and dest are different. */
174 continue;
175
176 fputs (opcode->name, stream);
177
178 {
179 register const char *s;
180
181 if (opcode->args[0] != ',')
182 fputs (" ", stream);
183 for (s = opcode->args; *s != '\0'; ++s) {
184 while (*s == ',') {
185 fputs (",", stream);
186 ++s;
187
188 switch (*s) {
189 case 'a':
190 fputs ("a", stream);
191 ++s;
192 continue;
193 #ifndef NO_V9
194 case 'N':
195 fputs("pn", stream);
196 ++s;
197 continue;
198
199 case 'T':
200 fputs("pt", stream);
201 ++s;
202 continue;
203 #endif /* NO_V9 */
204
205 default:
206 break;
207 } /* switch on arg */
208 } /* while there are comma started args */
209
210 fputs (" ", stream);
211
212 switch (*s)
213 {
214 case '+':
215 found_plus = 1;
216
217 /* note fall-through */
218 default:
219 fprintf (stream, "%c", *s);
220 break;
221
222 case '#':
223 fputs ("0", stream);
224 break;
225
226 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
227 case '1':
228 case 'r':
229 reg (insn.rs1);
230 break;
231
232 case '2':
233 reg (insn.rs2);
234 break;
235
236 case 'd':
237 reg (insn.rd);
238 break;
239 #undef reg
240
241 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
242 case 'e':
243 freg (insn.rs1);
244 break;
245
246 case 'f':
247 freg (insn.rs2);
248 break;
249
250 case 'g':
251 freg (insn.rd);
252 break;
253 #undef freg
254
255 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
256 case 'b':
257 creg (insn.rs1);
258 break;
259
260 case 'c':
261 creg (insn.rs2);
262 break;
263
264 case 'D':
265 creg (insn.rd);
266 break;
267 #undef creg
268
269 case 'h':
270 fprintf (stream, "%%hi(%#x)",
271 (unsigned int) insn.imm22 << 10);
272 break;
273
274 case 'i':
275 {
276 /* We cannot trust the compiler to sign-extend
277 when extracting the bitfield, hence the shifts. */
278 int imm = ((int) insn.imm13 << 19) >> 19;
279
280 /* Check to see whether we have a 1+i, and take
281 note of that fact.
282
283 Note: because of the way we sort the table,
284 we will be matching 1+i rather than i+1,
285 so it is OK to assume that i is after +,
286 not before it. */
287 if (found_plus)
288 imm_added_to_rs1 = 1;
289
290 if (imm <= 9)
291 fprintf (stream, "%d", imm);
292 else
293 fprintf (stream, "%#x", (unsigned) imm);
294 }
295 break;
296
297 #ifndef NO_V9
298 case 'k':
299 print_address ((bfd_vma)
300 (memaddr
301 + (((int) insn.disp14 << 18) >> 18) * 4),
302 stream);
303 break;
304
305 case 'K':
306 print_address ((bfd_vma)
307 (memaddr
308 + (((int) insn.disp21 << 11) >> 11) * 4),
309 stream);
310 break;
311
312 case 'Y':
313 fputs ("%amr", stream);
314 break;
315
316 #endif /* NO_V9 */
317
318 case 'M':
319 fprintf(stream, "%%asr%d", insn.rs1);
320 break;
321
322 case 'm':
323 fprintf(stream, "%%asr%d", insn.rd);
324 break;
325
326 case 'L':
327 print_address ((bfd_vma) memaddr + insn.disp30 * 4,
328 stream);
329 break;
330
331 case 'l':
332 if ((insn.code >> 22) == 0)
333 /* Special case for `unimp'. Don't try to turn
334 it's operand into a function offset. */
335 fprintf (stream, "%#x",
336 (unsigned) (((int) insn.disp22 << 10) >> 10));
337 else
338 /* We cannot trust the compiler to sign-extend
339 when extracting the bitfield, hence the shifts. */
340 print_address ((bfd_vma)
341 (memaddr
342 + (((int) insn.disp22 << 10) >> 10) * 4),
343 stream);
344 break;
345
346 case 'A':
347 fprintf (stream, "(%d)", (int) insn.asi);
348 break;
349
350 case 'C':
351 fputs ("%csr", stream);
352 break;
353
354 case 'F':
355 fputs ("%fsr", stream);
356 break;
357
358 case 'p':
359 fputs ("%psr", stream);
360 break;
361
362 case 'q':
363 fputs ("%fq", stream);
364 break;
365
366 case 'Q':
367 fputs ("%cq", stream);
368 break;
369
370 case 't':
371 fputs ("%tbr", stream);
372 break;
373
374 case 'w':
375 fputs ("%wim", stream);
376 break;
377
378 case 'y':
379 fputs ("%y", stream);
380 break;
381 }
382 }
383 }
384
385 /* If we are adding or or'ing something to rs1, then
386 check to see whether the previous instruction was
387 a sethi to the same register as in the sethi.
388 If so, attempt to print the result of the add or
389 or (in this context add and or do the same thing)
390 and its symbolic value. */
391 if (imm_added_to_rs1)
392 {
393 union sparc_insn prev_insn;
394 int errcode = 0;
395
396 memcpy(&prev_insn, buffer -4, sizeof (prev_insn));
397
398 if (errcode == 0)
399 {
400 /* If it is a delayed branch, we need to look at the
401 instruction before the delayed branch. This handles
402 sequences such as
403
404 sethi %o1, %hi(_foo), %o1
405 call _printf
406 or %o1, %lo(_foo), %o1
407 */
408
409 if (is_delayed_branch (prev_insn))
410 memcpy(&prev_insn, buffer - 8, sizeof(prev_insn));
411
412 }
413
414 /* If there was a problem reading memory, then assume
415 the previous instruction was not sethi. */
416 if (errcode == 0)
417 {
418 /* Is it sethi to the same register? */
419 if ((prev_insn.code & 0xc1c00000) == 0x01000000
420 && prev_insn.rd == insn.rs1)
421 {
422 fprintf (stream, "\t! ");
423 /* We cannot trust the compiler to sign-extend
424 when extracting the bitfield, hence the shifts. */
425 print_address (((int) prev_insn.imm22 << 10)
426 | (insn.imm13 << 19) >> 19, stream);
427 }
428 }
429 }
430
431 return sizeof (insn);
432 }
433 }
434
435 fprintf (stream, "%#8x", insn.code);
436 return sizeof (insn);
437 }
438
439
440 /* Compare opcodes A and B. */
441
442 static int
443 compare_opcodes (a, b)
444 char *a, *b;
445 {
446 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
447 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
448 unsigned long int match0 = op0->match, match1 = op1->match;
449 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
450 register unsigned int i;
451
452 /* If a bit is set in both match and lose, there is something
453 wrong with the opcode table. */
454 if (match0 & lose0)
455 {
456 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
457 op0->name, match0, lose0);
458 op0->lose &= ~op0->match;
459 lose0 = op0->lose;
460 }
461
462 if (match1 & lose1)
463 {
464 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
465 op1->name, match1, lose1);
466 op1->lose &= ~op1->match;
467 lose1 = op1->lose;
468 }
469
470 /* Because the bits that are variable in one opcode are constant in
471 another, it is important to order the opcodes in the right order. */
472 for (i = 0; i < 32; ++i)
473 {
474 unsigned long int x = 1 << i;
475 int x0 = (match0 & x) != 0;
476 int x1 = (match1 & x) != 0;
477
478 if (x0 != x1)
479 return x1 - x0;
480 }
481
482 for (i = 0; i < 32; ++i)
483 {
484 unsigned long int x = 1 << i;
485 int x0 = (lose0 & x) != 0;
486 int x1 = (lose1 & x) != 0;
487
488 if (x0 != x1)
489 return x1 - x0;
490 }
491
492 /* They are functionally equal. So as long as the opcode table is
493 valid, we can put whichever one first we want, on aesthetic grounds. */
494 {
495 int length_diff = strlen (op0->args) - strlen (op1->args);
496 if (length_diff != 0)
497 /* Put the one with fewer arguments first. */
498 return length_diff;
499 }
500
501 /* Put 1+i before i+1. */
502 {
503 char *p0 = (char *) index(op0->args, '+');
504 char *p1 = (char *) index(op1->args, '+');
505
506 if (p0 && p1)
507 {
508 /* There is a plus in both operands. Note that a plus
509 sign cannot be the first character in args,
510 so the following [-1]'s are valid. */
511 if (p0[-1] == 'i' && p1[1] == 'i')
512 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
513 return 1;
514 if (p0[1] == 'i' && p1[-1] == 'i')
515 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
516 return -1;
517 }
518 }
519
520 /* They are, as far as we can tell, identical.
521 Since qsort may have rearranged the table partially, there is
522 no way to tell which one was first in the opcode table as
523 written, so just say there are equal. */
524 return 0;
525 }
This page took 0.043986 seconds and 5 git commands to generate.