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.3 1991/05/19 08:00:57 rich
24 Updated to relect a gdb change in sparc-opcode.h.
26 * Revision 1.2 1991/04/18 21:14:21 steve
27 * Send the right # of args to an fprintf
29 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
30 * Back from Intel with Steve
32 * Revision 1.1 1991/03/21 21:26:55 gumby
35 * Revision 1.1 1991/03/13 00:34:40 chrisb
38 * Revision 1.3 1991/03/09 04:36:31 rich
40 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
43 * Pulled sysdep.h out of bfd.h.
45 * Revision 1.2 1991/03/08 21:54:53 rich
47 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
48 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
49 * sparc-pinsn.c strip.c
51 * Verifying Portland tree with steve's last changes. Also, some partial
54 * Revision 1.1 1991/02/22 16:48:04 sac
62 #include "sparc-opcode.h"
65 extern int print_address();
67 static char *reg_names
[] =
68 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
69 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
70 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
71 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
72 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
73 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
74 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
75 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
76 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
78 #define freg_names (®_names[4 * 8])
82 unsigned long int code
;
101 unsigned int OP
:2, RD
:5, op3
:6, RS1
:5, i
:1;
102 unsigned int IMM13
:13;
103 #define imm13 IMM13.IMM13
111 unsigned int DISP22
:22;
112 #define disp22 branch.DISP22
118 unsigned int DISP30
:30;
119 #define disp30 call.DISP30
123 /* Nonzero if INSN is the opcode for a delayed branch. */
125 is_delayed_branch (insn
)
126 union sparc_insn insn
;
130 for (i
= 0; i
< NUMOPCODES
; ++i
)
132 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
133 if ((opcode
->match
& insn
.code
) == opcode
->match
134 && (opcode
->lose
& insn
.code
) == 0
135 && (opcode
->flags
&F_DELAYED
))
141 static int opcodes_sorted
= 0;
143 /* Print one instruction from MEMADDR on STREAM. */
145 print_insn_sparc (memaddr
, buffer
, stream
)
151 union sparc_insn insn
;
153 register unsigned int i
;
157 static int compare_opcodes ();
158 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
159 sizeof (sparc_opcodes
[0]), compare_opcodes
);
163 memcpy(&insn
,buffer
, sizeof (insn
));
165 for (i
= 0; i
< NUMOPCODES
; ++i
)
167 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
168 if ((opcode
->match
& insn
.code
) == opcode
->match
169 && (opcode
->lose
& insn
.code
) == 0)
171 /* Nonzero means that we have found an instruction which has
172 the effect of adding or or'ing the imm13 field to rs1. */
173 int imm_added_to_rs1
= 0;
175 /* Nonzero means that we have found a plus sign in the args
176 field of the opcode table. */
179 /* Do we have an 'or' instruction where rs1 is the same
180 as rsd, and which has the i bit set? */
181 if (opcode
->match
== 0x80102000
182 && insn
.rs1
== insn
.rd
)
183 imm_added_to_rs1
= 1;
185 if (index (opcode
->args
, 'S') != 0)
186 /* Reject the special case for `set'.
187 The real `sethi' will match. */
189 if (insn
.rs1
!= insn
.rd
190 && index (opcode
->args
, 'r') != 0)
191 /* Can't do simple format if source and dest are different. */
194 fputs (opcode
->name
, stream
);
197 register const char *s
;
199 if (opcode
->args
[0] != ',')
201 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
220 /* note fall-through */
222 fprintf (stream
, "%c", *s
);
229 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
244 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
258 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
273 fprintf (stream
, "%%hi(%#x)",
274 (unsigned int) insn
.imm22
<< 10);
279 /* We cannot trust the compiler to sign-extend
280 when extracting the bitfield, hence the shifts. */
281 int imm
= ((int) insn
.imm13
<< 19) >> 19;
283 /* Check to see whether we have a 1+i, and take
286 Note: because of the way we sort the table,
287 we will be matching 1+i rather than i+1,
288 so it is OK to assume that i is after +,
291 imm_added_to_rs1
= 1;
294 fprintf (stream
, "%d", imm
);
296 fprintf (stream
, "%#x", (unsigned) imm
);
301 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
306 if ((insn
.code
>> 22) == 0)
307 /* Special case for `unimp'. Don't try to turn
308 it's operand into a function offset. */
309 fprintf (stream
, "%#x",
310 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
312 /* We cannot trust the compiler to sign-extend
313 when extracting the bitfield, hence the shifts. */
314 print_address ((bfd_vma
)
316 + (((int) insn
.disp22
<< 10) >> 10) * 4),
321 fprintf (stream
, "(%d)", (int) insn
.asi
);
325 fputs ("%csr", stream
);
329 fputs ("%fsr", stream
);
333 fputs ("%psr", stream
);
337 fputs ("%fq", stream
);
341 fputs ("%cq", stream
);
345 fputs ("%tbr", stream
);
349 fputs ("%wim", stream
);
353 fputs ("%y", stream
);
359 /* If we are adding or or'ing something to rs1, then
360 check to see whether the previous instruction was
361 a sethi to the same register as in the sethi.
362 If so, attempt to print the result of the add or
363 or (in this context add and or do the same thing)
364 and its symbolic value. */
365 if (imm_added_to_rs1
)
367 union sparc_insn prev_insn
;
370 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
374 /* If it is a delayed branch, we need to look at the
375 instruction before the delayed branch. This handles
378 sethi %o1, %hi(_foo), %o1
380 or %o1, %lo(_foo), %o1
383 if (is_delayed_branch (prev_insn
))
384 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
388 /* If there was a problem reading memory, then assume
389 the previous instruction was not sethi. */
392 /* Is it sethi to the same register? */
393 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
394 && prev_insn
.rd
== insn
.rs1
)
396 fprintf (stream
, "\t! ");
397 /* We cannot trust the compiler to sign-extend
398 when extracting the bitfield, hence the shifts. */
399 print_address (((int) prev_insn
.imm22
<< 10)
400 | (insn
.imm13
<< 19) >> 19, stream
);
405 return sizeof (insn
);
409 fprintf (stream
, "%#8x", insn
.code
);
410 return sizeof (insn
);
414 /* Compare opcodes A and B. */
417 compare_opcodes (a
, b
)
420 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
421 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
422 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
423 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
424 register unsigned int i
;
426 /* If a bit is set in both match and lose, there is something
427 wrong with the opcode table. */
430 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
431 op0
->name
, match0
, lose0
);
432 op0
->lose
&= ~op0
->match
;
438 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
439 op1
->name
, match1
, lose1
);
440 op1
->lose
&= ~op1
->match
;
444 /* Because the bits that are variable in one opcode are constant in
445 another, it is important to order the opcodes in the right order. */
446 for (i
= 0; i
< 32; ++i
)
448 unsigned long int x
= 1 << i
;
449 int x0
= (match0
& x
) != 0;
450 int x1
= (match1
& x
) != 0;
456 for (i
= 0; i
< 32; ++i
)
458 unsigned long int x
= 1 << i
;
459 int x0
= (lose0
& x
) != 0;
460 int x1
= (lose1
& x
) != 0;
466 /* They are functionally equal. So as long as the opcode table is
467 valid, we can put whichever one first we want, on aesthetic grounds. */
469 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
470 if (length_diff
!= 0)
471 /* Put the one with fewer arguments first. */
475 /* Put 1+i before i+1. */
477 char *p0
= (char *) index(op0
->args
, '+');
478 char *p1
= (char *) index(op1
->args
, '+');
482 /* There is a plus in both operands. Note that a plus
483 sign cannot be the first character in args,
484 so the following [-1]'s are valid. */
485 if (p0
[-1] == 'i' && p1
[1] == 'i')
486 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
488 if (p0
[1] == 'i' && p1
[-1] == 'i')
489 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
494 /* They are, as far as we can tell, identical.
495 Since qsort may have rearranged the table partially, there is
496 no way to tell which one was first in the opcode table as
497 written, so just say there are equal. */