1 /* Print SPARC instructions for GDB, the GNU Debugger.
2 Copyright 1989, 1991 Free Software Foundation, Inc.
4 This file is part of GDB, the GNU disassembler.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include "opcode/sparc.h"
29 extern char *reg_names
[];
30 #define freg_names (®_names[4 * 8])
34 unsigned long int code
;
43 #define rs1 ldst.anrs1
46 #define asi ldst.anasi
48 #define rs2 ldst.anrs2
53 unsigned int anop
:2, anrd
:5, op3
:6, anrs1
:5, i
:1;
54 unsigned int IMM13
:13;
55 #define imm13 IMM13.IMM13
63 unsigned int DISP22
:22;
64 #define disp22 branch.DISP22
70 unsigned int adisp30
:30;
71 #define disp30 call.adisp30
75 /* Nonzero if INSN is the opcode for a delayed branch. */
77 is_delayed_branch (insn
)
78 union sparc_insn insn
;
82 for (i
= 0; i
< NUMOPCODES
; ++i
)
84 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
85 if ((opcode
->match
& insn
.code
) == opcode
->match
86 && (opcode
->lose
& insn
.code
) == 0)
87 return (opcode
->flags
& F_DELAYED
);
92 static int opcodes_sorted
= 0;
95 /* Print one instruction from MEMADDR on STREAM.
97 We suffix the instruction with a comment that gives the absolute
98 address involved, as well as its symbolic form, if the instruction
99 is preceded by a findable `sethi' and it either adds an immediate
100 displacement to that register, or it is an `add' or `or' instruction
103 print_insn (memaddr
, stream
)
107 union sparc_insn insn
;
109 register unsigned int i
;
113 static int compare_opcodes ();
114 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
115 sizeof (sparc_opcodes
[0]), compare_opcodes
);
119 read_memory (memaddr
, (char *) &insn
, sizeof (insn
));
121 for (i
= 0; i
< NUMOPCODES
; ++i
)
123 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
124 if ((opcode
->match
& insn
.code
) == opcode
->match
125 && (opcode
->lose
& insn
.code
) == 0)
127 /* Nonzero means that we have found an instruction which has
128 the effect of adding or or'ing the imm13 field to rs1. */
129 int imm_added_to_rs1
= 0;
131 /* Nonzero means that we have found a plus sign in the args
132 field of the opcode table. */
135 /* Do we have an `add' or `or' instruction where rs1 is the same
136 as rsd, and which has the i bit set? */
137 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
139 && insn
.rs1
== insn
.rd
)
140 imm_added_to_rs1
= 1;
142 if (insn
.rs1
!= insn
.rd
143 && strchr (opcode
->args
, 'r') != 0)
144 /* Can't do simple format if source and dest are different. */
147 fputs_filtered (opcode
->name
, stream
);
150 register const char *s
;
152 if (opcode
->args
[0] != ',')
153 fputs_filtered (" ", stream
);
154 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
158 fputs_filtered (",", stream
);
162 fputs_filtered ("a", stream
);
165 fputs_filtered (" ", stream
);
173 /* note fall-through */
175 fprintf_filtered (stream
, "%c", *s
);
179 fputs_filtered ("0", stream
);
182 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
197 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
199 case 'v': /* double/even */
200 case 'V': /* quad/multiple of 4 */
205 case 'B': /* double/even */
206 case 'R': /* quad/multiple of 4 */
211 case 'H': /* double/even */
212 case 'J': /* quad/multiple of 4 */
217 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
232 fprintf_filtered (stream
, "%%hi(%#x)",
233 (int) insn
.imm22
<< 10);
238 /* We cannot trust the compiler to sign-extend
239 when extracting the bitfield, hence the shifts. */
240 int imm
= ((int) insn
.imm13
<< 19) >> 19;
242 /* Check to see whether we have a 1+i, and take
245 FIXME: No longer true/relavant ???
246 Note: because of the way we sort the table,
247 we will be matching 1+i rather than i+1,
248 so it is OK to assume that i is after +,
251 imm_added_to_rs1
= 1;
254 fprintf_filtered (stream
, "%d", imm
);
256 fprintf_filtered (stream
, "%#x", imm
);
261 print_address ((CORE_ADDR
) memaddr
+ insn
.disp30
* 4,
266 if ((insn
.code
>> 22) == 0)
267 /* Special case for `unimp'. Don't try to turn
268 it's operand into a function offset. */
269 fprintf_filtered (stream
, "%#x",
270 (int) (((int) insn
.disp22
<< 10) >> 10));
272 /* We cannot trust the compiler to sign-extend
273 when extracting the bitfield, hence the shifts. */
274 print_address ((CORE_ADDR
)
276 + (((int) insn
.disp22
<< 10) >> 10) * 4),
281 fprintf_filtered (stream
, "(%d)", (int) insn
.asi
);
285 fputs_filtered ("%csr", stream
);
289 fputs_filtered ("%fsr", stream
);
293 fputs_filtered ("%psr", stream
);
297 fputs_filtered ("%fq", stream
);
301 fputs_filtered ("%cq", stream
);
305 fputs_filtered ("%tbr", stream
);
309 fputs_filtered ("%wim", stream
);
313 fputs_filtered ("%y", stream
);
319 /* If we are adding or or'ing something to rs1, then
320 check to see whether the previous instruction was
321 a sethi to the same register as in the sethi.
322 If so, attempt to print the result of the add or
323 or (in this context add and or do the same thing)
324 and its symbolic value. */
325 if (imm_added_to_rs1
)
327 union sparc_insn prev_insn
;
330 errcode
= target_read_memory (memaddr
- 4,
331 (char *)&prev_insn
, sizeof (prev_insn
));
335 /* If it is a delayed branch, we need to look at the
336 instruction before the delayed branch. This handles
339 sethi %o1, %hi(_foo), %o1
341 or %o1, %lo(_foo), %o1
344 if (is_delayed_branch (prev_insn
))
345 errcode
= target_read_memory
346 (memaddr
- 8, (char *)&prev_insn
, sizeof (prev_insn
));
349 /* If there was a problem reading memory, then assume
350 the previous instruction was not sethi. */
353 /* Is it sethi to the same register? */
354 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
355 && prev_insn
.rd
== insn
.rs1
)
357 fprintf_filtered (stream
, "\t! ");
358 /* We cannot trust the compiler to sign-extend
359 when extracting the bitfield, hence the shifts. */
360 print_address (((int) prev_insn
.imm22
<< 10)
361 | (insn
.imm13
<< 19) >> 19, stream
);
366 return sizeof (insn
);
370 printf_filtered ("%#8x", insn
.code
);
371 return sizeof (insn
);
374 /* Compare opcodes A and B. */
377 compare_opcodes (a
, b
)
380 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
381 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
382 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
383 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
384 register unsigned int i
;
386 /* If a bit is set in both match and lose, there is something
387 wrong with the opcode table. */
390 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
391 op0
->name
, match0
, lose0
);
392 op0
->lose
&= ~op0
->match
;
398 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
399 op1
->name
, match1
, lose1
);
400 op1
->lose
&= ~op1
->match
;
404 /* Because the bits that are variable in one opcode are constant in
405 another, it is important to order the opcodes in the right order. */
406 for (i
= 0; i
< 32; ++i
)
408 unsigned long int x
= 1 << i
;
409 int x0
= (match0
& x
) != 0;
410 int x1
= (match1
& x
) != 0;
416 for (i
= 0; i
< 32; ++i
)
418 unsigned long int x
= 1 << i
;
419 int x0
= (lose0
& x
) != 0;
420 int x1
= (lose1
& x
) != 0;
426 /* They are functionally equal. So as long as the opcode table is
427 valid, we can put whichever one first we want, on aesthetic grounds. */
429 /* Our first aesthetic ground is that aliases defer to real insns. */
431 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
433 /* Put the one that isn't an alias first. */
437 /* Except for aliases, two "identical" instructions had
438 better have the same opcode. This is a sanity check on the table. */
439 i
= strcmp (op0
->name
, op1
->name
);
441 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
445 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
446 op0
->name
, op1
->name
);
448 /* Fewer arguments are preferred. */
450 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
451 if (length_diff
!= 0)
452 /* Put the one with fewer arguments first. */
456 /* Put 1+i before i+1. */
458 char *p0
= (char *) strchr(op0
->args
, '+');
459 char *p1
= (char *) strchr(op1
->args
, '+');
463 /* There is a plus in both operands. Note that a plus
464 sign cannot be the first character in args,
465 so the following [-1]'s are valid. */
466 if (p0
[-1] == 'i' && p1
[1] == 'i')
467 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
469 if (p0
[1] == 'i' && p1
[-1] == 'i')
470 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
475 /* They are, as far as we can tell, identical.
476 Since qsort may have rearranged the table partially, there is
477 no way to tell which one was first in the opcode table as
478 written, so just say there are equal. */
This page took 0.042128 seconds and 4 git commands to generate.