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.7 1991/06/09 20:38:03 rich
24 Don't sort the const array in place.
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
74 #include "sparc-opcode.h"
77 extern int print_address();
79 static char *reg_names
[] =
80 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
81 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
82 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
83 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
84 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
85 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
86 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
87 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
88 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
90 #define freg_names (®_names[4 * 8])
94 unsigned long int code
;
103 #define rs1 ldst._RS1
106 #define asi ldst._ASI
108 #define rs2 ldst._RS2
113 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
114 unsigned int IMM13
:13;
115 #define imm13 IMM13.IMM13
123 unsigned int DISP22
:22;
124 #define disp22 branch.DISP22
129 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
130 unsigned int DISP14
:14;
131 #define disp14 DISP14.DISP14
140 unsigned int DISP21
:21;
141 #define disp21 branch2.DISP21
149 unsigned int _DISP30
:30;
150 #define disp30 call._DISP30
154 /* Nonzero if INSN is the opcode for a delayed branch. */
156 is_delayed_branch (insn
)
157 union sparc_insn insn
;
161 for (i
= 0; i
< NUMOPCODES
; ++i
)
163 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
164 if ((opcode
->match
& insn
.code
) == opcode
->match
165 && (opcode
->lose
& insn
.code
) == 0
166 && (opcode
->flags
&F_DELAYED
))
172 static int opcodes_sorted
= 0;
174 /* Print one instruction from MEMADDR on STREAM. */
176 print_insn_sparc (memaddr
, buffer
, stream
)
182 union sparc_insn insn
;
184 register unsigned int i
;
189 static int compare_opcodes ();
190 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
191 sizeof (sparc_opcodes
[0]), compare_opcodes
);
196 memcpy(&insn
,buffer
, sizeof (insn
));
198 for (i
= 0; i
< NUMOPCODES
; ++i
)
200 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
201 if ((opcode
->match
& insn
.code
) == opcode
->match
202 && (opcode
->lose
& insn
.code
) == 0)
204 /* Nonzero means that we have found an instruction which has
205 the effect of adding or or'ing the imm13 field to rs1. */
206 int imm_added_to_rs1
= 0;
208 /* Nonzero means that we have found a plus sign in the args
209 field of the opcode table. */
212 /* Do we have an 'or' instruction where rs1 is the same
213 as rsd, and which has the i bit set? */
214 if (opcode
->match
== 0x80102000
215 && insn
.rs1
== insn
.rd
)
216 imm_added_to_rs1
= 1;
218 if (index (opcode
->args
, 'S') != 0)
219 /* Reject the special case for `set'.
220 The real `sethi' will match. */
222 if (insn
.rs1
!= insn
.rd
223 && index (opcode
->args
, 'r') != 0)
224 /* Can't do simple format if source and dest are different. */
227 fputs (opcode
->name
, stream
);
230 register const char *s
;
232 if (opcode
->args
[0] != ',')
234 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
258 } /* switch on arg */
259 } /* while there are comma started args */
268 /* note fall-through */
270 fprintf (stream
, "%c", *s
);
277 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
292 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
306 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
321 fprintf (stream
, "%%hi(%#x)",
322 (unsigned int) insn
.imm22
<< 10);
327 /* We cannot trust the compiler to sign-extend
328 when extracting the bitfield, hence the shifts. */
329 int imm
= ((int) insn
.imm13
<< 19) >> 19;
331 /* Check to see whether we have a 1+i, and take
334 Note: because of the way we sort the table,
335 we will be matching 1+i rather than i+1,
336 so it is OK to assume that i is after +,
339 imm_added_to_rs1
= 1;
342 fprintf (stream
, "%d", imm
);
344 fprintf (stream
, "%#x", (unsigned) imm
);
350 print_address ((bfd_vma
)
352 + (((int) insn
.disp14
<< 18) >> 18) * 4),
357 print_address ((bfd_vma
)
359 + (((int) insn
.disp21
<< 11) >> 11) * 4),
364 fputs ("%amr", stream
);
370 fprintf(stream
, "%%asr%d", insn
.rs1
);
374 fprintf(stream
, "%%asr%d", insn
.rd
);
378 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
383 if ((insn
.code
>> 22) == 0)
384 /* Special case for `unimp'. Don't try to turn
385 it's operand into a function offset. */
386 fprintf (stream
, "%#x",
387 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
389 /* We cannot trust the compiler to sign-extend
390 when extracting the bitfield, hence the shifts. */
391 print_address ((bfd_vma
)
393 + (((int) insn
.disp22
<< 10) >> 10) * 4),
398 fprintf (stream
, "(%d)", (int) insn
.asi
);
402 fputs ("%csr", stream
);
406 fputs ("%fsr", stream
);
410 fputs ("%psr", stream
);
414 fputs ("%fq", stream
);
418 fputs ("%cq", stream
);
422 fputs ("%tbr", stream
);
426 fputs ("%wim", stream
);
430 fputs ("%y", stream
);
436 /* If we are adding or or'ing something to rs1, then
437 check to see whether the previous instruction was
438 a sethi to the same register as in the sethi.
439 If so, attempt to print the result of the add or
440 or (in this context add and or do the same thing)
441 and its symbolic value. */
442 if (imm_added_to_rs1
)
444 union sparc_insn prev_insn
;
447 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
451 /* If it is a delayed branch, we need to look at the
452 instruction before the delayed branch. This handles
455 sethi %o1, %hi(_foo), %o1
457 or %o1, %lo(_foo), %o1
460 if (is_delayed_branch (prev_insn
))
461 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
465 /* If there was a problem reading memory, then assume
466 the previous instruction was not sethi. */
469 /* Is it sethi to the same register? */
470 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
471 && prev_insn
.rd
== insn
.rs1
)
473 fprintf (stream
, "\t! ");
474 /* We cannot trust the compiler to sign-extend
475 when extracting the bitfield, hence the shifts. */
476 print_address (((int) prev_insn
.imm22
<< 10)
477 | (insn
.imm13
<< 19) >> 19, stream
);
482 return sizeof (insn
);
486 fprintf (stream
, "%#8x", insn
.code
);
487 return sizeof (insn
);
491 /* Compare opcodes A and B. */
494 compare_opcodes (a
, b
)
497 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
498 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
499 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
500 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
501 register unsigned int i
;
503 /* If a bit is set in both match and lose, there is something
504 wrong with the opcode table. */
507 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
508 op0
->name
, match0
, lose0
);
509 op0
->lose
&= ~op0
->match
;
515 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
516 op1
->name
, match1
, lose1
);
517 op1
->lose
&= ~op1
->match
;
521 /* Because the bits that are variable in one opcode are constant in
522 another, it is important to order the opcodes in the right order. */
523 for (i
= 0; i
< 32; ++i
)
525 unsigned long int x
= 1 << i
;
526 int x0
= (match0
& x
) != 0;
527 int x1
= (match1
& x
) != 0;
533 for (i
= 0; i
< 32; ++i
)
535 unsigned long int x
= 1 << i
;
536 int x0
= (lose0
& x
) != 0;
537 int x1
= (lose1
& x
) != 0;
543 /* They are functionally equal. So as long as the opcode table is
544 valid, we can put whichever one first we want, on aesthetic grounds. */
546 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
547 if (length_diff
!= 0)
548 /* Put the one with fewer arguments first. */
552 /* Put 1+i before i+1. */
554 char *p0
= (char *) index(op0
->args
, '+');
555 char *p1
= (char *) index(op1
->args
, '+');
559 /* There is a plus in both operands. Note that a plus
560 sign cannot be the first character in args,
561 so the following [-1]'s are valid. */
562 if (p0
[-1] == 'i' && p1
[1] == 'i')
563 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
565 if (p0
[1] == 'i' && p1
[-1] == 'i')
566 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
571 /* They are, as far as we can tell, identical.
572 Since qsort may have rearranged the table partially, there is
573 no way to tell which one was first in the opcode table as
574 written, so just say there are equal. */