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