1 /* Disassembler for the sparc.
2 Copyright (C) 1989 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. */
25 #include "sparc-opcode.h"
33 extern char *reg_names[];
34 #define freg_names (®_names[4 * 8])
38 unsigned long int code;
57 unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
58 unsigned int IMM13:13;
59 #define imm13 IMM13.IMM13
67 unsigned int DISP22:22;
68 #define disp22 branch.DISP22
74 unsigned int DISP30:30;
75 #define disp30 call.DISP30
79 /* Nonzero if INSN is the opcode for a delayed branch. */
81 is_delayed_branch (insn)
82 union sparc_insn insn;
86 for (i = 0; i < NUMOPCODES; ++i)
88 const struct sparc_opcode *opcode = &sparc_opcodes[i];
89 if ((opcode->match & insn.code) == opcode->match
90 && (opcode->lose & insn.code) == 0)
91 return (opcode->flags & F_DELAYED);
96 static int opcodes_sorted = 0;
98 /* Print one instruction from MEMADDR on STREAM. */
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, &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 'or' instruction where rs1 is the same
133 as rsd, and which has the i bit set? */
134 if (opcode->match == 0x80102000
135 && insn.rs1 == insn.rd)
136 imm_added_to_rs1 = 1;
138 if (insn.rs1 != insn.rd
139 && strchr (opcode->args, 'r') != 0)
140 /* Can't do simple format if source and dest are different. */
143 fputs_filtered (opcode->name, stream);
146 register const char *s;
148 if (opcode->args[0] != ',')
149 fputs_filtered (" ", stream);
150 for (s = opcode->args; *s != '\0'; ++s)
154 fputs_filtered (",", stream);
158 fputs_filtered ("a", stream);
161 fputs_filtered (" ", stream);
169 /* note fall-through */
171 fprintf_filtered (stream, "%c", *s);
175 fputs_filtered ("0", stream);
178 #define reg(n) fprintf_filtered (stream, "%%%s", reg_names[n])
193 #define freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
207 #define creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
222 fprintf_filtered (stream, "%%hi(%#x)",
223 (int) insn.imm22 << 10);
228 /* We cannot trust the compiler to sign-extend
229 when extracting the bitfield, hence the shifts. */
230 int imm = ((int) insn.imm13 << 19) >> 19;
232 /* Check to see whether we have a 1+i, and take
235 Note: because of the way we sort the table,
236 we will be matching 1+i rather than i+1,
237 so it is OK to assume that i is after +,
240 imm_added_to_rs1 = 1;
243 fprintf_filtered (stream, "%d", imm);
245 fprintf_filtered (stream, "%#x", imm);
250 print_address ((CORE_ADDR) memaddr + insn.disp30 * 4,
255 if ((insn.code >> 22) == 0)
256 /* Special case for `unimp'. Don't try to turn
257 it's operand into a function offset. */
258 fprintf_filtered (stream, "%#x",
259 (int) (((int) insn.disp22 << 10) >> 10));
261 /* We cannot trust the compiler to sign-extend
262 when extracting the bitfield, hence the shifts. */
263 print_address ((CORE_ADDR)
265 + (((int) insn.disp22 << 10) >> 10) * 4),
270 fprintf_filtered (stream, "(%d)", (int) insn.asi);
274 fputs_filtered ("%csr", stream);
278 fputs_filtered ("%fsr", stream);
282 fputs_filtered ("%psr", stream);
286 fputs_filtered ("%fq", stream);
290 fputs_filtered ("%cq", stream);
294 fputs_filtered ("%tbr", stream);
298 fputs_filtered ("%wim", stream);
302 fputs_filtered ("%y", stream);
308 /* If we are adding or or'ing something to rs1, then
309 check to see whether the previous instruction was
310 a sethi to the same register as in the sethi.
311 If so, attempt to print the result of the add or
312 or (in this context add and or do the same thing)
313 and its symbolic value. */
314 if (imm_added_to_rs1)
316 union sparc_insn prev_insn;
319 errcode = target_read_memory (memaddr - 4,
320 (char *)&prev_insn, sizeof (prev_insn));
324 /* If it is a delayed branch, we need to look at the
325 instruction before the delayed branch. This handles
328 sethi %o1, %hi(_foo), %o1
330 or %o1, %lo(_foo), %o1
333 if (is_delayed_branch (prev_insn))
334 errcode = target_read_memory
335 (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn));
338 /* If there was a problem reading memory, then assume
339 the previous instruction was not sethi. */
342 /* Is it sethi to the same register? */
343 if ((prev_insn.code & 0xc1c00000) == 0x01000000
344 && prev_insn.rd == insn.rs1)
346 fprintf_filtered (stream, "\t! ");
347 /* We cannot trust the compiler to sign-extend
348 when extracting the bitfield, hence the shifts. */
349 print_address (((int) prev_insn.imm22 << 10)
350 | (insn.imm13 << 19) >> 19, stream);
355 return sizeof (insn);
359 printf_filtered ("%#8x", insn.code);
360 return sizeof (insn);
364 /* Compare opcodes A and B. */
367 compare_opcodes (a, b)
370 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
371 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
372 unsigned long int match0 = op0->match, match1 = op1->match;
373 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
374 register unsigned int i;
376 /* If a bit is set in both match and lose, there is something
377 wrong with the opcode table. */
380 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
381 op0->name, match0, lose0);
382 op0->lose &= ~op0->match;
388 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
389 op1->name, match1, lose1);
390 op1->lose &= ~op1->match;
394 /* Because the bits that are variable in one opcode are constant in
395 another, it is important to order the opcodes in the right order. */
396 for (i = 0; i < 32; ++i)
398 unsigned long int x = 1 << i;
399 int x0 = (match0 & x) != 0;
400 int x1 = (match1 & x) != 0;
406 for (i = 0; i < 32; ++i)
408 unsigned long int x = 1 << i;
409 int x0 = (lose0 & x) != 0;
410 int x1 = (lose1 & x) != 0;
416 /* They are functionally equal. So as long as the opcode table is
417 valid, we can put whichever one first we want, on aesthetic grounds. */
419 /* Our first aesthetic ground is that aliases defer to real insns. */
421 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
423 /* Put the one that isn't an alias first. */
427 /* Except for the above aliases, two "identical" instructions had
428 better have the same opcode. This is a sanity check on the table. */
429 if (0 != strcmp (op0->name, op1->name))
430 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
431 op0->name, op1->name);
433 /* Fewer arguments are preferred. */
435 int length_diff = strlen (op0->args) - strlen (op1->args);
436 if (length_diff != 0)
437 /* Put the one with fewer arguments first. */
441 /* Put 1+i before i+1. */
443 char *p0 = (char *) strchr(op0->args, '+');
444 char *p1 = (char *) strchr(op1->args, '+');
448 /* There is a plus in both operands. Note that a plus
449 sign cannot be the first character in args,
450 so the following [-1]'s are valid. */
451 if (p0[-1] == 'i' && p1[1] == 'i')
452 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
454 if (p0[1] == 'i' && p1[-1] == 'i')
455 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
460 /* They are, as far as we can tell, identical.
461 Since qsort may have rearranged the table partially, there is
462 no way to tell which one was first in the opcode table as
463 written, so just say there are equal. */