1 /* Print SPARC instructions for GDB, the GNU Debugger.
2 Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GDB, the GNU debugger.
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 #define freg_names (®_names[4 * 8])
31 unsigned long int code
;
40 #define rs1 ldst.anrs1
43 #define asi ldst.anasi
45 #define rs2 ldst.anrs2
50 unsigned int anop
:2, anrd
:5, op3
:6, anrs1
:5, i
:1;
51 unsigned int IMM13
:13;
52 #define imm13 IMM13.IMM13
60 unsigned int DISP22
:22;
61 #define disp22 branch.DISP22
67 unsigned int adisp30
:30;
68 #define disp30 call.adisp30
72 /* Nonzero if INSN is the opcode for a delayed branch. */
74 is_delayed_branch (insn
)
75 union sparc_insn insn
;
79 for (i
= 0; i
< NUMOPCODES
; ++i
)
81 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
82 if ((opcode
->match
& insn
.code
) == opcode
->match
83 && (opcode
->lose
& insn
.code
) == 0)
84 return (opcode
->flags
& F_DELAYED
);
89 static int opcodes_sorted
= 0;
92 /* Print one instruction from MEMADDR on STREAM.
94 We suffix the instruction with a comment that gives the absolute
95 address involved, as well as its symbolic form, if the instruction
96 is preceded by a findable `sethi' and it either adds an immediate
97 displacement to that register, or it is an `add' or `or' instruction
100 print_insn (memaddr
, stream
)
104 union sparc_insn insn
;
106 register unsigned int i
;
110 static int compare_opcodes ();
111 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
112 sizeof (sparc_opcodes
[0]), compare_opcodes
);
116 read_memory (memaddr
, (char *) &insn
, sizeof (insn
));
118 for (i
= 0; i
< NUMOPCODES
; ++i
)
120 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
121 if ((opcode
->match
& insn
.code
) == opcode
->match
122 && (opcode
->lose
& insn
.code
) == 0)
124 /* Nonzero means that we have found an instruction which has
125 the effect of adding or or'ing the imm13 field to rs1. */
126 int imm_added_to_rs1
= 0;
128 /* Nonzero means that we have found a plus sign in the args
129 field of the opcode table. */
132 /* Do we have an `add' or `or' instruction where rs1 is the same
133 as rsd, and which has the i bit set? */
134 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
136 && insn
.rs1
== insn
.rd
)
137 imm_added_to_rs1
= 1;
139 if (insn
.rs1
!= insn
.rd
140 && strchr (opcode
->args
, 'r') != 0)
141 /* Can't do simple format if source and dest are different. */
144 fputs_filtered (opcode
->name
, stream
);
147 register const char *s
;
149 if (opcode
->args
[0] != ',')
150 fputs_filtered (" ", stream
);
151 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
155 fputs_filtered (",", stream
);
159 fputs_filtered ("a", stream
);
162 fputs_filtered (" ", stream
);
170 /* note fall-through */
172 fprintf_filtered (stream
, "%c", *s
);
176 fputs_filtered ("0", stream
);
179 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
194 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
196 case 'v': /* double/even */
197 case 'V': /* quad/multiple of 4 */
202 case 'B': /* double/even */
203 case 'R': /* quad/multiple of 4 */
208 case 'H': /* double/even */
209 case 'J': /* quad/multiple of 4 */
214 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
229 fprintf_filtered (stream
, "%%hi(%#x)",
230 (int) insn
.imm22
<< 10);
235 /* We cannot trust the compiler to sign-extend
236 when extracting the bitfield, hence the shifts. */
237 int imm
= ((int) insn
.imm13
<< 19) >> 19;
239 /* Check to see whether we have a 1+i, and take
242 FIXME: No longer true/relavant ???
243 Note: because of the way we sort the table,
244 we will be matching 1+i rather than i+1,
245 so it is OK to assume that i is after +,
248 imm_added_to_rs1
= 1;
251 fprintf_filtered (stream
, "%d", imm
);
253 fprintf_filtered (stream
, "%#x", imm
);
258 print_address ((CORE_ADDR
) memaddr
+ insn
.disp30
* 4,
263 if ((insn
.code
>> 22) == 0)
264 /* Special case for `unimp'. Don't try to turn
265 it's operand into a function offset. */
266 fprintf_filtered (stream
, "%#x",
267 (int) (((int) insn
.disp22
<< 10) >> 10));
269 /* We cannot trust the compiler to sign-extend
270 when extracting the bitfield, hence the shifts. */
271 print_address ((CORE_ADDR
)
273 + (((int) insn
.disp22
<< 10) >> 10) * 4),
278 fprintf_filtered (stream
, "(%d)", (int) insn
.asi
);
282 fputs_filtered ("%csr", stream
);
286 fputs_filtered ("%fsr", stream
);
290 fputs_filtered ("%psr", stream
);
294 fputs_filtered ("%fq", stream
);
298 fputs_filtered ("%cq", stream
);
302 fputs_filtered ("%tbr", stream
);
306 fputs_filtered ("%wim", stream
);
310 fputs_filtered ("%y", stream
);
316 /* If we are adding or or'ing something to rs1, then
317 check to see whether the previous instruction was
318 a sethi to the same register as in the sethi.
319 If so, attempt to print the result of the add or
320 or (in this context add and or do the same thing)
321 and its symbolic value. */
322 if (imm_added_to_rs1
)
324 union sparc_insn prev_insn
;
327 errcode
= target_read_memory (memaddr
- 4,
328 (char *)&prev_insn
, sizeof (prev_insn
));
332 /* If it is a delayed branch, we need to look at the
333 instruction before the delayed branch. This handles
336 sethi %o1, %hi(_foo), %o1
338 or %o1, %lo(_foo), %o1
341 if (is_delayed_branch (prev_insn
))
342 errcode
= target_read_memory
343 (memaddr
- 8, (char *)&prev_insn
, sizeof (prev_insn
));
346 /* If there was a problem reading memory, then assume
347 the previous instruction was not sethi. */
350 /* Is it sethi to the same register? */
351 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
352 && prev_insn
.rd
== insn
.rs1
)
354 fprintf_filtered (stream
, "\t! ");
355 /* We cannot trust the compiler to sign-extend
356 when extracting the bitfield, hence the shifts. */
357 print_address (((int) prev_insn
.imm22
<< 10)
358 | (insn
.imm13
<< 19) >> 19, stream
);
363 return sizeof (insn
);
367 printf_filtered ("%#8x", insn
.code
);
368 return sizeof (insn
);
371 /* Compare opcodes A and B. */
374 compare_opcodes (a
, b
)
377 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
378 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
379 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
380 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
381 register unsigned int i
;
383 /* If a bit is set in both match and lose, there is something
384 wrong with the opcode table. */
387 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
388 op0
->name
, match0
, lose0
);
389 op0
->lose
&= ~op0
->match
;
395 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
396 op1
->name
, match1
, lose1
);
397 op1
->lose
&= ~op1
->match
;
401 /* Because the bits that are variable in one opcode are constant in
402 another, it is important to order the opcodes in the right order. */
403 for (i
= 0; i
< 32; ++i
)
405 unsigned long int x
= 1 << i
;
406 int x0
= (match0
& x
) != 0;
407 int x1
= (match1
& x
) != 0;
413 for (i
= 0; i
< 32; ++i
)
415 unsigned long int x
= 1 << i
;
416 int x0
= (lose0
& x
) != 0;
417 int x1
= (lose1
& x
) != 0;
423 /* They are functionally equal. So as long as the opcode table is
424 valid, we can put whichever one first we want, on aesthetic grounds. */
426 /* Our first aesthetic ground is that aliases defer to real insns. */
428 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
430 /* Put the one that isn't an alias first. */
434 /* Except for aliases, two "identical" instructions had
435 better have the same opcode. This is a sanity check on the table. */
436 i
= STRCMP (op0
->name
, op1
->name
);
438 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
442 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
443 op0
->name
, op1
->name
);
445 /* Fewer arguments are preferred. */
447 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
448 if (length_diff
!= 0)
449 /* Put the one with fewer arguments first. */
453 /* Put 1+i before i+1. */
455 char *p0
= (char *) strchr(op0
->args
, '+');
456 char *p1
= (char *) strchr(op1
->args
, '+');
460 /* There is a plus in both operands. Note that a plus
461 sign cannot be the first character in args,
462 so the following [-1]'s are valid. */
463 if (p0
[-1] == 'i' && p1
[1] == 'i')
464 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
466 if (p0
[1] == 'i' && p1
[-1] == 'i')
467 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
472 /* They are, as far as we can tell, identical.
473 Since qsort may have rearranged the table partially, there is
474 no way to tell which one was first in the opcode table as
475 written, so just say there are equal. */
This page took 0.039604 seconds and 5 git commands to generate.