v9 stuff.
[binutils-gdb.git] / binutils / sparc-pinsn.c
1 /* disassemble sparc instructions for objdump
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
3
4
5 This file is part of the binutils.
6
7 The binutils are free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 The binutils are distributed in the hope that they will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with the binutils; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /* $Id$
22 $Log$
23 Revision 1.4 1991/05/22 01:17:48 rich
24 v9 stuff.
25
26 * Revision 1.3 1991/05/19 08:00:57 rich
27 * Updated to relect a gdb change in sparc-opcode.h.
28 *
29 * Revision 1.2 1991/04/18 21:14:21 steve
30 * Send the right # of args to an fprintf
31 *
32 * Revision 1.1.1.1 1991/03/21 21:26:56 gumby
33 * Back from Intel with Steve
34 *
35 * Revision 1.1 1991/03/21 21:26:55 gumby
36 * Initial revision
37 *
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
67 extern int fputs();
68 extern int print_address();
69
70 static 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
83 union sparc_insn
84 {
85 unsigned long int code;
86 struct
87 {
88 unsigned int _OP:2;
89 #define op ldst._OP
90 unsigned int _RD:5;
91 #define rd ldst._RD
92 unsigned int op3:6;
93 unsigned int _RS1:5;
94 #define rs1 ldst._RS1
95 unsigned int i:1;
96 unsigned int _ASI:8;
97 #define asi ldst._ASI
98 unsigned int _RS2:5;
99 #define rs2 ldst._RS2
100 #define shcnt rs2
101 } ldst;
102 struct
103 {
104 unsigned int _OP:2, _RD:5, op3:6, _RS1:5, i:1;
105 unsigned int IMM13:13;
106 #define imm13 IMM13.IMM13
107 } IMM13;
108 struct
109 {
110 unsigned int _OP:2;
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;
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
136 #define imm22 disp22
137 struct
138 {
139 unsigned int _OP:2;
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. */
146 static int
147 is_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
157 && (opcode->flags&F_DELAYED))
158 return 1;
159 }
160 return 0;
161 }
162
163 static int opcodes_sorted = 0;
164
165 /* Print one instruction from MEMADDR on STREAM. */
166 int
167 print_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
185 memcpy(&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);
223 for (s = opcode->args; *s != '\0'; ++s) {
224 while (*s == ',') {
225 fputs (",", stream);
226 ++s;
227
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
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
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':
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
475 fprintf (stream, "%#8x", insn.code);
476 return sizeof (insn);
477 }
478
479
480 /* Compare opcodes A and B. */
481
482 static int
483 compare_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 }