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 1991/03/21 21:26:55 gumby
26 * Revision 1.1 1991/03/13 00:34:40 chrisb
29 * Revision 1.3 1991/03/09 04:36:31 rich
31 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
34 * Pulled sysdep.h out of bfd.h.
36 * Revision 1.2 1991/03/08 21:54:53 rich
38 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
39 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
40 * sparc-pinsn.c strip.c
42 * Verifying Portland tree with steve's last changes. Also, some partial
45 * Revision 1.1 1991/02/22 16:48:04 sac
53 #include "sparc-opcode.h"
56 extern int print_address();
58 static char *reg_names
[] =
59 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
60 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
61 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
62 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
63 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
64 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
65 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
66 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
67 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
69 #define freg_names (®_names[4 * 8])
73 unsigned long int code
;
92 unsigned int OP
:2, RD
:5, op3
:6, RS1
:5, i
:1;
93 unsigned int IMM13
:13;
94 #define imm13 IMM13.IMM13
102 unsigned int DISP22
:22;
103 #define disp22 branch.DISP22
109 unsigned int DISP30
:30;
110 #define disp30 call.DISP30
114 /* Nonzero if INSN is the opcode for a delayed branch. */
116 is_delayed_branch (insn
)
117 union sparc_insn insn
;
121 for (i
= 0; i
< NUMOPCODES
; ++i
)
123 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
124 if ((opcode
->match
& insn
.code
) == opcode
->match
125 && (opcode
->lose
& insn
.code
) == 0
126 && (opcode
->delayed
))
132 static int opcodes_sorted
= 0;
134 /* Print one instruction from MEMADDR on STREAM. */
136 print_insn_sparc (memaddr
, buffer
, stream
)
142 union sparc_insn insn
;
144 register unsigned int i
;
148 static int compare_opcodes ();
149 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
150 sizeof (sparc_opcodes
[0]), compare_opcodes
);
154 memcpy(&insn
,buffer
, sizeof (insn
));
156 for (i
= 0; i
< NUMOPCODES
; ++i
)
158 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
159 if ((opcode
->match
& insn
.code
) == opcode
->match
160 && (opcode
->lose
& insn
.code
) == 0)
162 /* Nonzero means that we have found an instruction which has
163 the effect of adding or or'ing the imm13 field to rs1. */
164 int imm_added_to_rs1
= 0;
166 /* Nonzero means that we have found a plus sign in the args
167 field of the opcode table. */
170 /* Do we have an 'or' instruction where rs1 is the same
171 as rsd, and which has the i bit set? */
172 if (opcode
->match
== 0x80102000
173 && insn
.rs1
== insn
.rd
)
174 imm_added_to_rs1
= 1;
176 if (index (opcode
->args
, 'S') != 0)
177 /* Reject the special case for `set'.
178 The real `sethi' will match. */
180 if (insn
.rs1
!= insn
.rd
181 && index (opcode
->args
, 'r') != 0)
182 /* Can't do simple format if source and dest are different. */
185 fputs (opcode
->name
, stream
);
188 register const char *s
;
190 if (opcode
->args
[0] != ',')
192 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
211 /* note fall-through */
213 fprintf (stream
, "%c", *s
);
220 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
235 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
249 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
264 fprintf (stream
, "%%hi(%#x)",
265 (unsigned int) insn
.imm22
<< 10);
270 /* We cannot trust the compiler to sign-extend
271 when extracting the bitfield, hence the shifts. */
272 int imm
= ((int) insn
.imm13
<< 19) >> 19;
274 /* Check to see whether we have a 1+i, and take
277 Note: because of the way we sort the table,
278 we will be matching 1+i rather than i+1,
279 so it is OK to assume that i is after +,
282 imm_added_to_rs1
= 1;
285 fprintf (stream
, "%d", imm
);
287 fprintf (stream
, "%#x", (unsigned) imm
);
292 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
297 if ((insn
.code
>> 22) == 0)
298 /* Special case for `unimp'. Don't try to turn
299 it's operand into a function offset. */
300 fprintf (stream
, "%#x",
301 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
303 /* We cannot trust the compiler to sign-extend
304 when extracting the bitfield, hence the shifts. */
305 print_address ((bfd_vma
)
307 + (((int) insn
.disp22
<< 10) >> 10) * 4),
312 fprintf (stream
, "(%d)", (int) insn
.asi
);
316 fputs ("%csr", stream
);
320 fputs ("%fsr", stream
);
324 fputs ("%psr", stream
);
328 fputs ("%fq", stream
);
332 fputs ("%cq", stream
);
336 fputs ("%tbr", stream
);
340 fputs ("%wim", stream
);
344 fputs ("%y", stream
);
350 /* If we are adding or or'ing something to rs1, then
351 check to see whether the previous instruction was
352 a sethi to the same register as in the sethi.
353 If so, attempt to print the result of the add or
354 or (in this context add and or do the same thing)
355 and its symbolic value. */
356 if (imm_added_to_rs1
)
358 union sparc_insn prev_insn
;
361 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
365 /* If it is a delayed branch, we need to look at the
366 instruction before the delayed branch. This handles
369 sethi %o1, %hi(_foo), %o1
371 or %o1, %lo(_foo), %o1
374 if (is_delayed_branch (prev_insn
))
375 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
379 /* If there was a problem reading memory, then assume
380 the previous instruction was not sethi. */
383 /* Is it sethi to the same register? */
384 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
385 && prev_insn
.rd
== insn
.rs1
)
387 fprintf (stream
, "\t! ");
388 /* We cannot trust the compiler to sign-extend
389 when extracting the bitfield, hence the shifts. */
390 print_address (((int) prev_insn
.imm22
<< 10)
391 | (insn
.imm13
<< 19) >> 19, stream
);
396 return sizeof (insn
);
400 fprintf ("%#8x", insn
.code
);
401 return sizeof (insn
);
405 /* Compare opcodes A and B. */
408 compare_opcodes (a
, b
)
411 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
412 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
413 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
414 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
415 register unsigned int i
;
417 /* If a bit is set in both match and lose, there is something
418 wrong with the opcode table. */
421 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
422 op0
->name
, match0
, lose0
);
423 op0
->lose
&= ~op0
->match
;
429 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
430 op1
->name
, match1
, lose1
);
431 op1
->lose
&= ~op1
->match
;
435 /* Because the bits that are variable in one opcode are constant in
436 another, it is important to order the opcodes in the right order. */
437 for (i
= 0; i
< 32; ++i
)
439 unsigned long int x
= 1 << i
;
440 int x0
= (match0
& x
) != 0;
441 int x1
= (match1
& x
) != 0;
447 for (i
= 0; i
< 32; ++i
)
449 unsigned long int x
= 1 << i
;
450 int x0
= (lose0
& x
) != 0;
451 int x1
= (lose1
& x
) != 0;
457 /* They are functionally equal. So as long as the opcode table is
458 valid, we can put whichever one first we want, on aesthetic grounds. */
460 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
461 if (length_diff
!= 0)
462 /* Put the one with fewer arguments first. */
466 /* Put 1+i before i+1. */
468 char *p0
= (char *) index(op0
->args
, '+');
469 char *p1
= (char *) index(op1
->args
, '+');
473 /* There is a plus in both operands. Note that a plus
474 sign cannot be the first character in args,
475 so the following [-1]'s are valid. */
476 if (p0
[-1] == 'i' && p1
[1] == 'i')
477 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
479 if (p0
[1] == 'i' && p1
[-1] == 'i')
480 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
485 /* They are, as far as we can tell, identical.
486 Since qsort may have rearranged the table partially, there is
487 no way to tell which one was first in the opcode table as
488 written, so just say there are equal. */
This page took 0.054626 seconds and 4 git commands to generate.