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.4 1991/05/22 01:17:48 rich
26 * Revision 1.3 1991/05/19 08:00:57 rich
27 * Updated to relect a gdb change in sparc-opcode.h.
29 * Revision 1.2 1991/04/18 21:14:21 steve
30 * Send the right # of args to an fprintf
32 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
33 * Back from Intel with Steve
35 * Revision 1.1 1991/03/21 21:26:55 gumby
38 * Revision 1.1 1991/03/13 00:34:40 chrisb
41 * Revision 1.3 1991/03/09 04:36:31 rich
43 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
46 * Pulled sysdep.h out of bfd.h.
48 * Revision 1.2 1991/03/08 21:54:53 rich
50 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
51 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
52 * sparc-pinsn.c strip.c
54 * Verifying Portland tree with steve's last changes. Also, some partial
57 * Revision 1.1 1991/02/22 16:48:04 sac
65 #include "sparc-opcode.h"
68 extern int print_address();
70 static char *reg_names
[] =
71 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
72 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
73 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
74 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
75 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
76 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
77 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
78 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
79 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
81 #define freg_names (®_names[4 * 8])
85 unsigned long int code
;
104 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
105 unsigned int IMM13
:13;
106 #define imm13 IMM13.IMM13
114 unsigned int DISP22
:22;
115 #define disp22 branch.DISP22
120 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
121 unsigned int DISP14
:14;
122 #define disp14 DISP14.DISP14
131 unsigned int DISP21
:21;
132 #define disp21 branch.DISP21
140 unsigned int DISP30
:30;
141 #define disp30 call.DISP30
145 /* Nonzero if INSN is the opcode for a delayed branch. */
147 is_delayed_branch (insn
)
148 union sparc_insn insn
;
152 for (i
= 0; i
< NUMOPCODES
; ++i
)
154 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
155 if ((opcode
->match
& insn
.code
) == opcode
->match
156 && (opcode
->lose
& insn
.code
) == 0
157 && (opcode
->flags
&F_DELAYED
))
163 static int opcodes_sorted
= 0;
165 /* Print one instruction from MEMADDR on STREAM. */
167 print_insn_sparc (memaddr
, buffer
, stream
)
173 union sparc_insn insn
;
175 register unsigned int i
;
179 static int compare_opcodes ();
180 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
181 sizeof (sparc_opcodes
[0]), compare_opcodes
);
185 memcpy(&insn
,buffer
, sizeof (insn
));
187 for (i
= 0; i
< NUMOPCODES
; ++i
)
189 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
190 if ((opcode
->match
& insn
.code
) == opcode
->match
191 && (opcode
->lose
& insn
.code
) == 0)
193 /* Nonzero means that we have found an instruction which has
194 the effect of adding or or'ing the imm13 field to rs1. */
195 int imm_added_to_rs1
= 0;
197 /* Nonzero means that we have found a plus sign in the args
198 field of the opcode table. */
201 /* Do we have an 'or' instruction where rs1 is the same
202 as rsd, and which has the i bit set? */
203 if (opcode
->match
== 0x80102000
204 && insn
.rs1
== insn
.rd
)
205 imm_added_to_rs1
= 1;
207 if (index (opcode
->args
, 'S') != 0)
208 /* Reject the special case for `set'.
209 The real `sethi' will match. */
211 if (insn
.rs1
!= insn
.rd
212 && index (opcode
->args
, 'r') != 0)
213 /* Can't do simple format if source and dest are different. */
216 fputs (opcode
->name
, stream
);
219 register const char *s
;
221 if (opcode
->args
[0] != ',')
223 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
247 } /* switch on arg */
248 } /* while there are comma started args */
257 /* note fall-through */
259 fprintf (stream
, "%c", *s
);
266 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
281 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
295 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
310 fprintf (stream
, "%%hi(%#x)",
311 (unsigned int) insn
.imm22
<< 10);
316 /* We cannot trust the compiler to sign-extend
317 when extracting the bitfield, hence the shifts. */
318 int imm
= ((int) insn
.imm13
<< 19) >> 19;
320 /* Check to see whether we have a 1+i, and take
323 Note: because of the way we sort the table,
324 we will be matching 1+i rather than i+1,
325 so it is OK to assume that i is after +,
328 imm_added_to_rs1
= 1;
331 fprintf (stream
, "%d", imm
);
333 fprintf (stream
, "%#x", (unsigned) imm
);
339 print_address ((bfd_vma
)
341 + (((int) insn
.disp14
<< 18) >> 18) * 4),
346 print_address ((bfd_vma
)
348 + (((int) insn
.disp21
<< 11) >> 11) * 4),
353 fputs ("%amr", stream
);
359 fprintf(stream
, "%%asr%d", insn
.rs1
);
363 fprintf(stream
, "%%asr%d", insn
.rd
);
367 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
372 if ((insn
.code
>> 22) == 0)
373 /* Special case for `unimp'. Don't try to turn
374 it's operand into a function offset. */
375 fprintf (stream
, "%#x",
376 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
378 /* We cannot trust the compiler to sign-extend
379 when extracting the bitfield, hence the shifts. */
380 print_address ((bfd_vma
)
382 + (((int) insn
.disp22
<< 10) >> 10) * 4),
387 fprintf (stream
, "(%d)", (int) insn
.asi
);
391 fputs ("%csr", stream
);
395 fputs ("%fsr", stream
);
399 fputs ("%psr", stream
);
403 fputs ("%fq", stream
);
407 fputs ("%cq", stream
);
411 fputs ("%tbr", stream
);
415 fputs ("%wim", stream
);
419 fputs ("%y", stream
);
425 /* If we are adding or or'ing something to rs1, then
426 check to see whether the previous instruction was
427 a sethi to the same register as in the sethi.
428 If so, attempt to print the result of the add or
429 or (in this context add and or do the same thing)
430 and its symbolic value. */
431 if (imm_added_to_rs1
)
433 union sparc_insn prev_insn
;
436 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
440 /* If it is a delayed branch, we need to look at the
441 instruction before the delayed branch. This handles
444 sethi %o1, %hi(_foo), %o1
446 or %o1, %lo(_foo), %o1
449 if (is_delayed_branch (prev_insn
))
450 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
454 /* If there was a problem reading memory, then assume
455 the previous instruction was not sethi. */
458 /* Is it sethi to the same register? */
459 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
460 && prev_insn
.rd
== insn
.rs1
)
462 fprintf (stream
, "\t! ");
463 /* We cannot trust the compiler to sign-extend
464 when extracting the bitfield, hence the shifts. */
465 print_address (((int) prev_insn
.imm22
<< 10)
466 | (insn
.imm13
<< 19) >> 19, stream
);
471 return sizeof (insn
);
475 fprintf (stream
, "%#8x", insn
.code
);
476 return sizeof (insn
);
480 /* Compare opcodes A and B. */
483 compare_opcodes (a
, b
)
486 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
487 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
488 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
489 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
490 register unsigned int i
;
492 /* If a bit is set in both match and lose, there is something
493 wrong with the opcode table. */
496 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
497 op0
->name
, match0
, lose0
);
498 op0
->lose
&= ~op0
->match
;
504 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
505 op1
->name
, match1
, lose1
);
506 op1
->lose
&= ~op1
->match
;
510 /* Because the bits that are variable in one opcode are constant in
511 another, it is important to order the opcodes in the right order. */
512 for (i
= 0; i
< 32; ++i
)
514 unsigned long int x
= 1 << i
;
515 int x0
= (match0
& x
) != 0;
516 int x1
= (match1
& x
) != 0;
522 for (i
= 0; i
< 32; ++i
)
524 unsigned long int x
= 1 << i
;
525 int x0
= (lose0
& x
) != 0;
526 int x1
= (lose1
& x
) != 0;
532 /* They are functionally equal. So as long as the opcode table is
533 valid, we can put whichever one first we want, on aesthetic grounds. */
535 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
536 if (length_diff
!= 0)
537 /* Put the one with fewer arguments first. */
541 /* Put 1+i before i+1. */
543 char *p0
= (char *) index(op0
->args
, '+');
544 char *p1
= (char *) index(op1
->args
, '+');
548 /* There is a plus in both operands. Note that a plus
549 sign cannot be the first character in args,
550 so the following [-1]'s are valid. */
551 if (p0
[-1] == 'i' && p1
[1] == 'i')
552 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
554 if (p0
[1] == 'i' && p1
[-1] == 'i')
555 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
560 /* They are, as far as we can tell, identical.
561 Since qsort may have rearranged the table partially, there is
562 no way to tell which one was first in the opcode table as
563 written, so just say there are equal. */