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