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.8 1991/06/14 22:54:48 steve
24 *** empty log message ***
26 * Revision 1.6 1991/05/23 03:49:10 rich
27 * new sparc-opcode, new pinsn.
29 * Revision 1.5 1991/05/22 01:40:35 rich
32 * Revision 1.4 1991/05/22 01:17:48 rich
35 * Revision 1.3 1991/05/19 08:00:57 rich
36 * Updated to relect a gdb change in sparc-opcode.h.
38 * Revision 1.2 1991/04/18 21:14:21 steve
39 * Send the right # of args to an fprintf
41 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
42 * Back from Intel with Steve
44 * Revision 1.1 1991/03/21 21:26:55 gumby
47 * Revision 1.1 1991/03/13 00:34:40 chrisb
50 * Revision 1.3 1991/03/09 04:36:31 rich
52 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
55 * Pulled sysdep.h out of bfd.h.
57 * Revision 1.2 1991/03/08 21:54:53 rich
59 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
60 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
61 * sparc-pinsn.c strip.c
63 * Verifying Portland tree with steve's last changes. Also, some partial
66 * Revision 1.1 1991/02/22 16:48:04 sac
73 #include "sparc-opcode.h"
76 extern int print_address();
78 static char *reg_names
[] =
79 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
80 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
81 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
82 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
83 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
84 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
85 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
86 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
87 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
89 #define freg_names (®_names[4 * 8])
93 unsigned long int code
;
102 #define rs1 ldst._RS1
105 #define asi ldst._ASI
107 #define rs2 ldst._RS2
112 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
113 unsigned int IMM13
:13;
114 #define imm13 IMM13.IMM13
122 unsigned int DISP22
:22;
123 #define disp22 branch.DISP22
128 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
129 unsigned int DISP14
:14;
130 #define disp14 DISP14.DISP14
139 unsigned int DISP21
:21;
140 #define disp21 branch2.DISP21
148 unsigned int _DISP30
:30;
149 #define disp30 call._DISP30
153 /* Nonzero if INSN is the opcode for a delayed branch. */
155 is_delayed_branch (insn
)
156 union sparc_insn insn
;
160 for (i
= 0; i
< NUMOPCODES
; ++i
)
162 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
163 if ((opcode
->match
& insn
.code
) == opcode
->match
164 && (opcode
->lose
& insn
.code
) == 0
165 && (opcode
->flags
&F_DELAYED
))
171 static int opcodes_sorted
= 0;
173 /* Print one instruction from MEMADDR on STREAM. */
175 print_insn_sparc (memaddr
, buffer
, stream
)
181 union sparc_insn insn
;
183 register unsigned int i
;
187 static int compare_opcodes ();
188 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
189 sizeof (sparc_opcodes
[0]), compare_opcodes
);
193 memcpy(&insn
,buffer
, sizeof (insn
));
195 for (i
= 0; i
< NUMOPCODES
; ++i
)
197 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
198 if ((opcode
->match
& insn
.code
) == opcode
->match
199 && (opcode
->lose
& insn
.code
) == 0)
201 /* Nonzero means that we have found an instruction which has
202 the effect of adding or or'ing the imm13 field to rs1. */
203 int imm_added_to_rs1
= 0;
205 /* Nonzero means that we have found a plus sign in the args
206 field of the opcode table. */
209 /* Do we have an 'or' instruction where rs1 is the same
210 as rsd, and which has the i bit set? */
211 if (opcode
->match
== 0x80102000
212 && insn
.rs1
== insn
.rd
)
213 imm_added_to_rs1
= 1;
215 if (index (opcode
->args
, 'S') != 0)
216 /* Reject the special case for `set'.
217 The real `sethi' will match. */
219 if (insn
.rs1
!= insn
.rd
220 && index (opcode
->args
, 'r') != 0)
221 /* Can't do simple format if source and dest are different. */
224 fputs (opcode
->name
, stream
);
227 register const char *s
;
229 if (opcode
->args
[0] != ',')
231 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
255 } /* switch on arg */
256 } /* while there are comma started args */
265 /* note fall-through */
267 fprintf (stream
, "%c", *s
);
274 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
289 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
303 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
318 fprintf (stream
, "%%hi(%#x)",
319 (unsigned int) insn
.imm22
<< 10);
324 /* We cannot trust the compiler to sign-extend
325 when extracting the bitfield, hence the shifts. */
326 int imm
= ((int) insn
.imm13
<< 19) >> 19;
328 /* Check to see whether we have a 1+i, and take
331 Note: because of the way we sort the table,
332 we will be matching 1+i rather than i+1,
333 so it is OK to assume that i is after +,
336 imm_added_to_rs1
= 1;
339 fprintf (stream
, "%d", imm
);
341 fprintf (stream
, "%#x", (unsigned) imm
);
347 print_address ((bfd_vma
)
349 + (((int) insn
.disp14
<< 18) >> 18) * 4),
354 print_address ((bfd_vma
)
356 + (((int) insn
.disp21
<< 11) >> 11) * 4),
361 fputs ("%amr", stream
);
367 fprintf(stream
, "%%asr%d", insn
.rs1
);
371 fprintf(stream
, "%%asr%d", insn
.rd
);
375 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
380 if ((insn
.code
>> 22) == 0)
381 /* Special case for `unimp'. Don't try to turn
382 it's operand into a function offset. */
383 fprintf (stream
, "%#x",
384 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
386 /* We cannot trust the compiler to sign-extend
387 when extracting the bitfield, hence the shifts. */
388 print_address ((bfd_vma
)
390 + (((int) insn
.disp22
<< 10) >> 10) * 4),
395 fprintf (stream
, "(%d)", (int) insn
.asi
);
399 fputs ("%csr", stream
);
403 fputs ("%fsr", stream
);
407 fputs ("%psr", stream
);
411 fputs ("%fq", stream
);
415 fputs ("%cq", stream
);
419 fputs ("%tbr", stream
);
423 fputs ("%wim", stream
);
427 fputs ("%y", stream
);
433 /* If we are adding or or'ing something to rs1, then
434 check to see whether the previous instruction was
435 a sethi to the same register as in the sethi.
436 If so, attempt to print the result of the add or
437 or (in this context add and or do the same thing)
438 and its symbolic value. */
439 if (imm_added_to_rs1
)
441 union sparc_insn prev_insn
;
444 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
448 /* If it is a delayed branch, we need to look at the
449 instruction before the delayed branch. This handles
452 sethi %o1, %hi(_foo), %o1
454 or %o1, %lo(_foo), %o1
457 if (is_delayed_branch (prev_insn
))
458 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
462 /* If there was a problem reading memory, then assume
463 the previous instruction was not sethi. */
466 /* Is it sethi to the same register? */
467 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
468 && prev_insn
.rd
== insn
.rs1
)
470 fprintf (stream
, "\t! ");
471 /* We cannot trust the compiler to sign-extend
472 when extracting the bitfield, hence the shifts. */
473 print_address (((int) prev_insn
.imm22
<< 10)
474 | (insn
.imm13
<< 19) >> 19, stream
);
479 return sizeof (insn
);
483 fprintf (stream
, "%#8x", insn
.code
);
484 return sizeof (insn
);
488 /* Compare opcodes A and B. */
491 compare_opcodes (a
, b
)
494 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
495 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
496 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
497 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
498 register unsigned int i
;
500 /* If a bit is set in both match and lose, there is something
501 wrong with the opcode table. */
504 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
505 op0
->name
, match0
, lose0
);
506 op0
->lose
&= ~op0
->match
;
512 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
513 op1
->name
, match1
, lose1
);
514 op1
->lose
&= ~op1
->match
;
518 /* Because the bits that are variable in one opcode are constant in
519 another, it is important to order the opcodes in the right order. */
520 for (i
= 0; i
< 32; ++i
)
522 unsigned long int x
= 1 << i
;
523 int x0
= (match0
& x
) != 0;
524 int x1
= (match1
& x
) != 0;
530 for (i
= 0; i
< 32; ++i
)
532 unsigned long int x
= 1 << i
;
533 int x0
= (lose0
& x
) != 0;
534 int x1
= (lose1
& x
) != 0;
540 /* They are functionally equal. So as long as the opcode table is
541 valid, we can put whichever one first we want, on aesthetic grounds. */
543 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
544 if (length_diff
!= 0)
545 /* Put the one with fewer arguments first. */
549 /* Put 1+i before i+1. */
551 char *p0
= (char *) index(op0
->args
, '+');
552 char *p1
= (char *) index(op1
->args
, '+');
556 /* There is a plus in both operands. Note that a plus
557 sign cannot be the first character in args,
558 so the following [-1]'s are valid. */
559 if (p0
[-1] == 'i' && p1
[1] == 'i')
560 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
562 if (p0
[1] == 'i' && p1
[-1] == 'i')
563 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
568 /* They are, as far as we can tell, identical.
569 Since qsort may have rearranged the table partially, there is
570 no way to tell which one was first in the opcode table as
571 written, so just say there are equal. */