1 /* disassemble sparc instructions for objdump
2 Copyright (C) 1986, 1987, 1989, 1991 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 2, 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. */
26 #include "opcode/sparc.h"
28 extern int print_address();
30 static char *reg_names
[] =
31 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
32 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
33 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
34 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
35 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
36 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
37 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
38 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
39 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
41 #define freg_names (®_names[4 * 8])
45 unsigned long int code
;
64 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
65 unsigned int IMM13
:13;
66 #define imm13 IMM13.IMM13
74 unsigned int DISP22
:22;
75 #define disp22 branch.DISP22
80 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
81 unsigned int DISP14
:14;
82 #define disp14 DISP14.DISP14
91 unsigned int DISP21
:21;
92 #define disp21 branch2.DISP21
100 unsigned int _DISP30
:30;
101 #define disp30 call._DISP30
105 /* Nonzero if INSN is the opcode for a delayed branch. */
107 is_delayed_branch (insn
)
108 union sparc_insn insn
;
112 for (i
= 0; i
< NUMOPCODES
; ++i
)
114 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
115 if ((opcode
->match
& insn
.code
) == opcode
->match
116 && (opcode
->lose
& insn
.code
) == 0
117 && (opcode
->flags
&F_DELAYED
))
123 static int opcodes_sorted
= 0;
125 /* Print one instruction from MEMADDR on STREAM. */
127 print_insn_sparc (memaddr
, buffer
, stream
)
133 union sparc_insn insn
;
135 register unsigned int i
;
139 static int compare_opcodes ();
140 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
141 sizeof (sparc_opcodes
[0]), compare_opcodes
);
145 memcpy(&insn
,buffer
, sizeof (insn
));
147 for (i
= 0; i
< NUMOPCODES
; ++i
)
149 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
150 if ((opcode
->match
& insn
.code
) == opcode
->match
151 && (opcode
->lose
& insn
.code
) == 0)
153 /* Nonzero means that we have found an instruction which has
154 the effect of adding or or'ing the imm13 field to rs1. */
155 int imm_added_to_rs1
= 0;
157 /* Nonzero means that we have found a plus sign in the args
158 field of the opcode table. */
161 /* Do we have an 'or' instruction where rs1 is the same
162 as rsd, and which has the i bit set? */
163 if (opcode
->match
== 0x80102000
164 && insn
.rs1
== insn
.rd
)
165 imm_added_to_rs1
= 1;
167 if (index (opcode
->args
, 'S') != 0)
168 /* Reject the special case for `set'.
169 The real `sethi' will match. */
171 if (insn
.rs1
!= insn
.rd
172 && index (opcode
->args
, 'r') != 0)
173 /* Can't do simple format if source and dest are different. */
176 fputs (opcode
->name
, stream
);
179 register const char *s
;
181 if (opcode
->args
[0] != ',')
183 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
209 } /* switch on arg */
210 } /* while there are comma started args */
219 /* note fall-through */
221 fprintf (stream
, "%c", *s
);
228 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
243 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
245 case 'v': /* double/even */
246 case 'V': /* quad/multiple of 4 */
251 case 'B': /* double/even */
252 case 'R': /* quad/multiple of 4 */
257 /* Somebody who know needs to define rs3.
259 case 'u': * double/even *
260 case 'U': * quad/multiple of 4 *
267 case 'H': /* double/even */
268 case 'J': /* quad/multiple of 4 */
273 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
288 fprintf (stream
, "%%hi(%#x)",
289 (unsigned int) insn
.imm22
<< 10);
294 /* We cannot trust the compiler to sign-extend
295 when extracting the bitfield, hence the shifts. */
296 int imm
= ((int) insn
.imm13
<< 19) >> 19;
298 /* Check to see whether we have a 1+i, and take
301 Note: because of the way we sort the table,
302 we will be matching 1+i rather than i+1,
303 so it is OK to assume that i is after +,
306 imm_added_to_rs1
= 1;
309 fprintf (stream
, "%d", imm
);
311 fprintf (stream
, "%#x", (unsigned) imm
);
317 print_address ((bfd_vma
)
319 + (((int) insn
.disp14
<< 18) >> 18) * 4),
324 print_address ((bfd_vma
)
326 /* We use only 19 of the 21 bits. */
327 + (((int) insn
.disp21
<< 13) >> 13) * 4),
332 fputs ("%amr", stream
);
339 fprintf (stream
, "fcc%c", *s
- '6' + '0');
343 fputs ("icc", stream
);
347 fputs ("xcc", stream
);
352 fprintf(stream
, "%%asr%d", insn
.rs1
);
356 fprintf(stream
, "%%asr%d", insn
.rd
);
360 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
365 if ((insn
.code
>> 22) == 0)
366 /* Special case for `unimp'. Don't try to turn
367 it's operand into a function offset. */
368 fprintf (stream
, "%#x",
369 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
371 /* We cannot trust the compiler to sign-extend
372 when extracting the bitfield, hence the shifts. */
373 print_address ((bfd_vma
)
375 + (((int) insn
.disp22
<< 10) >> 10) * 4),
380 fprintf (stream
, "(%d)", (int) insn
.asi
);
384 fputs ("%csr", stream
);
388 fputs ("%fsr", stream
);
392 fputs ("%psr", stream
);
396 fputs ("%fq", stream
);
400 fputs ("%cq", stream
);
404 fputs ("%tbr", stream
);
408 fputs ("%wim", stream
);
412 fputs ("%y", stream
);
418 /* If we are adding or or'ing something to rs1, then
419 check to see whether the previous instruction was
420 a sethi to the same register as in the sethi.
421 If so, attempt to print the result of the add or
422 or (in this context add and or do the same thing)
423 and its symbolic value. */
424 if (imm_added_to_rs1
)
426 union sparc_insn prev_insn
;
429 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
433 /* If it is a delayed branch, we need to look at the
434 instruction before the delayed branch. This handles
437 sethi %o1, %hi(_foo), %o1
439 or %o1, %lo(_foo), %o1
442 if (is_delayed_branch (prev_insn
))
443 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
447 /* If there was a problem reading memory, then assume
448 the previous instruction was not sethi. */
451 /* Is it sethi to the same register? */
452 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
453 && prev_insn
.rd
== insn
.rs1
)
455 fprintf (stream
, "\t! ");
456 /* We cannot trust the compiler to sign-extend
457 when extracting the bitfield, hence the shifts. */
458 print_address (((int) prev_insn
.imm22
<< 10)
459 | (insn
.imm13
<< 19) >> 19, stream
);
464 return sizeof (insn
);
468 fprintf (stream
, "%#8x", insn
.code
);
469 return sizeof (insn
);
473 /* Compare opcodes A and B. */
476 compare_opcodes (a
, b
)
479 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
480 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
481 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
482 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
483 register unsigned int i
;
485 /* If a bit is set in both match and lose, there is something
486 wrong with the opcode table. */
489 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
490 op0
->name
, match0
, lose0
);
491 op0
->lose
&= ~op0
->match
;
497 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
498 op1
->name
, match1
, lose1
);
499 op1
->lose
&= ~op1
->match
;
503 /* Because the bits that are variable in one opcode are constant in
504 another, it is important to order the opcodes in the right order. */
505 for (i
= 0; i
< 32; ++i
)
507 unsigned long int x
= 1 << i
;
508 int x0
= (match0
& x
) != 0;
509 int x1
= (match1
& x
) != 0;
515 for (i
= 0; i
< 32; ++i
)
517 unsigned long int x
= 1 << i
;
518 int x0
= (lose0
& x
) != 0;
519 int x1
= (lose1
& x
) != 0;
525 /* They are functionally equal. So as long as the opcode table is
526 valid, we can put whichever one first we want, on aesthetic grounds. */
528 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
529 if (length_diff
!= 0)
530 /* Put the one with fewer arguments first. */
534 /* Put 1+i before i+1. */
536 char *p0
= (char *) index(op0
->args
, '+');
537 char *p1
= (char *) index(op1
->args
, '+');
541 /* There is a plus in both operands. Note that a plus
542 sign cannot be the first character in args,
543 so the following [-1]'s are valid. */
544 if (p0
[-1] == 'i' && p1
[1] == 'i')
545 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
547 if (p0
[1] == 'i' && p1
[-1] == 'i')
548 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
553 /* They are, as far as we can tell, identical.
554 Since qsort may have rearranged the table partially, there is
555 no way to tell which one was first in the opcode table as
556 written, so just say there are equal. */