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 "sparc-opcode.h"
32 extern char *reg_names
[];
33 #define freg_names (®_names[4 * 8])
37 unsigned long int code
;
56 unsigned int OP
:2, RD
:5, op3
:6, RS1
:5, i
:1;
57 unsigned int IMM13
:13;
58 #define imm13 IMM13.IMM13
66 unsigned int DISP22
:22;
67 #define disp22 branch.DISP22
73 unsigned int DISP30
:30;
74 #define disp30 call.DISP30
78 /* Nonzero if INSN is the opcode for a delayed branch. */
80 is_delayed_branch (insn
)
81 union sparc_insn insn
;
85 for (i
= 0; i
< NUMOPCODES
; ++i
)
87 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
88 if ((opcode
->match
& insn
.code
) == opcode
->match
89 && (opcode
->lose
& insn
.code
) == 0)
90 return (opcode
->flags
& F_DELAYED
);
95 static int opcodes_sorted
= 0;
97 /* Print one instruction from MEMADDR on STREAM. */
99 print_insn (memaddr
, stream
)
103 union sparc_insn insn
;
105 register unsigned int i
;
109 static int compare_opcodes ();
110 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
111 sizeof (sparc_opcodes
[0]), compare_opcodes
);
115 read_memory (memaddr
, &insn
, sizeof (insn
));
117 for (i
= 0; i
< NUMOPCODES
; ++i
)
119 const struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
120 if ((opcode
->match
& insn
.code
) == opcode
->match
121 && (opcode
->lose
& insn
.code
) == 0)
123 /* Nonzero means that we have found an instruction which has
124 the effect of adding or or'ing the imm13 field to rs1. */
125 int imm_added_to_rs1
= 0;
127 /* Nonzero means that we have found a plus sign in the args
128 field of the opcode table. */
131 /* Do we have an 'or' instruction where rs1 is the same
132 as rsd, and which has the i bit set? */
133 if (opcode
->match
== 0x80102000
134 && insn
.rs1
== insn
.rd
)
135 imm_added_to_rs1
= 1;
137 if (insn
.rs1
!= insn
.rd
138 && strchr (opcode
->args
, 'r') != 0)
139 /* Can't do simple format if source and dest are different. */
142 fputs_filtered (opcode
->name
, stream
);
145 register const char *s
;
147 if (opcode
->args
[0] != ',')
148 fputs_filtered (" ", stream
);
149 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
153 fputs_filtered (",", stream
);
157 fputs_filtered ("a", stream
);
160 fputs_filtered (" ", stream
);
168 /* note fall-through */
170 fprintf_filtered (stream
, "%c", *s
);
174 fputs_filtered ("0", stream
);
177 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
192 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
206 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
221 fprintf_filtered (stream
, "%%hi(%#x)",
222 (int) insn
.imm22
<< 10);
227 /* We cannot trust the compiler to sign-extend
228 when extracting the bitfield, hence the shifts. */
229 int imm
= ((int) insn
.imm13
<< 19) >> 19;
231 /* Check to see whether we have a 1+i, and take
234 Note: because of the way we sort the table,
235 we will be matching 1+i rather than i+1,
236 so it is OK to assume that i is after +,
239 imm_added_to_rs1
= 1;
242 fprintf_filtered (stream
, "%d", imm
);
244 fprintf_filtered (stream
, "%#x", imm
);
249 print_address ((CORE_ADDR
) memaddr
+ insn
.disp30
* 4,
254 if ((insn
.code
>> 22) == 0)
255 /* Special case for `unimp'. Don't try to turn
256 it's operand into a function offset. */
257 fprintf_filtered (stream
, "%#x",
258 (int) (((int) insn
.disp22
<< 10) >> 10));
260 /* We cannot trust the compiler to sign-extend
261 when extracting the bitfield, hence the shifts. */
262 print_address ((CORE_ADDR
)
264 + (((int) insn
.disp22
<< 10) >> 10) * 4),
269 fprintf_filtered (stream
, "(%d)", (int) insn
.asi
);
273 fputs_filtered ("%csr", stream
);
277 fputs_filtered ("%fsr", stream
);
281 fputs_filtered ("%psr", stream
);
285 fputs_filtered ("%fq", stream
);
289 fputs_filtered ("%cq", stream
);
293 fputs_filtered ("%tbr", stream
);
297 fputs_filtered ("%wim", stream
);
301 fputs_filtered ("%y", stream
);
307 /* If we are adding or or'ing something to rs1, then
308 check to see whether the previous instruction was
309 a sethi to the same register as in the sethi.
310 If so, attempt to print the result of the add or
311 or (in this context add and or do the same thing)
312 and its symbolic value. */
313 if (imm_added_to_rs1
)
315 union sparc_insn prev_insn
;
318 errcode
= target_read_memory (memaddr
- 4,
319 (char *)&prev_insn
, sizeof (prev_insn
));
323 /* If it is a delayed branch, we need to look at the
324 instruction before the delayed branch. This handles
327 sethi %o1, %hi(_foo), %o1
329 or %o1, %lo(_foo), %o1
332 if (is_delayed_branch (prev_insn
))
333 errcode
= target_read_memory
334 (memaddr
- 8, (char *)&prev_insn
, sizeof (prev_insn
));
337 /* If there was a problem reading memory, then assume
338 the previous instruction was not sethi. */
341 /* Is it sethi to the same register? */
342 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
343 && prev_insn
.rd
== insn
.rs1
)
345 fprintf_filtered (stream
, "\t! ");
346 /* We cannot trust the compiler to sign-extend
347 when extracting the bitfield, hence the shifts. */
348 print_address (((int) prev_insn
.imm22
<< 10)
349 | (insn
.imm13
<< 19) >> 19, stream
);
354 return sizeof (insn
);
358 printf_filtered ("%#8x", insn
.code
);
359 return sizeof (insn
);
363 /* Compare opcodes A and B. */
366 compare_opcodes (a
, b
)
369 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
370 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
371 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
372 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
373 register unsigned int i
;
375 /* If a bit is set in both match and lose, there is something
376 wrong with the opcode table. */
379 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
380 op0
->name
, match0
, lose0
);
381 op0
->lose
&= ~op0
->match
;
387 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
388 op1
->name
, match1
, lose1
);
389 op1
->lose
&= ~op1
->match
;
393 /* Because the bits that are variable in one opcode are constant in
394 another, it is important to order the opcodes in the right order. */
395 for (i
= 0; i
< 32; ++i
)
397 unsigned long int x
= 1 << i
;
398 int x0
= (match0
& x
) != 0;
399 int x1
= (match1
& x
) != 0;
405 for (i
= 0; i
< 32; ++i
)
407 unsigned long int x
= 1 << i
;
408 int x0
= (lose0
& x
) != 0;
409 int x1
= (lose1
& x
) != 0;
415 /* They are functionally equal. So as long as the opcode table is
416 valid, we can put whichever one first we want, on aesthetic grounds. */
418 /* Our first aesthetic ground is that aliases defer to real insns. */
420 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
422 /* Put the one that isn't an alias first. */
426 /* Except for the above aliases, two "identical" instructions had
427 better have the same opcode. This is a sanity check on the table. */
428 if (0 != strcmp (op0
->name
, op1
->name
))
429 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
430 op0
->name
, op1
->name
);
432 /* Fewer arguments are preferred. */
434 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
435 if (length_diff
!= 0)
436 /* Put the one with fewer arguments first. */
440 /* Put 1+i before i+1. */
442 char *p0
= (char *) strchr(op0
->args
, '+');
443 char *p1
= (char *) strchr(op1
->args
, '+');
447 /* There is a plus in both operands. Note that a plus
448 sign cannot be the first character in args,
449 so the following [-1]'s are valid. */
450 if (p0
[-1] == 'i' && p1
[1] == 'i')
451 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
453 if (p0
[1] == 'i' && p1
[-1] == 'i')
454 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
459 /* They are, as far as we can tell, identical.
460 Since qsort may have rearranged the table partially, there is
461 no way to tell which one was first in the opcode table as
462 written, so just say there are equal. */
This page took 0.055604 seconds and 5 git commands to generate.