1 /* disassemble sparc instructions for objdump
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
5 This file is part of the binutils.
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)
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.
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. */
23 Revision 1.2 1991/04/18 21:14:21 steve
24 Send the right # of args to an fprintf
26 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
27 * Back from Intel with Steve
29 * Revision 1.1 1991/03/21 21:26:55 gumby
32 * Revision 1.1 1991/03/13 00:34:40 chrisb
35 * Revision 1.3 1991/03/09 04:36:31 rich
37 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
40 * Pulled sysdep.h out of bfd.h.
42 * Revision 1.2 1991/03/08 21:54:53 rich
44 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
45 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
46 * sparc-pinsn.c strip.c
48 * Verifying Portland tree with steve's last changes. Also, some partial
51 * Revision 1.1 1991/02/22 16:48:04 sac
59 #include "sparc-opcode.h"
62 extern int print_address();
64 static char *reg_names
[] =
65 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
66 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
67 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
68 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
69 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
70 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
71 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
72 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
73 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
75 #define freg_names (®_names[4 * 8])
79 unsigned long int code
;
98 unsigned int OP
:2, RD
:5, op3
:6, RS1
:5, i
:1;
99 unsigned int IMM13
:13;
100 #define imm13 IMM13.IMM13
108 unsigned int DISP22
:22;
109 #define disp22 branch.DISP22
115 unsigned int DISP30
:30;
116 #define disp30 call.DISP30
120 /* Nonzero if INSN is the opcode for a delayed branch. */
122 is_delayed_branch (insn
)
123 union sparc_insn insn
;
127 for (i
= 0; i
< NUMOPCODES
; ++i
)
129 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
130 if ((opcode
->match
& insn
.code
) == opcode
->match
131 && (opcode
->lose
& insn
.code
) == 0
132 && (opcode
->delayed
))
138 static int opcodes_sorted
= 0;
140 /* Print one instruction from MEMADDR on STREAM. */
142 print_insn_sparc (memaddr
, buffer
, stream
)
148 union sparc_insn insn
;
150 register unsigned int i
;
154 static int compare_opcodes ();
155 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
156 sizeof (sparc_opcodes
[0]), compare_opcodes
);
160 memcpy(&insn
,buffer
, sizeof (insn
));
162 for (i
= 0; i
< NUMOPCODES
; ++i
)
164 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
165 if ((opcode
->match
& insn
.code
) == opcode
->match
166 && (opcode
->lose
& insn
.code
) == 0)
168 /* Nonzero means that we have found an instruction which has
169 the effect of adding or or'ing the imm13 field to rs1. */
170 int imm_added_to_rs1
= 0;
172 /* Nonzero means that we have found a plus sign in the args
173 field of the opcode table. */
176 /* Do we have an 'or' instruction where rs1 is the same
177 as rsd, and which has the i bit set? */
178 if (opcode
->match
== 0x80102000
179 && insn
.rs1
== insn
.rd
)
180 imm_added_to_rs1
= 1;
182 if (index (opcode
->args
, 'S') != 0)
183 /* Reject the special case for `set'.
184 The real `sethi' will match. */
186 if (insn
.rs1
!= insn
.rd
187 && index (opcode
->args
, 'r') != 0)
188 /* Can't do simple format if source and dest are different. */
191 fputs (opcode
->name
, stream
);
194 register const char *s
;
196 if (opcode
->args
[0] != ',')
198 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
217 /* note fall-through */
219 fprintf (stream
, "%c", *s
);
226 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
241 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
255 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
270 fprintf (stream
, "%%hi(%#x)",
271 (unsigned int) insn
.imm22
<< 10);
276 /* We cannot trust the compiler to sign-extend
277 when extracting the bitfield, hence the shifts. */
278 int imm
= ((int) insn
.imm13
<< 19) >> 19;
280 /* Check to see whether we have a 1+i, and take
283 Note: because of the way we sort the table,
284 we will be matching 1+i rather than i+1,
285 so it is OK to assume that i is after +,
288 imm_added_to_rs1
= 1;
291 fprintf (stream
, "%d", imm
);
293 fprintf (stream
, "%#x", (unsigned) imm
);
298 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
303 if ((insn
.code
>> 22) == 0)
304 /* Special case for `unimp'. Don't try to turn
305 it's operand into a function offset. */
306 fprintf (stream
, "%#x",
307 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
309 /* We cannot trust the compiler to sign-extend
310 when extracting the bitfield, hence the shifts. */
311 print_address ((bfd_vma
)
313 + (((int) insn
.disp22
<< 10) >> 10) * 4),
318 fprintf (stream
, "(%d)", (int) insn
.asi
);
322 fputs ("%csr", stream
);
326 fputs ("%fsr", stream
);
330 fputs ("%psr", stream
);
334 fputs ("%fq", stream
);
338 fputs ("%cq", stream
);
342 fputs ("%tbr", stream
);
346 fputs ("%wim", stream
);
350 fputs ("%y", stream
);
356 /* If we are adding or or'ing something to rs1, then
357 check to see whether the previous instruction was
358 a sethi to the same register as in the sethi.
359 If so, attempt to print the result of the add or
360 or (in this context add and or do the same thing)
361 and its symbolic value. */
362 if (imm_added_to_rs1
)
364 union sparc_insn prev_insn
;
367 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
371 /* If it is a delayed branch, we need to look at the
372 instruction before the delayed branch. This handles
375 sethi %o1, %hi(_foo), %o1
377 or %o1, %lo(_foo), %o1
380 if (is_delayed_branch (prev_insn
))
381 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
385 /* If there was a problem reading memory, then assume
386 the previous instruction was not sethi. */
389 /* Is it sethi to the same register? */
390 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
391 && prev_insn
.rd
== insn
.rs1
)
393 fprintf (stream
, "\t! ");
394 /* We cannot trust the compiler to sign-extend
395 when extracting the bitfield, hence the shifts. */
396 print_address (((int) prev_insn
.imm22
<< 10)
397 | (insn
.imm13
<< 19) >> 19, stream
);
402 return sizeof (insn
);
406 fprintf (stream
, "%#8x", insn
.code
);
407 return sizeof (insn
);
411 /* Compare opcodes A and B. */
414 compare_opcodes (a
, b
)
417 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
418 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
419 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
420 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
421 register unsigned int i
;
423 /* If a bit is set in both match and lose, there is something
424 wrong with the opcode table. */
427 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
428 op0
->name
, match0
, lose0
);
429 op0
->lose
&= ~op0
->match
;
435 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
436 op1
->name
, match1
, lose1
);
437 op1
->lose
&= ~op1
->match
;
441 /* Because the bits that are variable in one opcode are constant in
442 another, it is important to order the opcodes in the right order. */
443 for (i
= 0; i
< 32; ++i
)
445 unsigned long int x
= 1 << i
;
446 int x0
= (match0
& x
) != 0;
447 int x1
= (match1
& x
) != 0;
453 for (i
= 0; i
< 32; ++i
)
455 unsigned long int x
= 1 << i
;
456 int x0
= (lose0
& x
) != 0;
457 int x1
= (lose1
& x
) != 0;
463 /* They are functionally equal. So as long as the opcode table is
464 valid, we can put whichever one first we want, on aesthetic grounds. */
466 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
467 if (length_diff
!= 0)
468 /* Put the one with fewer arguments first. */
472 /* Put 1+i before i+1. */
474 char *p0
= (char *) index(op0
->args
, '+');
475 char *p1
= (char *) index(op1
->args
, '+');
479 /* There is a plus in both operands. Note that a plus
480 sign cannot be the first character in args,
481 so the following [-1]'s are valid. */
482 if (p0
[-1] == 'i' && p1
[1] == 'i')
483 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
485 if (p0
[1] == 'i' && p1
[-1] == 'i')
486 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
491 /* They are, as far as we can tell, identical.
492 Since qsort may have rearranged the table partially, there is
493 no way to tell which one was first in the opcode table as
494 written, so just say there are equal. */