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