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.5 1991/05/22 01:40:35 rich
26 * Revision 1.4 1991/05/22 01:17:48 rich
29 * Revision 1.3 1991/05/19 08:00:57 rich
30 * Updated to relect a gdb change in sparc-opcode.h.
32 * Revision 1.2 1991/04/18 21:14:21 steve
33 * Send the right # of args to an fprintf
35 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
36 * Back from Intel with Steve
38 * Revision 1.1 1991/03/21 21:26:55 gumby
41 * Revision 1.1 1991/03/13 00:34:40 chrisb
44 * Revision 1.3 1991/03/09 04:36:31 rich
46 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
49 * Pulled sysdep.h out of bfd.h.
51 * Revision 1.2 1991/03/08 21:54:53 rich
53 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
54 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
55 * sparc-pinsn.c strip.c
57 * Verifying Portland tree with steve's last changes. Also, some partial
60 * Revision 1.1 1991/02/22 16:48:04 sac
68 #include "sparc-opcode.h"
71 extern int print_address();
73 static char *reg_names
[] =
74 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
75 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
76 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
77 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
78 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
79 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
80 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
81 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
82 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
84 #define freg_names (®_names[4 * 8])
88 unsigned long int code
;
100 #define asi ldst._ASI
102 #define rs2 ldst._RS2
107 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
108 unsigned int IMM13
:13;
109 #define imm13 IMM13.IMM13
117 unsigned int DISP22
:22;
118 #define disp22 branch.DISP22
123 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
124 unsigned int DISP14
:14;
125 #define disp14 DISP14.DISP14
134 unsigned int DISP21
:21;
135 #define disp21 branch2.DISP21
143 unsigned int DISP30
:30;
144 #define disp30 call.DISP30
148 /* Nonzero if INSN is the opcode for a delayed branch. */
150 is_delayed_branch (insn
)
151 union sparc_insn insn
;
155 for (i
= 0; i
< NUMOPCODES
; ++i
)
157 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
158 if ((opcode
->match
& insn
.code
) == opcode
->match
159 && (opcode
->lose
& insn
.code
) == 0
160 && (opcode
->flags
&F_DELAYED
))
166 static int opcodes_sorted
= 0;
168 /* Print one instruction from MEMADDR on STREAM. */
170 print_insn_sparc (memaddr
, buffer
, stream
)
176 union sparc_insn insn
;
178 register unsigned int i
;
182 static int compare_opcodes ();
183 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
184 sizeof (sparc_opcodes
[0]), compare_opcodes
);
188 memcpy(&insn
,buffer
, sizeof (insn
));
190 for (i
= 0; i
< NUMOPCODES
; ++i
)
192 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
193 if ((opcode
->match
& insn
.code
) == opcode
->match
194 && (opcode
->lose
& insn
.code
) == 0)
196 /* Nonzero means that we have found an instruction which has
197 the effect of adding or or'ing the imm13 field to rs1. */
198 int imm_added_to_rs1
= 0;
200 /* Nonzero means that we have found a plus sign in the args
201 field of the opcode table. */
204 /* Do we have an 'or' instruction where rs1 is the same
205 as rsd, and which has the i bit set? */
206 if (opcode
->match
== 0x80102000
207 && insn
.rs1
== insn
.rd
)
208 imm_added_to_rs1
= 1;
210 if (index (opcode
->args
, 'S') != 0)
211 /* Reject the special case for `set'.
212 The real `sethi' will match. */
214 if (insn
.rs1
!= insn
.rd
215 && index (opcode
->args
, 'r') != 0)
216 /* Can't do simple format if source and dest are different. */
219 fputs (opcode
->name
, stream
);
222 register const char *s
;
224 if (opcode
->args
[0] != ',')
226 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
250 } /* switch on arg */
251 } /* while there are comma started args */
260 /* note fall-through */
262 fprintf (stream
, "%c", *s
);
269 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
284 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
298 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
313 fprintf (stream
, "%%hi(%#x)",
314 (unsigned int) insn
.imm22
<< 10);
319 /* We cannot trust the compiler to sign-extend
320 when extracting the bitfield, hence the shifts. */
321 int imm
= ((int) insn
.imm13
<< 19) >> 19;
323 /* Check to see whether we have a 1+i, and take
326 Note: because of the way we sort the table,
327 we will be matching 1+i rather than i+1,
328 so it is OK to assume that i is after +,
331 imm_added_to_rs1
= 1;
334 fprintf (stream
, "%d", imm
);
336 fprintf (stream
, "%#x", (unsigned) imm
);
342 print_address ((bfd_vma
)
344 + (((int) insn
.disp14
<< 18) >> 18) * 4),
349 print_address ((bfd_vma
)
351 + (((int) insn
.disp21
<< 11) >> 11) * 4),
356 fputs ("%amr", stream
);
362 fprintf(stream
, "%%asr%d", insn
.rs1
);
366 fprintf(stream
, "%%asr%d", insn
.rd
);
370 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
375 if ((insn
.code
>> 22) == 0)
376 /* Special case for `unimp'. Don't try to turn
377 it's operand into a function offset. */
378 fprintf (stream
, "%#x",
379 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
381 /* We cannot trust the compiler to sign-extend
382 when extracting the bitfield, hence the shifts. */
383 print_address ((bfd_vma
)
385 + (((int) insn
.disp22
<< 10) >> 10) * 4),
390 fprintf (stream
, "(%d)", (int) insn
.asi
);
394 fputs ("%csr", stream
);
398 fputs ("%fsr", stream
);
402 fputs ("%psr", stream
);
406 fputs ("%fq", stream
);
410 fputs ("%cq", stream
);
414 fputs ("%tbr", stream
);
418 fputs ("%wim", stream
);
422 fputs ("%y", stream
);
428 /* If we are adding or or'ing something to rs1, then
429 check to see whether the previous instruction was
430 a sethi to the same register as in the sethi.
431 If so, attempt to print the result of the add or
432 or (in this context add and or do the same thing)
433 and its symbolic value. */
434 if (imm_added_to_rs1
)
436 union sparc_insn prev_insn
;
439 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
443 /* If it is a delayed branch, we need to look at the
444 instruction before the delayed branch. This handles
447 sethi %o1, %hi(_foo), %o1
449 or %o1, %lo(_foo), %o1
452 if (is_delayed_branch (prev_insn
))
453 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
457 /* If there was a problem reading memory, then assume
458 the previous instruction was not sethi. */
461 /* Is it sethi to the same register? */
462 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
463 && prev_insn
.rd
== insn
.rs1
)
465 fprintf (stream
, "\t! ");
466 /* We cannot trust the compiler to sign-extend
467 when extracting the bitfield, hence the shifts. */
468 print_address (((int) prev_insn
.imm22
<< 10)
469 | (insn
.imm13
<< 19) >> 19, stream
);
474 return sizeof (insn
);
478 fprintf (stream
, "%#8x", insn
.code
);
479 return sizeof (insn
);
483 /* Compare opcodes A and B. */
486 compare_opcodes (a
, b
)
489 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
490 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
491 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
492 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
493 register unsigned int i
;
495 /* If a bit is set in both match and lose, there is something
496 wrong with the opcode table. */
499 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
500 op0
->name
, match0
, lose0
);
501 op0
->lose
&= ~op0
->match
;
507 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
508 op1
->name
, match1
, lose1
);
509 op1
->lose
&= ~op1
->match
;
513 /* Because the bits that are variable in one opcode are constant in
514 another, it is important to order the opcodes in the right order. */
515 for (i
= 0; i
< 32; ++i
)
517 unsigned long int x
= 1 << i
;
518 int x0
= (match0
& x
) != 0;
519 int x1
= (match1
& x
) != 0;
525 for (i
= 0; i
< 32; ++i
)
527 unsigned long int x
= 1 << i
;
528 int x0
= (lose0
& x
) != 0;
529 int x1
= (lose1
& x
) != 0;
535 /* They are functionally equal. So as long as the opcode table is
536 valid, we can put whichever one first we want, on aesthetic grounds. */
538 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
539 if (length_diff
!= 0)
540 /* Put the one with fewer arguments first. */
544 /* Put 1+i before i+1. */
546 char *p0
= (char *) index(op0
->args
, '+');
547 char *p1
= (char *) index(op1
->args
, '+');
551 /* There is a plus in both operands. Note that a plus
552 sign cannot be the first character in args,
553 so the following [-1]'s are valid. */
554 if (p0
[-1] == 'i' && p1
[1] == 'i')
555 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
557 if (p0
[1] == 'i' && p1
[-1] == 'i')
558 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
563 /* They are, as far as we can tell, identical.
564 Since qsort may have rearranged the table partially, there is
565 no way to tell which one was first in the opcode table as
566 written, so just say there are equal. */