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