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