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 "sparc-opcode.h"
29 extern int print_address();
31 static char *reg_names
[] =
32 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
33 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
34 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
35 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
36 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
37 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
38 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
39 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
40 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
42 #define freg_names (®_names[4 * 8])
46 unsigned long int code
;
65 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
66 unsigned int IMM13
:13;
67 #define imm13 IMM13.IMM13
75 unsigned int DISP22
:22;
76 #define disp22 branch.DISP22
81 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
82 unsigned int DISP14
:14;
83 #define disp14 DISP14.DISP14
92 unsigned int DISP21
:21;
93 #define disp21 branch2.DISP21
101 unsigned int _DISP30
:30;
102 #define disp30 call._DISP30
106 /* Nonzero if INSN is the opcode for a delayed branch. */
108 is_delayed_branch (insn
)
109 union sparc_insn insn
;
113 for (i
= 0; i
< NUMOPCODES
; ++i
)
115 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
116 if ((opcode
->match
& insn
.code
) == opcode
->match
117 && (opcode
->lose
& insn
.code
) == 0
118 && (opcode
->flags
&F_DELAYED
))
124 static int opcodes_sorted
= 0;
126 /* Print one instruction from MEMADDR on STREAM. */
128 print_insn_sparc (memaddr
, buffer
, stream
)
134 union sparc_insn insn
;
136 register unsigned int i
;
140 static int compare_opcodes ();
141 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
142 sizeof (sparc_opcodes
[0]), compare_opcodes
);
146 memcpy(&insn
,buffer
, sizeof (insn
));
148 for (i
= 0; i
< NUMOPCODES
; ++i
)
150 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
151 if ((opcode
->match
& insn
.code
) == opcode
->match
152 && (opcode
->lose
& insn
.code
) == 0)
154 /* Nonzero means that we have found an instruction which has
155 the effect of adding or or'ing the imm13 field to rs1. */
156 int imm_added_to_rs1
= 0;
158 /* Nonzero means that we have found a plus sign in the args
159 field of the opcode table. */
162 /* Do we have an 'or' instruction where rs1 is the same
163 as rsd, and which has the i bit set? */
164 if (opcode
->match
== 0x80102000
165 && insn
.rs1
== insn
.rd
)
166 imm_added_to_rs1
= 1;
168 if (index (opcode
->args
, 'S') != 0)
169 /* Reject the special case for `set'.
170 The real `sethi' will match. */
172 if (insn
.rs1
!= insn
.rd
173 && index (opcode
->args
, 'r') != 0)
174 /* Can't do simple format if source and dest are different. */
177 fputs (opcode
->name
, stream
);
180 register const char *s
;
182 if (opcode
->args
[0] != ',')
184 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
208 } /* switch on arg */
209 } /* while there are comma started args */
218 /* note fall-through */
220 fprintf (stream
, "%c", *s
);
227 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
242 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
256 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
271 fprintf (stream
, "%%hi(%#x)",
272 (unsigned int) insn
.imm22
<< 10);
277 /* We cannot trust the compiler to sign-extend
278 when extracting the bitfield, hence the shifts. */
279 int imm
= ((int) insn
.imm13
<< 19) >> 19;
281 /* Check to see whether we have a 1+i, and take
284 Note: because of the way we sort the table,
285 we will be matching 1+i rather than i+1,
286 so it is OK to assume that i is after +,
289 imm_added_to_rs1
= 1;
292 fprintf (stream
, "%d", imm
);
294 fprintf (stream
, "%#x", (unsigned) imm
);
300 print_address ((bfd_vma
)
302 + (((int) insn
.disp14
<< 18) >> 18) * 4),
307 print_address ((bfd_vma
)
309 + (((int) insn
.disp21
<< 11) >> 11) * 4),
314 fputs ("%amr", stream
);
320 fprintf(stream
, "%%asr%d", insn
.rs1
);
324 fprintf(stream
, "%%asr%d", insn
.rd
);
328 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
333 if ((insn
.code
>> 22) == 0)
334 /* Special case for `unimp'. Don't try to turn
335 it's operand into a function offset. */
336 fprintf (stream
, "%#x",
337 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
339 /* We cannot trust the compiler to sign-extend
340 when extracting the bitfield, hence the shifts. */
341 print_address ((bfd_vma
)
343 + (((int) insn
.disp22
<< 10) >> 10) * 4),
348 fprintf (stream
, "(%d)", (int) insn
.asi
);
352 fputs ("%csr", stream
);
356 fputs ("%fsr", stream
);
360 fputs ("%psr", stream
);
364 fputs ("%fq", stream
);
368 fputs ("%cq", stream
);
372 fputs ("%tbr", stream
);
376 fputs ("%wim", stream
);
380 fputs ("%y", stream
);
386 /* If we are adding or or'ing something to rs1, then
387 check to see whether the previous instruction was
388 a sethi to the same register as in the sethi.
389 If so, attempt to print the result of the add or
390 or (in this context add and or do the same thing)
391 and its symbolic value. */
392 if (imm_added_to_rs1
)
394 union sparc_insn prev_insn
;
397 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
401 /* If it is a delayed branch, we need to look at the
402 instruction before the delayed branch. This handles
405 sethi %o1, %hi(_foo), %o1
407 or %o1, %lo(_foo), %o1
410 if (is_delayed_branch (prev_insn
))
411 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
415 /* If there was a problem reading memory, then assume
416 the previous instruction was not sethi. */
419 /* Is it sethi to the same register? */
420 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
421 && prev_insn
.rd
== insn
.rs1
)
423 fprintf (stream
, "\t! ");
424 /* We cannot trust the compiler to sign-extend
425 when extracting the bitfield, hence the shifts. */
426 print_address (((int) prev_insn
.imm22
<< 10)
427 | (insn
.imm13
<< 19) >> 19, stream
);
432 return sizeof (insn
);
436 fprintf (stream
, "%#8x", insn
.code
);
437 return sizeof (insn
);
441 /* Compare opcodes A and B. */
444 compare_opcodes (a
, b
)
447 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
448 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
449 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
450 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
451 register unsigned int i
;
453 /* If a bit is set in both match and lose, there is something
454 wrong with the opcode table. */
457 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
458 op0
->name
, match0
, lose0
);
459 op0
->lose
&= ~op0
->match
;
465 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
466 op1
->name
, match1
, lose1
);
467 op1
->lose
&= ~op1
->match
;
471 /* Because the bits that are variable in one opcode are constant in
472 another, it is important to order the opcodes in the right order. */
473 for (i
= 0; i
< 32; ++i
)
475 unsigned long int x
= 1 << i
;
476 int x0
= (match0
& x
) != 0;
477 int x1
= (match1
& x
) != 0;
483 for (i
= 0; i
< 32; ++i
)
485 unsigned long int x
= 1 << i
;
486 int x0
= (lose0
& x
) != 0;
487 int x1
= (lose1
& x
) != 0;
493 /* They are functionally equal. So as long as the opcode table is
494 valid, we can put whichever one first we want, on aesthetic grounds. */
496 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
497 if (length_diff
!= 0)
498 /* Put the one with fewer arguments first. */
502 /* Put 1+i before i+1. */
504 char *p0
= (char *) index(op0
->args
, '+');
505 char *p1
= (char *) index(op1
->args
, '+');
509 /* There is a plus in both operands. Note that a plus
510 sign cannot be the first character in args,
511 so the following [-1]'s are valid. */
512 if (p0
[-1] == 'i' && p1
[1] == 'i')
513 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
515 if (p0
[1] == 'i' && p1
[-1] == 'i')
516 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
521 /* They are, as far as we can tell, identical.
522 Since qsort may have rearranged the table partially, there is
523 no way to tell which one was first in the opcode table as
524 written, so just say there are equal. */
This page took 0.081136 seconds and 4 git commands to generate.