Fix prototype problems related to recent disassembler changes
[deliverable/binutils-gdb.git] / opcodes / sparc-dis.c
1 /* Print SPARC instructions.
2 Copyright 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include "opcode/sparc.h"
19 #include "dis-asm.h"
20 #include <string.h>
21
22 static char *reg_names[] =
23 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
24 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
25 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
26 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
27 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
28 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
29 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
30 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
31 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
32
33 #define freg_names (&reg_names[4 * 8])
34
35 /* FIXME--need to deal with byte order (probably using masking and
36 shifting rather than bitfields is easiest). */
37
38 union sparc_insn
39 {
40 unsigned long int code;
41 struct
42 {
43 unsigned int anop:2;
44 #define op ldst.anop
45 unsigned int anrd:5;
46 #define rd ldst.anrd
47 unsigned int op3:6;
48 unsigned int anrs1:5;
49 #define rs1 ldst.anrs1
50 unsigned int i:1;
51 unsigned int anasi:8;
52 #define asi ldst.anasi
53 unsigned int anrs2:5;
54 #define rs2 ldst.anrs2
55 #define shcnt rs2
56 } ldst;
57 struct
58 {
59 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
60 unsigned int IMM13:13;
61 #define imm13 IMM13.IMM13
62 } IMM13;
63 struct
64 {
65 unsigned int anop:2;
66 unsigned int a:1;
67 unsigned int cond:4;
68 unsigned int op2:3;
69 unsigned int DISP22:22;
70 #define disp22 branch.DISP22
71 } branch;
72 #ifndef NO_V9
73 struct
74 {
75 unsigned int _OP:2, _RD:5, op3:6, _RS1:5;
76 unsigned int DISP14:14;
77 #define disp14 DISP14.DISP14
78 } DISP14;
79 struct
80 {
81 unsigned int _OP:2;
82 unsigned int a:1;
83 unsigned int cond:4;
84 unsigned int op2:3;
85 unsigned int p:1;
86 unsigned int DISP21:21;
87 #define disp21 branch2.DISP21
88 } branch2;
89 #endif /* NO_V9 */
90
91 #define imm22 disp22
92 struct
93 {
94 unsigned int anop:2;
95 unsigned int adisp30:30;
96 #define disp30 call.adisp30
97 } call;
98 };
99
100 /* Nonzero if INSN is the opcode for a delayed branch. */
101 static int
102 is_delayed_branch (insn)
103 union sparc_insn insn;
104 {
105 unsigned int i;
106
107 for (i = 0; i < NUMOPCODES; ++i)
108 {
109 const struct sparc_opcode *opcode = &sparc_opcodes[i];
110 if ((opcode->match & insn.code) == opcode->match
111 && (opcode->lose & insn.code) == 0)
112 return (opcode->flags & F_DELAYED);
113 }
114 return 0;
115 }
116
117 static int opcodes_sorted = 0;
118 extern void qsort ();
119
120 /* Print one instruction from MEMADDR on STREAM.
121
122 We suffix the instruction with a comment that gives the absolute
123 address involved, as well as its symbolic form, if the instruction
124 is preceded by a findable `sethi' and it either adds an immediate
125 displacement to that register, or it is an `add' or `or' instruction
126 on that register. */
127 int
128 print_insn_sparc (memaddr, info)
129 bfd_vma memaddr;
130 disassemble_info *info;
131 {
132 FILE *stream = info->stream;
133 union sparc_insn insn;
134
135 register unsigned int i;
136
137 if (!opcodes_sorted)
138 {
139 static int compare_opcodes ();
140 qsort ((char *) sparc_opcodes, NUMOPCODES,
141 sizeof (sparc_opcodes[0]), compare_opcodes);
142 opcodes_sorted = 1;
143 }
144
145 {
146 int status =
147 (*info->read_memory_func) (memaddr, (char *) &insn, sizeof (insn), info);
148 if (status != 0)
149 {
150 (*info->memory_error_func) (status, memaddr, info);
151 return -1;
152 }
153 }
154
155 for (i = 0; i < NUMOPCODES; ++i)
156 {
157 const struct sparc_opcode *opcode = &sparc_opcodes[i];
158 if ((opcode->match & insn.code) == opcode->match
159 && (opcode->lose & insn.code) == 0)
160 {
161 /* Nonzero means that we have found an instruction which has
162 the effect of adding or or'ing the imm13 field to rs1. */
163 int imm_added_to_rs1 = 0;
164
165 /* Nonzero means that we have found a plus sign in the args
166 field of the opcode table. */
167 int found_plus = 0;
168
169 /* Do we have an `add' or `or' instruction where rs1 is the same
170 as rsd, and which has the i bit set? */
171 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
172 /* (or) (add) */
173 && insn.rs1 == insn.rd)
174 imm_added_to_rs1 = 1;
175
176 if (insn.rs1 != insn.rd
177 && strchr (opcode->args, 'r') != 0)
178 /* Can't do simple format if source and dest are different. */
179 continue;
180
181 (*info->fprintf_func) (stream, opcode->name);
182
183 {
184 register const char *s;
185
186 if (opcode->args[0] != ',')
187 (*info->fprintf_func) (stream, " ");
188 for (s = opcode->args; *s != '\0'; ++s)
189 {
190 while (*s == ',')
191 {
192 (*info->fprintf_func) (stream, ",");
193 ++s;
194 switch (*s) {
195 case 'a':
196 (*info->fprintf_func) (stream, "a");
197 ++s;
198 continue;
199 #ifndef NO_V9
200 case 'N':
201 (*info->fprintf_func) (stream, "pn");
202 ++s;
203 continue;
204
205 case 'T':
206 (*info->fprintf_func) (stream, "pt");
207 ++s;
208 continue;
209 #endif /* NO_V9 */
210
211 default:
212 break;
213 } /* switch on arg */
214 } /* while there are comma started args */
215
216 (*info->fprintf_func) (stream, " ");
217
218 switch (*s)
219 {
220 case '+':
221 found_plus = 1;
222
223 /* note fall-through */
224 default:
225 (*info->fprintf_func) (stream, "%c", *s);
226 break;
227
228 case '#':
229 (*info->fprintf_func) (stream, "0");
230 break;
231
232 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
233 case '1':
234 case 'r':
235 reg (insn.rs1);
236 break;
237
238 case '2':
239 reg (insn.rs2);
240 break;
241
242 case 'd':
243 reg (insn.rd);
244 break;
245 #undef reg
246
247 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
248 case 'e':
249 case 'v': /* double/even */
250 case 'V': /* quad/multiple of 4 */
251 freg (insn.rs1);
252 break;
253
254 case 'f':
255 case 'B': /* double/even */
256 case 'R': /* quad/multiple of 4 */
257 freg (insn.rs2);
258 break;
259
260 case 'g':
261 case 'H': /* double/even */
262 case 'J': /* quad/multiple of 4 */
263 freg (insn.rd);
264 break;
265 #undef freg
266
267 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
268 case 'b':
269 creg (insn.rs1);
270 break;
271
272 case 'c':
273 creg (insn.rs2);
274 break;
275
276 case 'D':
277 creg (insn.rd);
278 break;
279 #undef creg
280
281 case 'h':
282 (*info->fprintf_func) (stream, "%%hi(%#x)",
283 (int) insn.imm22 << 10);
284 break;
285
286 case 'i':
287 {
288 /* We cannot trust the compiler to sign-extend
289 when extracting the bitfield, hence the shifts. */
290 int imm = ((int) insn.imm13 << 19) >> 19;
291
292 /* Check to see whether we have a 1+i, and take
293 note of that fact.
294
295 Note: because of the way we sort the table,
296 we will be matching 1+i rather than i+1,
297 so it is OK to assume that i is after +,
298 not before it. */
299 if (found_plus)
300 imm_added_to_rs1 = 1;
301
302 if (imm <= 9)
303 (*info->fprintf_func) (stream, "%d", imm);
304 else
305 (*info->fprintf_func) (stream, "%#x", imm);
306 }
307 break;
308
309 #ifndef NO_V9
310 case 'I': /* 11 bit immediate. */
311 case 'j': /* 10 bit immediate. */
312 {
313 /* We cannot trust the compiler to sign-extend
314 when extracting the bitfield, hence the shifts. */
315 int imm;
316
317 if (*s == 'I')
318 imm = ((int) insn.imm13 << 21) >> 21;
319 else
320 imm = ((int) insn.imm13 << 22) >> 22;
321
322 /* Check to see whether we have a 1+i, and take
323 note of that fact.
324
325 Note: because of the way we sort the table,
326 we will be matching 1+i rather than i+1,
327 so it is OK to assume that i is after +,
328 not before it. */
329 if (found_plus)
330 imm_added_to_rs1 = 1;
331
332 if (imm <= 9)
333 (info->fprintf_func) (stream, "%d", imm);
334 else
335 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
336 }
337 break;
338
339
340
341
342 case 'k':
343 print_address ((bfd_vma)
344 (memaddr
345 + (((int) insn.disp14 << 18) >> 18) * 4),
346 stream);
347 break;
348
349 case 'G':
350 print_address ((bfd_vma)
351 (memaddr
352 /* We use only 19 of the 21 bits. */
353 + (((int) insn.disp21 << 13) >> 13) * 4),
354 stream);
355 break;
356
357 case '6':
358 case '7':
359 case '8':
360 case '9':
361 fprintf (stream, "fcc%c", *s - '6' + '0');
362 break;
363
364 case 'z':
365 fputs ("icc", stream);
366 break;
367
368 case 'Z':
369 fputs ("xcc", stream);
370 break;
371
372 case 'E':
373 fputs ("%ccr", stream);
374 break;
375
376 case 's':
377 fputs ("%fprs", stream);
378 break;
379 #endif /* NO_V9 */
380
381 case 'M':
382 fprintf(stream, "%%asr%d", insn.rs1);
383 break;
384
385 case 'm':
386 fprintf(stream, "%%asr%d", insn.rd);
387 break;
388
389 case 'L':
390 print_address ((bfd_vma) memaddr + insn.disp30 * 4,
391 stream);
392 break;
393
394 case 'l':
395 if ((insn.code >> 22) == 0)
396 /* Special case for `unimp'. Don't try to turn
397 it's operand into a function offset. */
398 (*info->fprintf_func)
399 (stream, "%#x",
400 (int) (((int) insn.disp22 << 10) >> 10));
401 else
402 /* We cannot trust the compiler to sign-extend
403 when extracting the bitfield, hence the shifts. */
404 print_address ((bfd_vma)
405 (memaddr
406 + (((int) insn.disp22 << 10) >> 10) * 4),
407 stream);
408 break;
409
410 case 'A':
411 (*info->fprintf_func) (stream, "(%d)", (int) insn.asi);
412 break;
413
414 case 'C':
415 (*info->fprintf_func) (stream, "%csr");
416 break;
417
418 case 'F':
419 (*info->fprintf_func) (stream, "%fsr");
420 break;
421
422 case 'p':
423 (*info->fprintf_func) (stream, "%psr");
424 break;
425
426 case 'q':
427 (*info->fprintf_func) (stream, "%fq");
428 break;
429
430 case 'Q':
431 (*info->fprintf_func) (stream, "%cq");
432 break;
433
434 case 't':
435 (*info->fprintf_func) (stream, "%tbr");
436 break;
437
438 case 'w':
439 (*info->fprintf_func) (stream, "%wim");
440 break;
441
442 case 'y':
443 (*info->fprintf_func) (stream, "%y");
444 break;
445 }
446 }
447 }
448
449 /* If we are adding or or'ing something to rs1, then
450 check to see whether the previous instruction was
451 a sethi to the same register as in the sethi.
452 If so, attempt to print the result of the add or
453 or (in this context add and or do the same thing)
454 and its symbolic value. */
455 if (imm_added_to_rs1)
456 {
457 union sparc_insn prev_insn;
458 int errcode;
459
460 errcode =
461 (*info->read_memory_func)
462 (memaddr - 4,
463 (char *)&prev_insn, sizeof (prev_insn), info);
464
465 if (errcode == 0)
466 {
467 /* If it is a delayed branch, we need to look at the
468 instruction before the delayed branch. This handles
469 sequences such as
470
471 sethi %o1, %hi(_foo), %o1
472 call _printf
473 or %o1, %lo(_foo), %o1
474 */
475
476 if (is_delayed_branch (prev_insn))
477 errcode = (*info->read_memory_func)
478 (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn),
479 info);
480 }
481
482 /* If there was a problem reading memory, then assume
483 the previous instruction was not sethi. */
484 if (errcode == 0)
485 {
486 /* Is it sethi to the same register? */
487 if ((prev_insn.code & 0xc1c00000) == 0x01000000
488 && prev_insn.rd == insn.rs1)
489 {
490 (*info->fprintf_func) (stream, "\t! ");
491 /* We cannot trust the compiler to sign-extend
492 when extracting the bitfield, hence the shifts. */
493 print_address (((int) prev_insn.imm22 << 10)
494 | (insn.imm13 << 19) >> 19, stream);
495 }
496 }
497 }
498
499 return sizeof (insn);
500 }
501 }
502
503 (*info->fprintf_func) (stream, "%#8x", insn.code);
504 return sizeof (insn);
505 }
506
507 /* Compare opcodes A and B. */
508
509 static int
510 compare_opcodes (a, b)
511 char *a, *b;
512 {
513 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
514 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
515 unsigned long int match0 = op0->match, match1 = op1->match;
516 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
517 register unsigned int i;
518
519 /* If a bit is set in both match and lose, there is something
520 wrong with the opcode table. */
521 if (match0 & lose0)
522 {
523 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
524 op0->name, match0, lose0);
525 op0->lose &= ~op0->match;
526 lose0 = op0->lose;
527 }
528
529 if (match1 & lose1)
530 {
531 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
532 op1->name, match1, lose1);
533 op1->lose &= ~op1->match;
534 lose1 = op1->lose;
535 }
536
537 /* Because the bits that are variable in one opcode are constant in
538 another, it is important to order the opcodes in the right order. */
539 for (i = 0; i < 32; ++i)
540 {
541 unsigned long int x = 1 << i;
542 int x0 = (match0 & x) != 0;
543 int x1 = (match1 & x) != 0;
544
545 if (x0 != x1)
546 return x1 - x0;
547 }
548
549 for (i = 0; i < 32; ++i)
550 {
551 unsigned long int x = 1 << i;
552 int x0 = (lose0 & x) != 0;
553 int x1 = (lose1 & x) != 0;
554
555 if (x0 != x1)
556 return x1 - x0;
557 }
558
559 /* They are functionally equal. So as long as the opcode table is
560 valid, we can put whichever one first we want, on aesthetic grounds. */
561
562 /* Our first aesthetic ground is that aliases defer to real insns. */
563 {
564 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
565 if (alias_diff != 0)
566 /* Put the one that isn't an alias first. */
567 return alias_diff;
568 }
569
570 /* Except for aliases, two "identical" instructions had
571 better have the same opcode. This is a sanity check on the table. */
572 i = strcmp (op0->name, op1->name);
573 if (i)
574 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
575 return i;
576 else
577 fprintf (stderr,
578 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
579 op0->name, op1->name);
580
581 /* Fewer arguments are preferred. */
582 {
583 int length_diff = strlen (op0->args) - strlen (op1->args);
584 if (length_diff != 0)
585 /* Put the one with fewer arguments first. */
586 return length_diff;
587 }
588
589 /* Put 1+i before i+1. */
590 {
591 char *p0 = (char *) strchr(op0->args, '+');
592 char *p1 = (char *) strchr(op1->args, '+');
593
594 if (p0 && p1)
595 {
596 /* There is a plus in both operands. Note that a plus
597 sign cannot be the first character in args,
598 so the following [-1]'s are valid. */
599 if (p0[-1] == 'i' && p1[1] == 'i')
600 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
601 return 1;
602 if (p0[1] == 'i' && p1[-1] == 'i')
603 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
604 return -1;
605 }
606 }
607
608 /* They are, as far as we can tell, identical.
609 Since qsort may have rearranged the table partially, there is
610 no way to tell which one was first in the opcode table as
611 written, so just say there are equal. */
612 return 0;
613 }
This page took 0.068057 seconds and 5 git commands to generate.