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