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.1.1.1 1991/03/21 21:26:56 gumby
24 Back from Intel with Steve
26 * Revision 1.1 1991/03/21 21:26:55 gumby
29 * Revision 1.1 1991/03/13 00:34:40 chrisb
32 * Revision 1.3 1991/03/09 04:36:31 rich
34 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
37 * Pulled sysdep.h out of bfd.h.
39 * Revision 1.2 1991/03/08 21:54:53 rich
41 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
42 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
43 * sparc-pinsn.c strip.c
45 * Verifying Portland tree with steve's last changes. Also, some partial
48 * Revision 1.1 1991/02/22 16:48:04 sac
56 #include "sparc-opcode.h"
59 extern int print_address();
61 static char *reg_names
[] =
62 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
63 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
64 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
65 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
66 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
67 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
68 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
69 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
70 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
72 #define freg_names (®_names[4 * 8])
76 unsigned long int code
;
95 unsigned int OP
:2, RD
:5, op3
:6, RS1
:5, i
:1;
96 unsigned int IMM13
:13;
97 #define imm13 IMM13.IMM13
105 unsigned int DISP22
:22;
106 #define disp22 branch.DISP22
112 unsigned int DISP30
:30;
113 #define disp30 call.DISP30
117 /* Nonzero if INSN is the opcode for a delayed branch. */
119 is_delayed_branch (insn
)
120 union sparc_insn insn
;
124 for (i
= 0; i
< NUMOPCODES
; ++i
)
126 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
127 if ((opcode
->match
& insn
.code
) == opcode
->match
128 && (opcode
->lose
& insn
.code
) == 0
129 && (opcode
->delayed
))
135 static int opcodes_sorted
= 0;
137 /* Print one instruction from MEMADDR on STREAM. */
139 print_insn_sparc (memaddr
, buffer
, stream
)
145 union sparc_insn insn
;
147 register unsigned int i
;
151 static int compare_opcodes ();
152 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
153 sizeof (sparc_opcodes
[0]), compare_opcodes
);
157 memcpy(&insn
,buffer
, sizeof (insn
));
159 for (i
= 0; i
< NUMOPCODES
; ++i
)
161 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
162 if ((opcode
->match
& insn
.code
) == opcode
->match
163 && (opcode
->lose
& insn
.code
) == 0)
165 /* Nonzero means that we have found an instruction which has
166 the effect of adding or or'ing the imm13 field to rs1. */
167 int imm_added_to_rs1
= 0;
169 /* Nonzero means that we have found a plus sign in the args
170 field of the opcode table. */
173 /* Do we have an 'or' instruction where rs1 is the same
174 as rsd, and which has the i bit set? */
175 if (opcode
->match
== 0x80102000
176 && insn
.rs1
== insn
.rd
)
177 imm_added_to_rs1
= 1;
179 if (index (opcode
->args
, 'S') != 0)
180 /* Reject the special case for `set'.
181 The real `sethi' will match. */
183 if (insn
.rs1
!= insn
.rd
184 && index (opcode
->args
, 'r') != 0)
185 /* Can't do simple format if source and dest are different. */
188 fputs (opcode
->name
, stream
);
191 register const char *s
;
193 if (opcode
->args
[0] != ',')
195 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
214 /* note fall-through */
216 fprintf (stream
, "%c", *s
);
223 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
238 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
252 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
267 fprintf (stream
, "%%hi(%#x)",
268 (unsigned int) insn
.imm22
<< 10);
273 /* We cannot trust the compiler to sign-extend
274 when extracting the bitfield, hence the shifts. */
275 int imm
= ((int) insn
.imm13
<< 19) >> 19;
277 /* Check to see whether we have a 1+i, and take
280 Note: because of the way we sort the table,
281 we will be matching 1+i rather than i+1,
282 so it is OK to assume that i is after +,
285 imm_added_to_rs1
= 1;
288 fprintf (stream
, "%d", imm
);
290 fprintf (stream
, "%#x", (unsigned) imm
);
295 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
300 if ((insn
.code
>> 22) == 0)
301 /* Special case for `unimp'. Don't try to turn
302 it's operand into a function offset. */
303 fprintf (stream
, "%#x",
304 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
306 /* We cannot trust the compiler to sign-extend
307 when extracting the bitfield, hence the shifts. */
308 print_address ((bfd_vma
)
310 + (((int) insn
.disp22
<< 10) >> 10) * 4),
315 fprintf (stream
, "(%d)", (int) insn
.asi
);
319 fputs ("%csr", stream
);
323 fputs ("%fsr", stream
);
327 fputs ("%psr", stream
);
331 fputs ("%fq", stream
);
335 fputs ("%cq", stream
);
339 fputs ("%tbr", stream
);
343 fputs ("%wim", stream
);
347 fputs ("%y", stream
);
353 /* If we are adding or or'ing something to rs1, then
354 check to see whether the previous instruction was
355 a sethi to the same register as in the sethi.
356 If so, attempt to print the result of the add or
357 or (in this context add and or do the same thing)
358 and its symbolic value. */
359 if (imm_added_to_rs1
)
361 union sparc_insn prev_insn
;
364 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
368 /* If it is a delayed branch, we need to look at the
369 instruction before the delayed branch. This handles
372 sethi %o1, %hi(_foo), %o1
374 or %o1, %lo(_foo), %o1
377 if (is_delayed_branch (prev_insn
))
378 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
382 /* If there was a problem reading memory, then assume
383 the previous instruction was not sethi. */
386 /* Is it sethi to the same register? */
387 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
388 && prev_insn
.rd
== insn
.rs1
)
390 fprintf (stream
, "\t! ");
391 /* We cannot trust the compiler to sign-extend
392 when extracting the bitfield, hence the shifts. */
393 print_address (((int) prev_insn
.imm22
<< 10)
394 | (insn
.imm13
<< 19) >> 19, stream
);
399 return sizeof (insn
);
403 fprintf ("%#8x", insn
.code
);
404 return sizeof (insn
);
408 /* Compare opcodes A and B. */
411 compare_opcodes (a
, b
)
414 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
415 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
416 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
417 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
418 register unsigned int i
;
420 /* If a bit is set in both match and lose, there is something
421 wrong with the opcode table. */
424 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
425 op0
->name
, match0
, lose0
);
426 op0
->lose
&= ~op0
->match
;
432 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
433 op1
->name
, match1
, lose1
);
434 op1
->lose
&= ~op1
->match
;
438 /* Because the bits that are variable in one opcode are constant in
439 another, it is important to order the opcodes in the right order. */
440 for (i
= 0; i
< 32; ++i
)
442 unsigned long int x
= 1 << i
;
443 int x0
= (match0
& x
) != 0;
444 int x1
= (match1
& x
) != 0;
450 for (i
= 0; i
< 32; ++i
)
452 unsigned long int x
= 1 << i
;
453 int x0
= (lose0
& x
) != 0;
454 int x1
= (lose1
& x
) != 0;
460 /* They are functionally equal. So as long as the opcode table is
461 valid, we can put whichever one first we want, on aesthetic grounds. */
463 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
464 if (length_diff
!= 0)
465 /* Put the one with fewer arguments first. */
469 /* Put 1+i before i+1. */
471 char *p0
= (char *) index(op0
->args
, '+');
472 char *p1
= (char *) index(op1
->args
, '+');
476 /* There is a plus in both operands. Note that a plus
477 sign cannot be the first character in args,
478 so the following [-1]'s are valid. */
479 if (p0
[-1] == 'i' && p1
[1] == 'i')
480 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
482 if (p0
[1] == 'i' && p1
[-1] == 'i')
483 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
488 /* They are, as far as we can tell, identical.
489 Since qsort may have rearranged the table partially, there is
490 no way to tell which one was first in the opcode table as
491 written, so just say there are equal. */