Wed Jun 10 07:53:24 1992 Steve Chamberlain (sac@thepub.cygnus.com)
[deliverable/binutils-gdb.git] / binutils / sparc-pinsn.c
CommitLineData
2fa0b342 1/* disassemble sparc instructions for objdump
d8474a9b 2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
2fa0b342
DHW
3
4
5This file is part of the binutils.
6
7The binutils are free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
d8474a9b 9the Free Software Foundation; either version 2, or (at your option)
2fa0b342
DHW
10any later version.
11
12The binutils are distributed in the hope that they will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with the binutils; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
2a5f387b 21/* $Id$ */
2fa0b342 22
2a5f387b 23#include "bfd.h"
2fa0b342 24#include "sysdep.h"
17e6f61f 25#include <stdio.h>
4aa58a0a 26#include "opcode/sparc.h"
5a77e916 27#include "objdump.h"
2fa0b342
DHW
28extern int print_address();
29
30static 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
43union sparc_insn
44 {
45 unsigned long int code;
46 struct
47 {
839df5c3
RP
48 unsigned int _OP:2;
49#define op ldst._OP
50 unsigned int _RD:5;
51#define rd ldst._RD
2fa0b342 52 unsigned int op3:6;
839df5c3
RP
53 unsigned int _RS1:5;
54#define rs1 ldst._RS1
2fa0b342 55 unsigned int i:1;
839df5c3
RP
56 unsigned int _ASI:8;
57#define asi ldst._ASI
58 unsigned int _RS2:5;
59#define rs2 ldst._RS2
2fa0b342
DHW
60#define shcnt rs2
61 } ldst;
62 struct
63 {
839df5c3 64 unsigned int _OP:2, _RD:5, op3:6, _RS1:5, i:1;
2fa0b342
DHW
65 unsigned int IMM13:13;
66#define imm13 IMM13.IMM13
67 } IMM13;
68 struct
69 {
839df5c3 70 unsigned int _OP:2;
2fa0b342
DHW
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;
839df5c3
RP
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;
c64cf848 92#define disp21 branch2.DISP21
839df5c3
RP
93 } branch2;
94#endif /* NO_V9 */
95
2fa0b342
DHW
96#define imm22 disp22
97 struct
98 {
839df5c3 99 unsigned int _OP:2;
320484bf
RP
100 unsigned int _DISP30:30;
101#define disp30 call._DISP30
2fa0b342
DHW
102 } call;
103 };
104
105/* Nonzero if INSN is the opcode for a delayed branch. */
106static int
107is_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
bb50293f 117 && (opcode->flags&F_DELAYED))
2fa0b342
DHW
118 return 1;
119 }
120 return 0;
121}
122
123static int opcodes_sorted = 0;
124
125/* Print one instruction from MEMADDR on STREAM. */
126int
127print_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
145memcpy(&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);
76d89cb1
MT
183 for (s = opcode->args; *s != '\0'; ++s)
184 {
185 while (*s == ',')
186 {
187 fputs (",", stream);
188 ++s;
189
190 switch (*s) {
191 case 'a':
192 fputs ("a", stream);
193 ++s;
194 continue;
839df5c3 195#ifndef NO_V9
76d89cb1
MT
196 case 'N':
197 fputs("pn", stream);
198 ++s;
199 continue;
200
201 case 'T':
202 fputs("pt", stream);
203 ++s;
204 continue;
205#endif /* NO_V9 */
206
207 default:
208 break;
209 } /* switch on arg */
210 } /* while there are comma started args */
839df5c3
RP
211
212 fputs (" ", stream);
213
2fa0b342
DHW
214 switch (*s)
215 {
216 case '+':
217 found_plus = 1;
218
219 /* note fall-through */
220 default:
221 fprintf (stream, "%c", *s);
222 break;
223
224 case '#':
225 fputs ("0", stream);
226 break;
227
228#define reg(n) fprintf (stream, "%%%s", reg_names[n])
229 case '1':
230 case 'r':
231 reg (insn.rs1);
232 break;
233
234 case '2':
235 reg (insn.rs2);
236 break;
237
238 case 'd':
239 reg (insn.rd);
240 break;
241#undef reg
242
243#define freg(n) fprintf (stream, "%%%s", freg_names[n])
244 case 'e':
6f34472d
PB
245 case 'v': /* double/even */
246 case 'V': /* quad/multiple of 4 */
2fa0b342
DHW
247 freg (insn.rs1);
248 break;
249
250 case 'f':
6f34472d
PB
251 case 'B': /* double/even */
252 case 'R': /* quad/multiple of 4 */
2fa0b342
DHW
253 freg (insn.rs2);
254 break;
255
6f34472d 256#ifndef NO_V9
d17c317c 257/* Somebody who know needs to define rs3.
6f34472d 258 case 'j':
d17c317c
PB
259 case 'u': * double/even *
260 case 'U': * quad/multiple of 4 *
6f34472d
PB
261 freg (insn.rs3);
262 break;
d17c317c 263*/
6f34472d
PB
264#endif /* NO_V9 */
265
2fa0b342 266 case 'g':
6f34472d
PB
267 case 'H': /* double/even */
268 case 'J': /* quad/multiple of 4 */
2fa0b342
DHW
269 freg (insn.rd);
270 break;
271#undef freg
272
273#define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
274 case 'b':
275 creg (insn.rs1);
276 break;
277
278 case 'c':
279 creg (insn.rs2);
280 break;
281
282 case 'D':
283 creg (insn.rd);
284 break;
285#undef creg
286
287 case 'h':
288 fprintf (stream, "%%hi(%#x)",
76d89cb1 289 (unsigned int) insn.imm22 << 10);
2fa0b342
DHW
290 break;
291
292 case 'i':
293 {
294 /* We cannot trust the compiler to sign-extend
295 when extracting the bitfield, hence the shifts. */
296 int imm = ((int) insn.imm13 << 19) >> 19;
297
298 /* Check to see whether we have a 1+i, and take
299 note of that fact.
76d89cb1 300
2fa0b342
DHW
301 Note: because of the way we sort the table,
302 we will be matching 1+i rather than i+1,
303 so it is OK to assume that i is after +,
304 not before it. */
305 if (found_plus)
306 imm_added_to_rs1 = 1;
307
308 if (imm <= 9)
309 fprintf (stream, "%d", imm);
310 else
311 fprintf (stream, "%#x", (unsigned) imm);
312 }
313 break;
314
839df5c3
RP
315#ifndef NO_V9
316 case 'k':
317 print_address ((bfd_vma)
318 (memaddr
319 + (((int) insn.disp14 << 18) >> 18) * 4),
320 stream);
321 break;
322
5f4d1571 323 case 'G':
839df5c3
RP
324 print_address ((bfd_vma)
325 (memaddr
5f4d1571
MT
326 /* We use only 19 of the 21 bits. */
327 + (((int) insn.disp21 << 13) >> 13) * 4),
839df5c3
RP
328 stream);
329 break;
330
76d89cb1 331 case 'Y':
839df5c3
RP
332 fputs ("%amr", stream);
333 break;
334
5f4d1571
MT
335 case '6':
336 case '7':
337 case '8':
338 case '9':
339 fprintf (stream, "fcc%c", *s - '6' + '0');
340 break;
341
342 case 'z':
343 fputs ("icc", stream);
344 break;
345
346 case 'Z':
347 fputs ("xcc", stream);
348 break;
76d89cb1 349#endif /* NO_V9 */
839df5c3 350
76d89cb1 351 case 'M':
839df5c3
RP
352 fprintf(stream, "%%asr%d", insn.rs1);
353 break;
354
76d89cb1 355 case 'm':
839df5c3
RP
356 fprintf(stream, "%%asr%d", insn.rd);
357 break;
358
76d89cb1 359 case 'L':
2fa0b342
DHW
360 print_address ((bfd_vma) memaddr + insn.disp30 * 4,
361 stream);
362 break;
363
364 case 'l':
365 if ((insn.code >> 22) == 0)
366 /* Special case for `unimp'. Don't try to turn
367 it's operand into a function offset. */
368 fprintf (stream, "%#x",
76d89cb1 369 (unsigned) (((int) insn.disp22 << 10) >> 10));
2fa0b342
DHW
370 else
371 /* We cannot trust the compiler to sign-extend
372 when extracting the bitfield, hence the shifts. */
373 print_address ((bfd_vma)
374 (memaddr
375 + (((int) insn.disp22 << 10) >> 10) * 4),
376 stream);
377 break;
378
379 case 'A':
380 fprintf (stream, "(%d)", (int) insn.asi);
381 break;
382
383 case 'C':
384 fputs ("%csr", stream);
385 break;
386
387 case 'F':
388 fputs ("%fsr", stream);
389 break;
390
391 case 'p':
392 fputs ("%psr", stream);
393 break;
394
395 case 'q':
396 fputs ("%fq", stream);
397 break;
398
399 case 'Q':
400 fputs ("%cq", stream);
401 break;
402
403 case 't':
404 fputs ("%tbr", stream);
405 break;
406
407 case 'w':
408 fputs ("%wim", stream);
409 break;
410
411 case 'y':
412 fputs ("%y", stream);
413 break;
414 }
415 }
416 }
417
418 /* If we are adding or or'ing something to rs1, then
419 check to see whether the previous instruction was
420 a sethi to the same register as in the sethi.
421 If so, attempt to print the result of the add or
422 or (in this context add and or do the same thing)
423 and its symbolic value. */
424 if (imm_added_to_rs1)
425 {
426 union sparc_insn prev_insn;
5a77e916 427 int errcode = 0;
2fa0b342
DHW
428
429 memcpy(&prev_insn, buffer -4, sizeof (prev_insn));
430
431 if (errcode == 0)
432 {
433 /* If it is a delayed branch, we need to look at the
434 instruction before the delayed branch. This handles
435 sequences such as
436
437 sethi %o1, %hi(_foo), %o1
438 call _printf
439 or %o1, %lo(_foo), %o1
440 */
441
442 if (is_delayed_branch (prev_insn))
443 memcpy(&prev_insn, buffer - 8, sizeof(prev_insn));
444
445 }
446
447 /* If there was a problem reading memory, then assume
448 the previous instruction was not sethi. */
449 if (errcode == 0)
450 {
451 /* Is it sethi to the same register? */
452 if ((prev_insn.code & 0xc1c00000) == 0x01000000
453 && prev_insn.rd == insn.rs1)
454 {
455 fprintf (stream, "\t! ");
456 /* We cannot trust the compiler to sign-extend
457 when extracting the bitfield, hence the shifts. */
458 print_address (((int) prev_insn.imm22 << 10)
459 | (insn.imm13 << 19) >> 19, stream);
460 }
461 }
462 }
463
464 return sizeof (insn);
465 }
466 }
467
75a082e2 468 fprintf (stream, "%#8x", insn.code);
2fa0b342
DHW
469 return sizeof (insn);
470}
471
472
473/* Compare opcodes A and B. */
474
475static int
476compare_opcodes (a, b)
477 char *a, *b;
478{
479 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
480 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
481 unsigned long int match0 = op0->match, match1 = op1->match;
482 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
483 register unsigned int i;
484
485 /* If a bit is set in both match and lose, there is something
486 wrong with the opcode table. */
487 if (match0 & lose0)
488 {
489 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
490 op0->name, match0, lose0);
491 op0->lose &= ~op0->match;
492 lose0 = op0->lose;
493 }
494
495 if (match1 & lose1)
496 {
497 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
498 op1->name, match1, lose1);
499 op1->lose &= ~op1->match;
500 lose1 = op1->lose;
501 }
502
503 /* Because the bits that are variable in one opcode are constant in
504 another, it is important to order the opcodes in the right order. */
505 for (i = 0; i < 32; ++i)
506 {
507 unsigned long int x = 1 << i;
508 int x0 = (match0 & x) != 0;
509 int x1 = (match1 & x) != 0;
510
511 if (x0 != x1)
512 return x1 - x0;
513 }
514
515 for (i = 0; i < 32; ++i)
516 {
517 unsigned long int x = 1 << i;
518 int x0 = (lose0 & x) != 0;
519 int x1 = (lose1 & x) != 0;
520
521 if (x0 != x1)
522 return x1 - x0;
523 }
524
525 /* They are functionally equal. So as long as the opcode table is
526 valid, we can put whichever one first we want, on aesthetic grounds. */
527 {
528 int length_diff = strlen (op0->args) - strlen (op1->args);
529 if (length_diff != 0)
530 /* Put the one with fewer arguments first. */
531 return length_diff;
532 }
533
534 /* Put 1+i before i+1. */
535 {
536 char *p0 = (char *) index(op0->args, '+');
537 char *p1 = (char *) index(op1->args, '+');
538
539 if (p0 && p1)
540 {
541 /* There is a plus in both operands. Note that a plus
542 sign cannot be the first character in args,
543 so the following [-1]'s are valid. */
544 if (p0[-1] == 'i' && p1[1] == 'i')
545 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
546 return 1;
547 if (p0[1] == 'i' && p1[-1] == 'i')
548 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
549 return -1;
550 }
551 }
552
553 /* They are, as far as we can tell, identical.
554 Since qsort may have rearranged the table partially, there is
555 no way to tell which one was first in the opcode table as
556 written, so just say there are equal. */
557 return 0;
558}
This page took 0.073111 seconds and 4 git commands to generate.