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. */
24 #include "opcode/sparc.h"
26 extern int print_address();
28 static char *reg_names
[] =
29 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
30 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
31 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
32 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
33 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
34 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
35 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
36 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
37 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
39 #define freg_names (®_names[4 * 8])
43 unsigned long int code
;
62 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5, i
:1;
63 unsigned int IMM13
:13;
64 #define imm13 IMM13.IMM13
72 unsigned int DISP22
:22;
73 #define disp22 branch.DISP22
78 unsigned int _OP
:2, _RD
:5, op3
:6, _RS1
:5;
79 unsigned int DISP14
:14;
80 #define disp14 DISP14.DISP14
89 unsigned int DISP21
:21;
90 #define disp21 branch2.DISP21
98 unsigned int _DISP30
:30;
99 #define disp30 call._DISP30
103 /* Nonzero if INSN is the opcode for a delayed branch. */
105 is_delayed_branch (insn
)
106 union sparc_insn insn
;
110 for (i
= 0; i
< NUMOPCODES
; ++i
)
112 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
113 if ((opcode
->match
& insn
.code
) == opcode
->match
114 && (opcode
->lose
& insn
.code
) == 0
115 && (opcode
->flags
&F_DELAYED
))
121 static int opcodes_sorted
= 0;
123 /* Print one instruction from MEMADDR on STREAM. */
125 print_insn_sparc (memaddr
, buffer
, stream
)
131 union sparc_insn insn
;
133 register unsigned int i
;
137 static int compare_opcodes ();
138 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
139 sizeof (sparc_opcodes
[0]), compare_opcodes
);
143 memcpy(&insn
,buffer
, sizeof (insn
));
145 for (i
= 0; i
< NUMOPCODES
; ++i
)
147 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
148 if ((opcode
->match
& insn
.code
) == opcode
->match
149 && (opcode
->lose
& insn
.code
) == 0)
151 /* Nonzero means that we have found an instruction which has
152 the effect of adding or or'ing the imm13 field to rs1. */
153 int imm_added_to_rs1
= 0;
155 /* Nonzero means that we have found a plus sign in the args
156 field of the opcode table. */
159 /* Do we have an 'or' instruction where rs1 is the same
160 as rsd, and which has the i bit set? */
161 if (opcode
->match
== 0x80102000
162 && insn
.rs1
== insn
.rd
)
163 imm_added_to_rs1
= 1;
165 if (strchr (opcode
->args
, 'S') != 0)
166 /* Reject the special case for `set'.
167 The real `sethi' will match. */
169 if (insn
.rs1
!= insn
.rd
170 && strchr (opcode
->args
, 'r') != 0)
171 /* Can't do simple format if source and dest are different. */
174 fputs (opcode
->name
, stream
);
177 register const char *s
;
179 if (opcode
->args
[0] != ',')
181 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
207 } /* switch on arg */
208 } /* while there are comma started args */
217 /* note fall-through */
219 fprintf (stream
, "%c", *s
);
226 #define reg(n) fprintf (stream, "%%%s", reg_names[n])
241 #define freg(n) fprintf (stream, "%%%s", freg_names[n])
243 case 'v': /* double/even */
244 case 'V': /* quad/multiple of 4 */
249 case 'B': /* double/even */
250 case 'R': /* quad/multiple of 4 */
255 case 'H': /* double/even */
256 case 'J': /* quad/multiple of 4 */
261 #define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
276 fprintf (stream
, "%%hi(%#x)",
277 (unsigned int) insn
.imm22
<< 10);
282 /* We cannot trust the compiler to sign-extend
283 when extracting the bitfield, hence the shifts. */
284 int imm
= ((int) insn
.imm13
<< 19) >> 19;
286 /* Check to see whether we have a 1+i, and take
289 Note: because of the way we sort the table,
290 we will be matching 1+i rather than i+1,
291 so it is OK to assume that i is after +,
294 imm_added_to_rs1
= 1;
297 fprintf (stream
, "%d", imm
);
299 fprintf (stream
, "%#x", (unsigned) imm
);
304 case 'I': /* 11 bit immediate. */
305 case 'j': /* 10 bit immediate. */
307 /* We cannot trust the compiler to sign-extend
308 when extracting the bitfield, hence the shifts. */
312 imm
= ((int) insn
.imm13
<< 21) >> 21;
314 imm
= ((int) insn
.imm13
<< 22) >> 22;
316 /* Check to see whether we have a 1+i, and take
319 Note: because of the way we sort the table,
320 we will be matching 1+i rather than i+1,
321 so it is OK to assume that i is after +,
324 imm_added_to_rs1
= 1;
327 fprintf (stream
, "%d", imm
);
329 fprintf (stream
, "%#x", (unsigned) imm
);
337 print_address ((bfd_vma
)
339 + (((int) insn
.disp14
<< 18) >> 18) * 4),
344 print_address ((bfd_vma
)
346 /* We use only 19 of the 21 bits. */
347 + (((int) insn
.disp21
<< 13) >> 13) * 4),
355 fprintf (stream
, "fcc%c", *s
- '6' + '0');
359 fputs ("icc", stream
);
363 fputs ("xcc", stream
);
367 fputs ("%ccr", stream
);
371 fputs ("%fprs", stream
);
376 fprintf(stream
, "%%asr%d", insn
.rs1
);
380 fprintf(stream
, "%%asr%d", insn
.rd
);
384 print_address ((bfd_vma
) memaddr
+ insn
.disp30
* 4,
389 if ((insn
.code
>> 22) == 0)
390 /* Special case for `unimp'. Don't try to turn
391 it's operand into a function offset. */
392 fprintf (stream
, "%#x",
393 (unsigned) (((int) insn
.disp22
<< 10) >> 10));
395 /* We cannot trust the compiler to sign-extend
396 when extracting the bitfield, hence the shifts. */
397 print_address ((bfd_vma
)
399 + (((int) insn
.disp22
<< 10) >> 10) * 4),
404 fprintf (stream
, "(%d)", (int) insn
.asi
);
408 fputs ("%csr", stream
);
412 fputs ("%fsr", stream
);
416 fputs ("%psr", stream
);
420 fputs ("%fq", stream
);
424 fputs ("%cq", stream
);
428 fputs ("%tbr", stream
);
432 fputs ("%wim", stream
);
436 fputs ("%y", stream
);
442 /* If we are adding or or'ing something to rs1, then
443 check to see whether the previous instruction was
444 a sethi to the same register as in the sethi.
445 If so, attempt to print the result of the add or
446 or (in this context add and or do the same thing)
447 and its symbolic value. */
448 if (imm_added_to_rs1
)
450 union sparc_insn prev_insn
;
453 memcpy(&prev_insn
, buffer
-4, sizeof (prev_insn
));
457 /* If it is a delayed branch, we need to look at the
458 instruction before the delayed branch. This handles
461 sethi %o1, %hi(_foo), %o1
463 or %o1, %lo(_foo), %o1
466 if (is_delayed_branch (prev_insn
))
467 memcpy(&prev_insn
, buffer
- 8, sizeof(prev_insn
));
471 /* If there was a problem reading memory, then assume
472 the previous instruction was not sethi. */
475 /* Is it sethi to the same register? */
476 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
477 && prev_insn
.rd
== insn
.rs1
)
479 fprintf (stream
, "\t! ");
480 /* We cannot trust the compiler to sign-extend
481 when extracting the bitfield, hence the shifts. */
482 print_address (((int) prev_insn
.imm22
<< 10)
483 | (insn
.imm13
<< 19) >> 19, stream
);
488 return sizeof (insn
);
492 fprintf (stream
, "%#8x", insn
.code
);
493 return sizeof (insn
);
497 /* Compare opcodes A and B. */
500 compare_opcodes (a
, b
)
503 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
504 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
505 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
506 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
507 register unsigned int i
;
509 /* If a bit is set in both match and lose, there is something
510 wrong with the opcode table. */
513 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
514 op0
->name
, match0
, lose0
);
515 op0
->lose
&= ~op0
->match
;
521 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
522 op1
->name
, match1
, lose1
);
523 op1
->lose
&= ~op1
->match
;
527 /* Because the bits that are variable in one opcode are constant in
528 another, it is important to order the opcodes in the right order. */
529 for (i
= 0; i
< 32; ++i
)
531 unsigned long int x
= 1 << i
;
532 int x0
= (match0
& x
) != 0;
533 int x1
= (match1
& x
) != 0;
539 for (i
= 0; i
< 32; ++i
)
541 unsigned long int x
= 1 << i
;
542 int x0
= (lose0
& x
) != 0;
543 int x1
= (lose1
& x
) != 0;
549 /* They are functionally equal. So as long as the opcode table is
550 valid, we can put whichever one first we want, on aesthetic grounds. */
552 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
553 if (length_diff
!= 0)
554 /* Put the one with fewer arguments first. */
558 /* Put 1+i before i+1. */
560 char *p0
= (char *) strchr(op0
->args
, '+');
561 char *p1
= (char *) strchr(op1
->args
, '+');
565 /* There is a plus in both operands. Note that a plus
566 sign cannot be the first character in args,
567 so the following [-1]'s are valid. */
568 if (p0
[-1] == 'i' && p1
[1] == 'i')
569 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
571 if (p0
[1] == 'i' && p1
[-1] == 'i')
572 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
577 /* They are, as far as we can tell, identical.
578 Since qsort may have rearranged the table partially, there is
579 no way to tell which one was first in the opcode table as
580 written, so just say there are equal. */
This page took 0.04116 seconds and 4 git commands to generate.