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. */
22 #include "opcode/sparc.h"
27 extern char *reg_names
[];
28 #define freg_names (®_names[4 * 8])
32 unsigned long int code
;
41 #define rs1 ldst.anrs1
44 #define asi ldst.anasi
46 #define rs2 ldst.anrs2
51 unsigned int anop
:2, anrd
:5, op3
:6, anrs1
:5, i
:1;
52 unsigned int IMM13
:13;
53 #define imm13 IMM13.IMM13
61 unsigned int DISP22
:22;
62 #define disp22 branch.DISP22
68 unsigned int adisp30
:30;
69 #define disp30 call.adisp30
73 /* Nonzero if INSN is the opcode for a delayed branch. */
75 is_delayed_branch (insn
)
76 union sparc_insn insn
;
80 for (i
= 0; i
< NUMOPCODES
; ++i
)
82 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
83 if ((opcode
->match
& insn
.code
) == opcode
->match
84 && (opcode
->lose
& insn
.code
) == 0)
85 return (opcode
->flags
& F_DELAYED
);
90 static int opcodes_sorted
= 0;
93 /* Print one instruction from MEMADDR on STREAM.
95 We suffix the instruction with a comment that gives the absolute
96 address involved, as well as its symbolic form, if the instruction
97 is preceded by a findable `sethi' and it either adds an immediate
98 displacement to that register, or it is an `add' or `or' instruction
101 print_insn (memaddr
, stream
)
105 union sparc_insn insn
;
107 register unsigned int i
;
111 static int compare_opcodes ();
112 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
113 sizeof (sparc_opcodes
[0]), compare_opcodes
);
117 read_memory (memaddr
, (char *) &insn
, sizeof (insn
));
119 for (i
= 0; i
< NUMOPCODES
; ++i
)
121 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
122 if ((opcode
->match
& insn
.code
) == opcode
->match
123 && (opcode
->lose
& insn
.code
) == 0)
125 /* Nonzero means that we have found an instruction which has
126 the effect of adding or or'ing the imm13 field to rs1. */
127 int imm_added_to_rs1
= 0;
129 /* Nonzero means that we have found a plus sign in the args
130 field of the opcode table. */
133 /* Do we have an `add' or `or' instruction where rs1 is the same
134 as rsd, and which has the i bit set? */
135 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
137 && insn
.rs1
== insn
.rd
)
138 imm_added_to_rs1
= 1;
140 if (insn
.rs1
!= insn
.rd
141 && strchr (opcode
->args
, 'r') != 0)
142 /* Can't do simple format if source and dest are different. */
145 fputs_filtered (opcode
->name
, stream
);
148 register const char *s
;
150 if (opcode
->args
[0] != ',')
151 fputs_filtered (" ", stream
);
152 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
156 fputs_filtered (",", stream
);
160 fputs_filtered ("a", stream
);
163 fputs_filtered (" ", stream
);
171 /* note fall-through */
173 fprintf_filtered (stream
, "%c", *s
);
177 fputs_filtered ("0", stream
);
180 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
195 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
197 case 'v': /* double/even */
198 case 'V': /* quad/multiple of 4 */
203 case 'B': /* double/even */
204 case 'R': /* quad/multiple of 4 */
209 case 'H': /* double/even */
210 case 'J': /* quad/multiple of 4 */
215 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
230 fprintf_filtered (stream
, "%%hi(%#x)",
231 (int) insn
.imm22
<< 10);
236 /* We cannot trust the compiler to sign-extend
237 when extracting the bitfield, hence the shifts. */
238 int imm
= ((int) insn
.imm13
<< 19) >> 19;
240 /* Check to see whether we have a 1+i, and take
243 FIXME: No longer true/relavant ???
244 Note: because of the way we sort the table,
245 we will be matching 1+i rather than i+1,
246 so it is OK to assume that i is after +,
249 imm_added_to_rs1
= 1;
252 fprintf_filtered (stream
, "%d", imm
);
254 fprintf_filtered (stream
, "%#x", imm
);
259 print_address ((CORE_ADDR
) memaddr
+ insn
.disp30
* 4,
264 if ((insn
.code
>> 22) == 0)
265 /* Special case for `unimp'. Don't try to turn
266 it's operand into a function offset. */
267 fprintf_filtered (stream
, "%#x",
268 (int) (((int) insn
.disp22
<< 10) >> 10));
270 /* We cannot trust the compiler to sign-extend
271 when extracting the bitfield, hence the shifts. */
272 print_address ((CORE_ADDR
)
274 + (((int) insn
.disp22
<< 10) >> 10) * 4),
279 fprintf_filtered (stream
, "(%d)", (int) insn
.asi
);
283 fputs_filtered ("%csr", stream
);
287 fputs_filtered ("%fsr", stream
);
291 fputs_filtered ("%psr", stream
);
295 fputs_filtered ("%fq", stream
);
299 fputs_filtered ("%cq", stream
);
303 fputs_filtered ("%tbr", stream
);
307 fputs_filtered ("%wim", stream
);
311 fputs_filtered ("%y", stream
);
317 /* If we are adding or or'ing something to rs1, then
318 check to see whether the previous instruction was
319 a sethi to the same register as in the sethi.
320 If so, attempt to print the result of the add or
321 or (in this context add and or do the same thing)
322 and its symbolic value. */
323 if (imm_added_to_rs1
)
325 union sparc_insn prev_insn
;
328 errcode
= target_read_memory (memaddr
- 4,
329 (char *)&prev_insn
, sizeof (prev_insn
));
333 /* If it is a delayed branch, we need to look at the
334 instruction before the delayed branch. This handles
337 sethi %o1, %hi(_foo), %o1
339 or %o1, %lo(_foo), %o1
342 if (is_delayed_branch (prev_insn
))
343 errcode
= target_read_memory
344 (memaddr
- 8, (char *)&prev_insn
, sizeof (prev_insn
));
347 /* If there was a problem reading memory, then assume
348 the previous instruction was not sethi. */
351 /* Is it sethi to the same register? */
352 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
353 && prev_insn
.rd
== insn
.rs1
)
355 fprintf_filtered (stream
, "\t! ");
356 /* We cannot trust the compiler to sign-extend
357 when extracting the bitfield, hence the shifts. */
358 print_address (((int) prev_insn
.imm22
<< 10)
359 | (insn
.imm13
<< 19) >> 19, stream
);
364 return sizeof (insn
);
368 printf_filtered ("%#8x", insn
.code
);
369 return sizeof (insn
);
372 /* Compare opcodes A and B. */
375 compare_opcodes (a
, b
)
378 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
379 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
380 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
381 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
382 register unsigned int i
;
384 /* If a bit is set in both match and lose, there is something
385 wrong with the opcode table. */
388 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
389 op0
->name
, match0
, lose0
);
390 op0
->lose
&= ~op0
->match
;
396 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
397 op1
->name
, match1
, lose1
);
398 op1
->lose
&= ~op1
->match
;
402 /* Because the bits that are variable in one opcode are constant in
403 another, it is important to order the opcodes in the right order. */
404 for (i
= 0; i
< 32; ++i
)
406 unsigned long int x
= 1 << i
;
407 int x0
= (match0
& x
) != 0;
408 int x1
= (match1
& x
) != 0;
414 for (i
= 0; i
< 32; ++i
)
416 unsigned long int x
= 1 << i
;
417 int x0
= (lose0
& x
) != 0;
418 int x1
= (lose1
& x
) != 0;
424 /* They are functionally equal. So as long as the opcode table is
425 valid, we can put whichever one first we want, on aesthetic grounds. */
427 /* Our first aesthetic ground is that aliases defer to real insns. */
429 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
431 /* Put the one that isn't an alias first. */
435 /* Except for aliases, two "identical" instructions had
436 better have the same opcode. This is a sanity check on the table. */
437 i
= strcmp (op0
->name
, op1
->name
);
439 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
443 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
444 op0
->name
, op1
->name
);
446 /* Fewer arguments are preferred. */
448 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
449 if (length_diff
!= 0)
450 /* Put the one with fewer arguments first. */
454 /* Put 1+i before i+1. */
456 char *p0
= (char *) strchr(op0
->args
, '+');
457 char *p1
= (char *) strchr(op1
->args
, '+');
461 /* There is a plus in both operands. Note that a plus
462 sign cannot be the first character in args,
463 so the following [-1]'s are valid. */
464 if (p0
[-1] == 'i' && p1
[1] == 'i')
465 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
467 if (p0
[1] == 'i' && p1
[-1] == 'i')
468 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
473 /* They are, as far as we can tell, identical.
474 Since qsort may have rearranged the table partially, there is
475 no way to tell which one was first in the opcode table as
476 written, so just say there are equal. */
This page took 0.03851 seconds and 4 git commands to generate.