0962f9f571e5841b3661e9a99f15f5ef4e72b430
[deliverable/binutils-gdb.git] / opcodes / sparc-dis.c
1 /* Print SPARC instructions.
2 Copyright 1989, 1991, 1992, 1993, 1995 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #include "ansidecl.h"
19 #include "opcode/sparc.h"
20 #include "dis-asm.h"
21 #include "libiberty.h"
22 #include <string.h>
23
24 /* For faster lookup, after insns are sorted they are hashed. */
25 /* ??? I think there is room for even more improvement. */
26
27 #define HASH_SIZE 256
28 /* It is important that we only look at insn code bits as that is how the
29 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
30 of the main types (0,1,2,3). */
31 static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
32 #define HASH_INSN(INSN) \
33 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
34 struct opcode_hash {
35 struct opcode_hash *next;
36 struct sparc_opcode *opcode;
37 };
38 static struct opcode_hash *opcode_hash_table[HASH_SIZE];
39 static void build_hash_table ();
40
41 /* Sign-extend a value which is N bits long. */
42 #define SEX(value, bits) \
43 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
44 >> ((8 * sizeof (int)) - bits) )
45
46 static char *reg_names[] =
47 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
48 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
49 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
50 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
51 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
52 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
53 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
54 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
55 #ifndef NO_V9
56 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
57 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
58 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
59 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
60 /* psr, wim, tbr, fpsr, cpsr are v8 only. */
61 #endif
62 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
63 };
64
65 #define freg_names (&reg_names[4 * 8])
66
67 #ifndef NO_V9
68 /* These are ordered according to there register number in
69 rdpr and wrpr insns. */
70 static char *v9_priv_reg_names[] =
71 {
72 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
73 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
74 "wstate", "fq"
75 /* "ver" - special cased */
76 };
77 #endif
78
79 /* Macros used to extract instruction fields. Not all fields have
80 macros defined here, only those which are actually used. */
81
82 #define X_RD(i) (((i) >> 25) & 0x1f)
83 #define X_RS1(i) (((i) >> 14) & 0x1f)
84 #define X_LDST_I(i) (((i) >> 13) & 1)
85 #define X_ASI(i) (((i) >> 5) & 0xff)
86 #define X_RS2(i) (((i) >> 0) & 0x1f)
87 #define X_IMM13(i) (((i) >> 0) & 0x1fff)
88 #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
89 #define X_IMM22(i) X_DISP22 (i)
90 #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
91
92 #ifndef NO_V9
93 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
94 #endif
95
96 /* Here is the union which was used to extract instruction fields
97 before the shift and mask macros were written.
98
99 union sparc_insn
100 {
101 unsigned long int code;
102 struct
103 {
104 unsigned int anop:2;
105 #define op ldst.anop
106 unsigned int anrd:5;
107 #define rd ldst.anrd
108 unsigned int op3:6;
109 unsigned int anrs1:5;
110 #define rs1 ldst.anrs1
111 unsigned int i:1;
112 unsigned int anasi:8;
113 #define asi ldst.anasi
114 unsigned int anrs2:5;
115 #define rs2 ldst.anrs2
116 #define shcnt rs2
117 } ldst;
118 struct
119 {
120 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
121 unsigned int IMM13:13;
122 #define imm13 IMM13.IMM13
123 } IMM13;
124 struct
125 {
126 unsigned int anop:2;
127 unsigned int a:1;
128 unsigned int cond:4;
129 unsigned int op2:3;
130 unsigned int DISP22:22;
131 #define disp22 branch.DISP22
132 #define imm22 disp22
133 } branch;
134 #ifndef NO_V9
135 struct
136 {
137 unsigned int anop:2;
138 unsigned int a:1;
139 unsigned int z:1;
140 unsigned int rcond:3;
141 unsigned int op2:3;
142 unsigned int DISP16HI:2;
143 unsigned int p:1;
144 unsigned int _rs1:5;
145 unsigned int DISP16LO:14;
146 } branch16;
147 #endif
148 struct
149 {
150 unsigned int anop:2;
151 unsigned int adisp30:30;
152 #define disp30 call.adisp30
153 } call;
154 };
155
156 */
157
158 /* Nonzero if INSN is the opcode for a delayed branch. */
159 static int
160 is_delayed_branch (insn)
161 unsigned long insn;
162 {
163 struct opcode_hash *op;
164
165 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
166 {
167 CONST struct sparc_opcode *opcode = op->opcode;
168 if ((opcode->match & insn) == opcode->match
169 && (opcode->lose & insn) == 0)
170 return (opcode->flags & F_DELAYED);
171 }
172 return 0;
173 }
174
175 /* Nonzero of opcode table has been initialized. */
176 static int opcodes_initialized = 0;
177
178 /* extern void qsort (); */
179 static int compare_opcodes ();
180
181 /* Print one instruction from MEMADDR on INFO->STREAM.
182
183 We suffix the instruction with a comment that gives the absolute
184 address involved, as well as its symbolic form, if the instruction
185 is preceded by a findable `sethi' and it either adds an immediate
186 displacement to that register, or it is an `add' or `or' instruction
187 on that register. */
188
189 static int
190 print_insn (memaddr, info, sparc64_p)
191 bfd_vma memaddr;
192 disassemble_info *info;
193 int sparc64_p;
194 {
195 FILE *stream = info->stream;
196 bfd_byte buffer[4];
197 unsigned long insn;
198 register unsigned int i;
199 register struct opcode_hash *op;
200
201 if (!opcodes_initialized)
202 {
203 qsort ((char *) sparc_opcodes, NUMOPCODES,
204 sizeof (sparc_opcodes[0]), compare_opcodes);
205 build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES);
206 opcodes_initialized = 1;
207 }
208
209 {
210 int status =
211 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
212 if (status != 0)
213 {
214 (*info->memory_error_func) (status, memaddr, info);
215 return -1;
216 }
217 }
218
219 insn = bfd_getb32 (buffer);
220
221 info->insn_info_valid = 1; /* We do return this info */
222 info->insn_type = dis_nonbranch; /* Assume non branch insn */
223 info->branch_delay_insns = 0; /* Assume no delay */
224 info->target = 0; /* Assume no target known */
225
226 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
227 {
228 CONST struct sparc_opcode *opcode = op->opcode;
229
230 /* If the current architecture isn't sparc64, skip sparc64 insns. */
231 if (!sparc64_p
232 && opcode->architecture == v9)
233 continue;
234
235 /* If the current architecture is sparc64, skip sparc32 only insns. */
236 if (sparc64_p
237 && (opcode->flags & F_NOTV9))
238 continue;
239
240 if ((opcode->match & insn) == opcode->match
241 && (opcode->lose & insn) == 0)
242 {
243 /* Nonzero means that we have found an instruction which has
244 the effect of adding or or'ing the imm13 field to rs1. */
245 int imm_added_to_rs1 = 0;
246
247 /* Nonzero means that we have found a plus sign in the args
248 field of the opcode table. */
249 int found_plus = 0;
250
251 /* Nonzero means we have an annulled branch. */
252 int is_annulled = 0;
253
254 /* Do we have an `add' or `or' instruction where rs1 is the same
255 as rsd, and which has the i bit set? */
256 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
257 /* (or) (add) */
258 && X_RS1 (insn) == X_RD (insn))
259 imm_added_to_rs1 = 1;
260
261 if (X_RS1 (insn) != X_RD (insn)
262 && strchr (opcode->args, 'r') != 0)
263 /* Can't do simple format if source and dest are different. */
264 continue;
265
266 (*info->fprintf_func) (stream, opcode->name);
267
268 {
269 register CONST char *s;
270
271 if (opcode->args[0] != ',')
272 (*info->fprintf_func) (stream, " ");
273 for (s = opcode->args; *s != '\0'; ++s)
274 {
275 while (*s == ',')
276 {
277 (*info->fprintf_func) (stream, ",");
278 ++s;
279 switch (*s) {
280 case 'a':
281 (*info->fprintf_func) (stream, "a");
282 is_annulled = 1;
283 ++s;
284 continue;
285 #ifndef NO_V9
286 case 'N':
287 (*info->fprintf_func) (stream, "pn");
288 ++s;
289 continue;
290
291 case 'T':
292 (*info->fprintf_func) (stream, "pt");
293 ++s;
294 continue;
295 #endif /* NO_V9 */
296
297 default:
298 break;
299 } /* switch on arg */
300 } /* while there are comma started args */
301
302 (*info->fprintf_func) (stream, " ");
303
304 switch (*s)
305 {
306 case '+':
307 found_plus = 1;
308
309 /* note fall-through */
310 default:
311 (*info->fprintf_func) (stream, "%c", *s);
312 break;
313
314 case '#':
315 (*info->fprintf_func) (stream, "0");
316 break;
317
318 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
319 case '1':
320 case 'r':
321 reg (X_RS1 (insn));
322 break;
323
324 case '2':
325 reg (X_RS2 (insn));
326 break;
327
328 case 'd':
329 reg (X_RD (insn));
330 break;
331 #undef reg
332
333 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
334 #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
335 case 'e':
336 freg (X_RS1 (insn));
337 break;
338 case 'v': /* double/even */
339 case 'V': /* quad/multiple of 4 */
340 fregx (X_RS1 (insn));
341 break;
342
343 case 'f':
344 freg (X_RS2 (insn));
345 break;
346 case 'B': /* double/even */
347 case 'R': /* quad/multiple of 4 */
348 fregx (X_RS2 (insn));
349 break;
350
351 case 'g':
352 freg (X_RD (insn));
353 break;
354 case 'H': /* double/even */
355 case 'J': /* quad/multiple of 4 */
356 fregx (X_RD (insn));
357 break;
358 #undef freg
359 #undef fregx
360
361 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
362 case 'b':
363 creg (X_RS1 (insn));
364 break;
365
366 case 'c':
367 creg (X_RS2 (insn));
368 break;
369
370 case 'D':
371 creg (X_RD (insn));
372 break;
373 #undef creg
374
375 case 'h':
376 (*info->fprintf_func) (stream, "%%hi(%#x)",
377 (0xFFFFFFFF
378 & ((int) X_IMM22 (insn) << 10)));
379 break;
380
381 case 'i':
382 {
383 int imm = SEX (X_IMM13 (insn), 13);
384
385 /* Check to see whether we have a 1+i, and take
386 note of that fact.
387
388 Note: because of the way we sort the table,
389 we will be matching 1+i rather than i+1,
390 so it is OK to assume that i is after +,
391 not before it. */
392 if (found_plus)
393 imm_added_to_rs1 = 1;
394
395 if (imm <= 9)
396 (*info->fprintf_func) (stream, "%d", imm);
397 else
398 (*info->fprintf_func) (stream, "%#x", imm);
399 }
400 break;
401
402 #ifndef NO_V9
403 case 'I': /* 11 bit immediate. */
404 case 'j': /* 10 bit immediate. */
405 {
406 int imm;
407
408 if (*s == 'I')
409 imm = SEX (X_IMM13 (insn), 11);
410 else
411 imm = SEX (X_IMM13 (insn), 10);
412
413 /* Check to see whether we have a 1+i, and take
414 note of that fact.
415
416 Note: because of the way we sort the table,
417 we will be matching 1+i rather than i+1,
418 so it is OK to assume that i is after +,
419 not before it. */
420 if (found_plus)
421 imm_added_to_rs1 = 1;
422
423 if (imm <= 9)
424 (info->fprintf_func) (stream, "%d", imm);
425 else
426 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
427 }
428 break;
429
430 case 'k':
431 info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4;
432 (*info->print_address_func) (info->target, info);
433 break;
434
435 case 'G':
436 info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4;
437 (*info->print_address_func) (info->target, info);
438 break;
439
440 case '6':
441 case '7':
442 case '8':
443 case '9':
444 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
445 break;
446
447 case 'z':
448 (*info->fprintf_func) (stream, "%%icc");
449 break;
450
451 case 'Z':
452 (*info->fprintf_func) (stream, "%%xcc");
453 break;
454
455 case 'E':
456 (*info->fprintf_func) (stream, "%%ccr");
457 break;
458
459 case 's':
460 (*info->fprintf_func) (stream, "%%fprs");
461 break;
462
463 case 'o':
464 (*info->fprintf_func) (stream, "%%asi");
465 break;
466
467 case 'W':
468 (*info->fprintf_func) (stream, "%%tick");
469 break;
470
471 case 'P':
472 (*info->fprintf_func) (stream, "%%pc");
473 break;
474
475 case '?':
476 if (X_RS1 (insn) == 31)
477 (*info->fprintf_func) (stream, "%%ver");
478 else if ((unsigned) X_RS1 (insn) < 16)
479 (*info->fprintf_func) (stream, "%%%s",
480 v9_priv_reg_names[X_RS1 (insn)]);
481 else
482 (*info->fprintf_func) (stream, "%%reserved");
483 break;
484
485 case '!':
486 if ((unsigned) X_RD (insn) < 15)
487 (*info->fprintf_func) (stream, "%%%s",
488 v9_priv_reg_names[X_RD (insn)]);
489 else
490 (*info->fprintf_func) (stream, "%%reserved");
491 break;
492 break;
493 #endif /* NO_V9 */
494
495 case 'M':
496 (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
497 break;
498
499 case 'm':
500 (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
501 break;
502
503 case 'L':
504 info->target = memaddr + X_DISP30 (insn) * 4;
505 (*info->print_address_func) (info->target, info);
506 break;
507
508 case 'n':
509 (*info->fprintf_func)
510 (stream, "%#x", (SEX (X_DISP22 (insn), 22)));
511 break;
512
513 case 'l':
514 info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4;
515 (*info->print_address_func) (info->target, info);
516 break;
517
518 case 'A':
519 {
520 char *name = sparc_decode_asi (X_ASI (insn));
521
522 if (name)
523 (*info->fprintf_func) (stream, "%s", name);
524 else
525 (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
526 break;
527 }
528
529 case 'C':
530 (*info->fprintf_func) (stream, "%%csr");
531 break;
532
533 case 'F':
534 (*info->fprintf_func) (stream, "%%fsr");
535 break;
536
537 case 'p':
538 (*info->fprintf_func) (stream, "%%psr");
539 break;
540
541 case 'q':
542 (*info->fprintf_func) (stream, "%%fq");
543 break;
544
545 case 'Q':
546 (*info->fprintf_func) (stream, "%%cq");
547 break;
548
549 case 't':
550 (*info->fprintf_func) (stream, "%%tbr");
551 break;
552
553 case 'w':
554 (*info->fprintf_func) (stream, "%%wim");
555 break;
556
557 case 'x':
558 (*info->fprintf_func) (stream, "%d",
559 ((X_LDST_I (insn) << 8)
560 + X_ASI (insn)));
561 break;
562
563 case 'y':
564 (*info->fprintf_func) (stream, "%%y");
565 break;
566 }
567 }
568 }
569
570 /* If we are adding or or'ing something to rs1, then
571 check to see whether the previous instruction was
572 a sethi to the same register as in the sethi.
573 If so, attempt to print the result of the add or
574 or (in this context add and or do the same thing)
575 and its symbolic value. */
576 if (imm_added_to_rs1)
577 {
578 unsigned long prev_insn;
579 int errcode;
580
581 errcode =
582 (*info->read_memory_func)
583 (memaddr - 4, buffer, sizeof (buffer), info);
584 prev_insn = bfd_getb32 (buffer);
585
586 if (errcode == 0)
587 {
588 /* If it is a delayed branch, we need to look at the
589 instruction before the delayed branch. This handles
590 sequences such as
591
592 sethi %o1, %hi(_foo), %o1
593 call _printf
594 or %o1, %lo(_foo), %o1
595 */
596
597 if (is_delayed_branch (prev_insn))
598 {
599 errcode = (*info->read_memory_func)
600 (memaddr - 8, buffer, sizeof (buffer), info);
601 prev_insn = bfd_getb32 (buffer);
602 }
603 }
604
605 /* If there was a problem reading memory, then assume
606 the previous instruction was not sethi. */
607 if (errcode == 0)
608 {
609 /* Is it sethi to the same register? */
610 if ((prev_insn & 0xc1c00000) == 0x01000000
611 && X_RD (prev_insn) == X_RS1 (insn))
612 {
613 (*info->fprintf_func) (stream, "\t! ");
614 info->target =
615 (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
616 | SEX (X_IMM13 (insn), 13);
617 (*info->print_address_func) (info->target, info);
618 info->insn_type = dis_dref;
619 info->data_size = 4; /* FIXME!!! */
620 }
621 }
622 }
623
624 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
625 {
626 /* FIXME -- check is_annulled flag */
627 if (opcode->flags & F_UNBR)
628 info->insn_type = dis_branch;
629 if (opcode->flags & F_CONDBR)
630 info->insn_type = dis_condbranch;
631 if (opcode->flags & F_JSR)
632 info->insn_type = dis_jsr;
633 if (opcode->flags & F_DELAYED)
634 info->branch_delay_insns = 1;
635 }
636
637 return sizeof (buffer);
638 }
639 }
640
641 info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
642 (*info->fprintf_func) (stream, "%#8x", insn);
643 return sizeof (buffer);
644 }
645
646 /* Compare opcodes A and B. */
647
648 static int
649 compare_opcodes (a, b)
650 char *a, *b;
651 {
652 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
653 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
654 unsigned long int match0 = op0->match, match1 = op1->match;
655 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
656 register unsigned int i;
657
658 /* If a bit is set in both match and lose, there is something
659 wrong with the opcode table. */
660 if (match0 & lose0)
661 {
662 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
663 op0->name, match0, lose0);
664 op0->lose &= ~op0->match;
665 lose0 = op0->lose;
666 }
667
668 if (match1 & lose1)
669 {
670 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
671 op1->name, match1, lose1);
672 op1->lose &= ~op1->match;
673 lose1 = op1->lose;
674 }
675
676 /* Because the bits that are variable in one opcode are constant in
677 another, it is important to order the opcodes in the right order. */
678 for (i = 0; i < 32; ++i)
679 {
680 unsigned long int x = 1 << i;
681 int x0 = (match0 & x) != 0;
682 int x1 = (match1 & x) != 0;
683
684 if (x0 != x1)
685 return x1 - x0;
686 }
687
688 for (i = 0; i < 32; ++i)
689 {
690 unsigned long int x = 1 << i;
691 int x0 = (lose0 & x) != 0;
692 int x1 = (lose1 & x) != 0;
693
694 if (x0 != x1)
695 return x1 - x0;
696 }
697
698 /* Put non-sparc64 insns ahead of sparc64 ones. */
699 if ((op0->architecture == v9) != (op1->architecture == v9))
700 return (op0->architecture == v9) - (op1->architecture == v9);
701
702 /* They are functionally equal. So as long as the opcode table is
703 valid, we can put whichever one first we want, on aesthetic grounds. */
704
705 /* Our first aesthetic ground is that aliases defer to real insns. */
706 {
707 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
708 if (alias_diff != 0)
709 /* Put the one that isn't an alias first. */
710 return alias_diff;
711 }
712
713 /* Except for aliases, two "identical" instructions had
714 better have the same opcode. This is a sanity check on the table. */
715 i = strcmp (op0->name, op1->name);
716 if (i)
717 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
718 return i;
719 else
720 fprintf (stderr,
721 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
722 op0->name, op1->name);
723
724 /* Fewer arguments are preferred. */
725 {
726 int length_diff = strlen (op0->args) - strlen (op1->args);
727 if (length_diff != 0)
728 /* Put the one with fewer arguments first. */
729 return length_diff;
730 }
731
732 /* Put 1+i before i+1. */
733 {
734 char *p0 = (char *) strchr(op0->args, '+');
735 char *p1 = (char *) strchr(op1->args, '+');
736
737 if (p0 && p1)
738 {
739 /* There is a plus in both operands. Note that a plus
740 sign cannot be the first character in args,
741 so the following [-1]'s are valid. */
742 if (p0[-1] == 'i' && p1[1] == 'i')
743 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
744 return 1;
745 if (p0[1] == 'i' && p1[-1] == 'i')
746 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
747 return -1;
748 }
749 }
750
751 /* Put 1,i before i,1. */
752 {
753 int i0 = strncmp (op0->args, "i,1", 3) == 0;
754 int i1 = strncmp (op1->args, "i,1", 3) == 0;
755
756 if (i0 ^ i1)
757 return i0 - i1;
758 }
759
760 /* They are, as far as we can tell, identical.
761 Since qsort may have rearranged the table partially, there is
762 no way to tell which one was first in the opcode table as
763 written, so just say there are equal. */
764 return 0;
765 }
766
767 /* Build a hash table from the opcode table. */
768
769 static void
770 build_hash_table (table, hash_table, num_opcodes)
771 struct sparc_opcode *table;
772 struct opcode_hash **hash_table;
773 int num_opcodes;
774 {
775 register int i;
776 int hash_count[HASH_SIZE];
777 static struct opcode_hash *hash_buf = NULL;
778
779 /* Start at the end of the table and work backwards so that each
780 chain is sorted. */
781
782 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
783 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
784 if (hash_buf != NULL)
785 free (hash_buf);
786 hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
787 for (i = num_opcodes - 1; i >= 0; --i)
788 {
789 register int hash = HASH_INSN (sparc_opcodes[i].match);
790 register struct opcode_hash *h = &hash_buf[i];
791 h->next = hash_table[hash];
792 h->opcode = &sparc_opcodes[i];
793 hash_table[hash] = h;
794 ++hash_count[hash];
795 }
796
797 #if 0 /* for debugging */
798 {
799 int min_count = num_opcodes, max_count = 0;
800 int total;
801
802 for (i = 0; i < HASH_SIZE; ++i)
803 {
804 if (hash_count[i] < min_count)
805 min_count = hash_count[i];
806 if (hash_count[i] > max_count)
807 max_count = hash_count[i];
808 total += hash_count[i];
809 }
810
811 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
812 min_count, max_count, (double) total / HASH_SIZE);
813 }
814 #endif
815 }
816
817 int
818 print_insn_sparc (memaddr, info)
819 bfd_vma memaddr;
820 disassemble_info *info;
821 {
822 return print_insn (memaddr, info, 0);
823 }
824
825 int
826 print_insn_sparc64 (memaddr, info)
827 bfd_vma memaddr;
828 disassemble_info *info;
829 {
830 return print_insn (memaddr, info, 1);
831 }
This page took 0.048182 seconds and 4 git commands to generate.