Added gdb.
[deliverable/binutils-gdb.git] / binutils / sparc-pinsn.c
CommitLineData
2fa0b342
DHW
1/* disassemble sparc instructions for objdump
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
3
4
5This file is part of the binutils.
6
7The binutils are free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
11
12The binutils are distributed in the hope that they will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with the binutils; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* $Id$
22 $Log$
75a082e2
SC
23 Revision 1.2 1991/04/18 21:14:21 steve
24 Send the right # of args to an fprintf
2fa0b342 25
75a082e2
SC
26 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
27 * Back from Intel with Steve
28 *
c074abee
DHW
29 * Revision 1.1 1991/03/21 21:26:55 gumby
30 * Initial revision
31 *
2fa0b342
DHW
32 * Revision 1.1 1991/03/13 00:34:40 chrisb
33 * Initial revision
34 *
35 * Revision 1.3 1991/03/09 04:36:31 rich
36 * Modified Files:
37 * sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
38 * binutils.h
39 *
40 * Pulled sysdep.h out of bfd.h.
41 *
42 * Revision 1.2 1991/03/08 21:54:53 rich
43 * Modified Files:
44 * Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
45 * i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
46 * sparc-pinsn.c strip.c
47 *
48 * Verifying Portland tree with steve's last changes. Also, some partial
49 * porting.
50 *
51 * Revision 1.1 1991/02/22 16:48:04 sac
52 * Initial revision
53 *
54*/
55
56#include <stdio.h>
57#include "sysdep.h"
58#include "bfd.h"
59#include "sparc-opcode.h"
60
61extern int fputs();
62extern int print_address();
63
64static char *reg_names[] =
65 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
66 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
67 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
68 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
69 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
70 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
71 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
72 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
73 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
74
75#define freg_names (&reg_names[4 * 8])
76
77union sparc_insn
78 {
79 unsigned long int code;
80 struct
81 {
82 unsigned int OP:2;
83#define op ldst.OP
84 unsigned int RD:5;
85#define rd ldst.RD
86 unsigned int op3:6;
87 unsigned int RS1:5;
88#define rs1 ldst.RS1
89 unsigned int i:1;
90 unsigned int ASI:8;
91#define asi ldst.ASI
92 unsigned int RS2:5;
93#define rs2 ldst.RS2
94#define shcnt rs2
95 } ldst;
96 struct
97 {
98 unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
99 unsigned int IMM13:13;
100#define imm13 IMM13.IMM13
101 } IMM13;
102 struct
103 {
104 unsigned int OP:2;
105 unsigned int a:1;
106 unsigned int cond:4;
107 unsigned int op2:3;
108 unsigned int DISP22:22;
109#define disp22 branch.DISP22
110 } branch;
111#define imm22 disp22
112 struct
113 {
114 unsigned int OP:2;
115 unsigned int DISP30:30;
116#define disp30 call.DISP30
117 } call;
118 };
119
120/* Nonzero if INSN is the opcode for a delayed branch. */
121static int
122is_delayed_branch (insn)
123 union sparc_insn insn;
124{
125 unsigned int i;
126
127 for (i = 0; i < NUMOPCODES; ++i)
128 {
129 const struct sparc_opcode *opcode = &sparc_opcodes[i];
130 if ((opcode->match & insn.code) == opcode->match
131 && (opcode->lose & insn.code) == 0
132 && (opcode->delayed))
133 return 1;
134 }
135 return 0;
136}
137
138static int opcodes_sorted = 0;
139
140/* Print one instruction from MEMADDR on STREAM. */
141int
142print_insn_sparc (memaddr, buffer, stream)
143 bfd_vma memaddr;
144 bfd_byte *buffer;
145 FILE *stream;
146
147{
148 union sparc_insn insn;
149
150 register unsigned int i;
151
152 if (!opcodes_sorted)
153 {
154 static int compare_opcodes ();
155 qsort ((char *) sparc_opcodes, NUMOPCODES,
156 sizeof (sparc_opcodes[0]), compare_opcodes);
157 opcodes_sorted = 1;
158 }
159
160memcpy(&insn,buffer, sizeof (insn));
161
162 for (i = 0; i < NUMOPCODES; ++i)
163 {
164 const struct sparc_opcode *opcode = &sparc_opcodes[i];
165 if ((opcode->match & insn.code) == opcode->match
166 && (opcode->lose & insn.code) == 0)
167 {
168 /* Nonzero means that we have found an instruction which has
169 the effect of adding or or'ing the imm13 field to rs1. */
170 int imm_added_to_rs1 = 0;
171
172 /* Nonzero means that we have found a plus sign in the args
173 field of the opcode table. */
174 int found_plus = 0;
175
176 /* Do we have an 'or' instruction where rs1 is the same
177 as rsd, and which has the i bit set? */
178 if (opcode->match == 0x80102000
179 && insn.rs1 == insn.rd)
180 imm_added_to_rs1 = 1;
181
182 if (index (opcode->args, 'S') != 0)
183 /* Reject the special case for `set'.
184 The real `sethi' will match. */
185 continue;
186 if (insn.rs1 != insn.rd
187 && index (opcode->args, 'r') != 0)
188 /* Can't do simple format if source and dest are different. */
189 continue;
190
191 fputs (opcode->name, stream);
192
193 {
194 register const char *s;
195
196 if (opcode->args[0] != ',')
197 fputs (" ", stream);
198 for (s = opcode->args; *s != '\0'; ++s)
199 {
200 if (*s == ',')
201 {
202 fputs (",", stream);
203 ++s;
204 if (*s == 'a')
205 {
206 fputs ("a", stream);
207 ++s;
208 }
209 fputs (" ", stream);
210 }
211
212 switch (*s)
213 {
214 case '+':
215 found_plus = 1;
216
217 /* note fall-through */
218 default:
219 fprintf (stream, "%c", *s);
220 break;
221
222 case '#':
223 fputs ("0", stream);
224 break;
225
226#define reg(n) fprintf (stream, "%%%s", reg_names[n])
227 case '1':
228 case 'r':
229 reg (insn.rs1);
230 break;
231
232 case '2':
233 reg (insn.rs2);
234 break;
235
236 case 'd':
237 reg (insn.rd);
238 break;
239#undef reg
240
241#define freg(n) fprintf (stream, "%%%s", freg_names[n])
242 case 'e':
243 freg (insn.rs1);
244 break;
245
246 case 'f':
247 freg (insn.rs2);
248 break;
249
250 case 'g':
251 freg (insn.rd);
252 break;
253#undef freg
254
255#define creg(n) fprintf (stream, "%%c%u", (unsigned int) (n))
256 case 'b':
257 creg (insn.rs1);
258 break;
259
260 case 'c':
261 creg (insn.rs2);
262 break;
263
264 case 'D':
265 creg (insn.rd);
266 break;
267#undef creg
268
269 case 'h':
270 fprintf (stream, "%%hi(%#x)",
271 (unsigned int) insn.imm22 << 10);
272 break;
273
274 case 'i':
275 {
276 /* We cannot trust the compiler to sign-extend
277 when extracting the bitfield, hence the shifts. */
278 int imm = ((int) insn.imm13 << 19) >> 19;
279
280 /* Check to see whether we have a 1+i, and take
281 note of that fact.
282
283 Note: because of the way we sort the table,
284 we will be matching 1+i rather than i+1,
285 so it is OK to assume that i is after +,
286 not before it. */
287 if (found_plus)
288 imm_added_to_rs1 = 1;
289
290 if (imm <= 9)
291 fprintf (stream, "%d", imm);
292 else
293 fprintf (stream, "%#x", (unsigned) imm);
294 }
295 break;
296
297 case 'L':
298 print_address ((bfd_vma) memaddr + insn.disp30 * 4,
299 stream);
300 break;
301
302 case 'l':
303 if ((insn.code >> 22) == 0)
304 /* Special case for `unimp'. Don't try to turn
305 it's operand into a function offset. */
306 fprintf (stream, "%#x",
307 (unsigned) (((int) insn.disp22 << 10) >> 10));
308 else
309 /* We cannot trust the compiler to sign-extend
310 when extracting the bitfield, hence the shifts. */
311 print_address ((bfd_vma)
312 (memaddr
313 + (((int) insn.disp22 << 10) >> 10) * 4),
314 stream);
315 break;
316
317 case 'A':
318 fprintf (stream, "(%d)", (int) insn.asi);
319 break;
320
321 case 'C':
322 fputs ("%csr", stream);
323 break;
324
325 case 'F':
326 fputs ("%fsr", stream);
327 break;
328
329 case 'p':
330 fputs ("%psr", stream);
331 break;
332
333 case 'q':
334 fputs ("%fq", stream);
335 break;
336
337 case 'Q':
338 fputs ("%cq", stream);
339 break;
340
341 case 't':
342 fputs ("%tbr", stream);
343 break;
344
345 case 'w':
346 fputs ("%wim", stream);
347 break;
348
349 case 'y':
350 fputs ("%y", stream);
351 break;
352 }
353 }
354 }
355
356 /* If we are adding or or'ing something to rs1, then
357 check to see whether the previous instruction was
358 a sethi to the same register as in the sethi.
359 If so, attempt to print the result of the add or
360 or (in this context add and or do the same thing)
361 and its symbolic value. */
362 if (imm_added_to_rs1)
363 {
364 union sparc_insn prev_insn;
365 int errcode;
366
367 memcpy(&prev_insn, buffer -4, sizeof (prev_insn));
368
369 if (errcode == 0)
370 {
371 /* If it is a delayed branch, we need to look at the
372 instruction before the delayed branch. This handles
373 sequences such as
374
375 sethi %o1, %hi(_foo), %o1
376 call _printf
377 or %o1, %lo(_foo), %o1
378 */
379
380 if (is_delayed_branch (prev_insn))
381 memcpy(&prev_insn, buffer - 8, sizeof(prev_insn));
382
383 }
384
385 /* If there was a problem reading memory, then assume
386 the previous instruction was not sethi. */
387 if (errcode == 0)
388 {
389 /* Is it sethi to the same register? */
390 if ((prev_insn.code & 0xc1c00000) == 0x01000000
391 && prev_insn.rd == insn.rs1)
392 {
393 fprintf (stream, "\t! ");
394 /* We cannot trust the compiler to sign-extend
395 when extracting the bitfield, hence the shifts. */
396 print_address (((int) prev_insn.imm22 << 10)
397 | (insn.imm13 << 19) >> 19, stream);
398 }
399 }
400 }
401
402 return sizeof (insn);
403 }
404 }
405
75a082e2 406 fprintf (stream, "%#8x", insn.code);
2fa0b342
DHW
407 return sizeof (insn);
408}
409
410
411/* Compare opcodes A and B. */
412
413static int
414compare_opcodes (a, b)
415 char *a, *b;
416{
417 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
418 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
419 unsigned long int match0 = op0->match, match1 = op1->match;
420 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
421 register unsigned int i;
422
423 /* If a bit is set in both match and lose, there is something
424 wrong with the opcode table. */
425 if (match0 & lose0)
426 {
427 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
428 op0->name, match0, lose0);
429 op0->lose &= ~op0->match;
430 lose0 = op0->lose;
431 }
432
433 if (match1 & lose1)
434 {
435 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
436 op1->name, match1, lose1);
437 op1->lose &= ~op1->match;
438 lose1 = op1->lose;
439 }
440
441 /* Because the bits that are variable in one opcode are constant in
442 another, it is important to order the opcodes in the right order. */
443 for (i = 0; i < 32; ++i)
444 {
445 unsigned long int x = 1 << i;
446 int x0 = (match0 & x) != 0;
447 int x1 = (match1 & x) != 0;
448
449 if (x0 != x1)
450 return x1 - x0;
451 }
452
453 for (i = 0; i < 32; ++i)
454 {
455 unsigned long int x = 1 << i;
456 int x0 = (lose0 & x) != 0;
457 int x1 = (lose1 & x) != 0;
458
459 if (x0 != x1)
460 return x1 - x0;
461 }
462
463 /* They are functionally equal. So as long as the opcode table is
464 valid, we can put whichever one first we want, on aesthetic grounds. */
465 {
466 int length_diff = strlen (op0->args) - strlen (op1->args);
467 if (length_diff != 0)
468 /* Put the one with fewer arguments first. */
469 return length_diff;
470 }
471
472 /* Put 1+i before i+1. */
473 {
474 char *p0 = (char *) index(op0->args, '+');
475 char *p1 = (char *) index(op1->args, '+');
476
477 if (p0 && p1)
478 {
479 /* There is a plus in both operands. Note that a plus
480 sign cannot be the first character in args,
481 so the following [-1]'s are valid. */
482 if (p0[-1] == 'i' && p1[1] == 'i')
483 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
484 return 1;
485 if (p0[1] == 'i' && p1[-1] == 'i')
486 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
487 return -1;
488 }
489 }
490
491 /* They are, as far as we can tell, identical.
492 Since qsort may have rearranged the table partially, there is
493 no way to tell which one was first in the opcode table as
494 written, so just say there are equal. */
495 return 0;
496}
This page took 0.055316 seconds and 4 git commands to generate.