* sparc-dis.c (HASH_SIZE, HASH_INSN): Define.
[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 /* Nonzero of the current architecture is sparc64.
179 This is kept in a global because compare_opcodes uses it. */
180 static int sparc64_p;
181
182 /* extern void qsort (); */
183 static int compare_opcodes ();
184
185 /* Print one instruction from MEMADDR on INFO->STREAM.
186
187 We suffix the instruction with a comment that gives the absolute
188 address involved, as well as its symbolic form, if the instruction
189 is preceded by a findable `sethi' and it either adds an immediate
190 displacement to that register, or it is an `add' or `or' instruction
191 on that register. */
192
193 static int
194 print_insn (memaddr, info)
195 bfd_vma memaddr;
196 disassemble_info *info;
197 {
198 FILE *stream = info->stream;
199 bfd_byte buffer[4];
200 unsigned long insn;
201 register unsigned int i;
202 register struct opcode_hash *op;
203
204 if (!opcodes_initialized)
205 {
206 qsort ((char *) sparc_opcodes, NUMOPCODES,
207 sizeof (sparc_opcodes[0]), compare_opcodes);
208 build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES);
209 opcodes_initialized = 1;
210 }
211
212 {
213 int status =
214 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
215 if (status != 0)
216 {
217 (*info->memory_error_func) (status, memaddr, info);
218 return -1;
219 }
220 }
221
222 insn = bfd_getb32 (buffer);
223
224 info->insn_info_valid = 1; /* We do return this info */
225 info->insn_type = dis_nonbranch; /* Assume non branch insn */
226 info->branch_delay_insns = 0; /* Assume no delay */
227 info->target = 0; /* Assume no target known */
228
229 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
230 {
231 CONST struct sparc_opcode *opcode = op->opcode;
232
233 if ((opcode->match & insn) == opcode->match
234 && (opcode->lose & insn) == 0)
235 {
236 /* Nonzero means that we have found an instruction which has
237 the effect of adding or or'ing the imm13 field to rs1. */
238 int imm_added_to_rs1 = 0;
239
240 /* Nonzero means that we have found a plus sign in the args
241 field of the opcode table. */
242 int found_plus = 0;
243
244 /* Nonzero means we have an annulled branch. */
245 int is_annulled = 0;
246
247 /* Do we have an `add' or `or' instruction where rs1 is the same
248 as rsd, and which has the i bit set? */
249 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
250 /* (or) (add) */
251 && X_RS1 (insn) == X_RD (insn))
252 imm_added_to_rs1 = 1;
253
254 if (X_RS1 (insn) != X_RD (insn)
255 && strchr (opcode->args, 'r') != 0)
256 /* Can't do simple format if source and dest are different. */
257 continue;
258
259 (*info->fprintf_func) (stream, opcode->name);
260
261 {
262 register CONST char *s;
263
264 if (opcode->args[0] != ',')
265 (*info->fprintf_func) (stream, " ");
266 for (s = opcode->args; *s != '\0'; ++s)
267 {
268 while (*s == ',')
269 {
270 (*info->fprintf_func) (stream, ",");
271 ++s;
272 switch (*s) {
273 case 'a':
274 (*info->fprintf_func) (stream, "a");
275 is_annulled = 1;
276 ++s;
277 continue;
278 #ifndef NO_V9
279 case 'N':
280 (*info->fprintf_func) (stream, "pn");
281 ++s;
282 continue;
283
284 case 'T':
285 (*info->fprintf_func) (stream, "pt");
286 ++s;
287 continue;
288 #endif /* NO_V9 */
289
290 default:
291 break;
292 } /* switch on arg */
293 } /* while there are comma started args */
294
295 (*info->fprintf_func) (stream, " ");
296
297 switch (*s)
298 {
299 case '+':
300 found_plus = 1;
301
302 /* note fall-through */
303 default:
304 (*info->fprintf_func) (stream, "%c", *s);
305 break;
306
307 case '#':
308 (*info->fprintf_func) (stream, "0");
309 break;
310
311 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
312 case '1':
313 case 'r':
314 reg (X_RS1 (insn));
315 break;
316
317 case '2':
318 reg (X_RS2 (insn));
319 break;
320
321 case 'd':
322 reg (X_RD (insn));
323 break;
324 #undef reg
325
326 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
327 #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
328 case 'e':
329 freg (X_RS1 (insn));
330 break;
331 case 'v': /* double/even */
332 case 'V': /* quad/multiple of 4 */
333 fregx (X_RS1 (insn));
334 break;
335
336 case 'f':
337 freg (X_RS2 (insn));
338 break;
339 case 'B': /* double/even */
340 case 'R': /* quad/multiple of 4 */
341 fregx (X_RS2 (insn));
342 break;
343
344 case 'g':
345 freg (X_RD (insn));
346 break;
347 case 'H': /* double/even */
348 case 'J': /* quad/multiple of 4 */
349 fregx (X_RD (insn));
350 break;
351 #undef freg
352 #undef fregx
353
354 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
355 case 'b':
356 creg (X_RS1 (insn));
357 break;
358
359 case 'c':
360 creg (X_RS2 (insn));
361 break;
362
363 case 'D':
364 creg (X_RD (insn));
365 break;
366 #undef creg
367
368 case 'h':
369 (*info->fprintf_func) (stream, "%%hi(%#x)",
370 (0xFFFFFFFF
371 & ((int) X_IMM22 (insn) << 10)));
372 break;
373
374 case 'i':
375 {
376 int imm = SEX (X_IMM13 (insn), 13);
377
378 /* Check to see whether we have a 1+i, and take
379 note of that fact.
380
381 Note: because of the way we sort the table,
382 we will be matching 1+i rather than i+1,
383 so it is OK to assume that i is after +,
384 not before it. */
385 if (found_plus)
386 imm_added_to_rs1 = 1;
387
388 if (imm <= 9)
389 (*info->fprintf_func) (stream, "%d", imm);
390 else
391 (*info->fprintf_func) (stream, "%#x", imm);
392 }
393 break;
394
395 #ifndef NO_V9
396 case 'I': /* 11 bit immediate. */
397 case 'j': /* 10 bit immediate. */
398 {
399 int imm;
400
401 if (*s == 'I')
402 imm = SEX (X_IMM13 (insn), 11);
403 else
404 imm = SEX (X_IMM13 (insn), 10);
405
406 /* Check to see whether we have a 1+i, and take
407 note of that fact.
408
409 Note: because of the way we sort the table,
410 we will be matching 1+i rather than i+1,
411 so it is OK to assume that i is after +,
412 not before it. */
413 if (found_plus)
414 imm_added_to_rs1 = 1;
415
416 if (imm <= 9)
417 (info->fprintf_func) (stream, "%d", imm);
418 else
419 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
420 }
421 break;
422
423 case 'k':
424 info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4;
425 (*info->print_address_func) (info->target, info);
426 break;
427
428 case 'G':
429 info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4;
430 (*info->print_address_func) (info->target, info);
431 break;
432
433 case '6':
434 case '7':
435 case '8':
436 case '9':
437 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
438 break;
439
440 case 'z':
441 (*info->fprintf_func) (stream, "%%icc");
442 break;
443
444 case 'Z':
445 (*info->fprintf_func) (stream, "%%xcc");
446 break;
447
448 case 'E':
449 (*info->fprintf_func) (stream, "%%ccr");
450 break;
451
452 case 's':
453 (*info->fprintf_func) (stream, "%%fprs");
454 break;
455
456 case 'o':
457 (*info->fprintf_func) (stream, "%%asi");
458 break;
459
460 case 'W':
461 (*info->fprintf_func) (stream, "%%tick");
462 break;
463
464 case 'P':
465 (*info->fprintf_func) (stream, "%%pc");
466 break;
467
468 case '?':
469 if (X_RS1 (insn) == 31)
470 (*info->fprintf_func) (stream, "%%ver");
471 else if ((unsigned) X_RS1 (insn) < 16)
472 (*info->fprintf_func) (stream, "%%%s",
473 v9_priv_reg_names[X_RS1 (insn)]);
474 else
475 (*info->fprintf_func) (stream, "%%reserved");
476 break;
477
478 case '!':
479 if ((unsigned) X_RD (insn) < 15)
480 (*info->fprintf_func) (stream, "%%%s",
481 v9_priv_reg_names[X_RD (insn)]);
482 else
483 (*info->fprintf_func) (stream, "%%reserved");
484 break;
485 break;
486 #endif /* NO_V9 */
487
488 case 'M':
489 (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
490 break;
491
492 case 'm':
493 (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
494 break;
495
496 case 'L':
497 info->target = memaddr + X_DISP30 (insn) * 4;
498 (*info->print_address_func) (info->target, info);
499 break;
500
501 case 'n':
502 (*info->fprintf_func)
503 (stream, "%#x", (SEX (X_DISP22 (insn), 22)));
504 break;
505
506 case 'l':
507 info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4;
508 (*info->print_address_func) (info->target, info);
509 break;
510
511 case 'A':
512 (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
513 break;
514
515 case 'C':
516 (*info->fprintf_func) (stream, "%%csr");
517 break;
518
519 case 'F':
520 (*info->fprintf_func) (stream, "%%fsr");
521 break;
522
523 case 'p':
524 (*info->fprintf_func) (stream, "%%psr");
525 break;
526
527 case 'q':
528 (*info->fprintf_func) (stream, "%%fq");
529 break;
530
531 case 'Q':
532 (*info->fprintf_func) (stream, "%%cq");
533 break;
534
535 case 't':
536 (*info->fprintf_func) (stream, "%%tbr");
537 break;
538
539 case 'w':
540 (*info->fprintf_func) (stream, "%%wim");
541 break;
542
543 case 'x':
544 (*info->fprintf_func) (stream, "%d",
545 ((X_LDST_I (insn) << 8)
546 + X_ASI (insn)));
547 break;
548
549 case 'y':
550 (*info->fprintf_func) (stream, "%%y");
551 break;
552 }
553 }
554 }
555
556 /* If we are adding or or'ing something to rs1, then
557 check to see whether the previous instruction was
558 a sethi to the same register as in the sethi.
559 If so, attempt to print the result of the add or
560 or (in this context add and or do the same thing)
561 and its symbolic value. */
562 if (imm_added_to_rs1)
563 {
564 unsigned long prev_insn;
565 int errcode;
566
567 errcode =
568 (*info->read_memory_func)
569 (memaddr - 4, buffer, sizeof (buffer), info);
570 prev_insn = bfd_getb32 (buffer);
571
572 if (errcode == 0)
573 {
574 /* If it is a delayed branch, we need to look at the
575 instruction before the delayed branch. This handles
576 sequences such as
577
578 sethi %o1, %hi(_foo), %o1
579 call _printf
580 or %o1, %lo(_foo), %o1
581 */
582
583 if (is_delayed_branch (prev_insn))
584 {
585 errcode = (*info->read_memory_func)
586 (memaddr - 8, buffer, sizeof (buffer), info);
587 prev_insn = bfd_getb32 (buffer);
588 }
589 }
590
591 /* If there was a problem reading memory, then assume
592 the previous instruction was not sethi. */
593 if (errcode == 0)
594 {
595 /* Is it sethi to the same register? */
596 if ((prev_insn & 0xc1c00000) == 0x01000000
597 && X_RD (prev_insn) == X_RS1 (insn))
598 {
599 (*info->fprintf_func) (stream, "\t! ");
600 info->target =
601 (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
602 | SEX (X_IMM13 (insn), 13);
603 (*info->print_address_func) (info->target, info);
604 info->insn_type = dis_dref;
605 info->data_size = 4; /* FIXME!!! */
606 }
607 }
608 }
609
610 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
611 {
612 /* FIXME -- check is_annulled flag */
613 if (opcode->flags & F_UNBR)
614 info->insn_type = dis_branch;
615 if (opcode->flags & F_CONDBR)
616 info->insn_type = dis_condbranch;
617 if (opcode->flags & F_JSR)
618 info->insn_type = dis_jsr;
619 if (opcode->flags & F_DELAYED)
620 info->branch_delay_insns = 1;
621 }
622
623 return sizeof (buffer);
624 }
625 }
626
627 info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
628 (*info->fprintf_func) (stream, "%#8x", insn);
629 return sizeof (buffer);
630 }
631
632 /* Compare opcodes A and B. */
633
634 static int
635 compare_opcodes (a, b)
636 char *a, *b;
637 {
638 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
639 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
640 unsigned long int match0 = op0->match, match1 = op1->match;
641 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
642 register unsigned int i;
643
644 /* If a bit is set in both match and lose, there is something
645 wrong with the opcode table. */
646 if (match0 & lose0)
647 {
648 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
649 op0->name, match0, lose0);
650 op0->lose &= ~op0->match;
651 lose0 = op0->lose;
652 }
653
654 if (match1 & lose1)
655 {
656 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
657 op1->name, match1, lose1);
658 op1->lose &= ~op1->match;
659 lose1 = op1->lose;
660 }
661
662 /* If the current architecture isn't sparc64, move v9 insns to the end.
663 Only do this when one isn't v9 and one is. If both are v9 we still
664 need to properly sort them.
665 This must be done before checking match and lose. */
666 if (!sparc64_p
667 && (op0->architecture == v9) != (op1->architecture == v9))
668 return (op0->architecture == v9) - (op1->architecture == v9);
669
670 /* If the current architecture is sparc64, move non-v9 insns to the end.
671 This must be done before checking match and lose. */
672 if (sparc64_p
673 && (op0->flags & F_NOTV9) != (op1->flags & F_NOTV9))
674 return (op0->flags & F_NOTV9) - (op1->flags & F_NOTV9);
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 /* They are functionally equal. So as long as the opcode table is
699 valid, we can put whichever one first we want, on aesthetic grounds. */
700
701 /* Our first aesthetic ground is that aliases defer to real insns. */
702 {
703 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
704 if (alias_diff != 0)
705 /* Put the one that isn't an alias first. */
706 return alias_diff;
707 }
708
709 /* Except for aliases, two "identical" instructions had
710 better have the same opcode. This is a sanity check on the table. */
711 i = strcmp (op0->name, op1->name);
712 if (i)
713 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
714 return i;
715 else
716 fprintf (stderr,
717 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
718 op0->name, op1->name);
719
720 /* Fewer arguments are preferred. */
721 {
722 int length_diff = strlen (op0->args) - strlen (op1->args);
723 if (length_diff != 0)
724 /* Put the one with fewer arguments first. */
725 return length_diff;
726 }
727
728 /* Put 1+i before i+1. */
729 {
730 char *p0 = (char *) strchr(op0->args, '+');
731 char *p1 = (char *) strchr(op1->args, '+');
732
733 if (p0 && p1)
734 {
735 /* There is a plus in both operands. Note that a plus
736 sign cannot be the first character in args,
737 so the following [-1]'s are valid. */
738 if (p0[-1] == 'i' && p1[1] == 'i')
739 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
740 return 1;
741 if (p0[1] == 'i' && p1[-1] == 'i')
742 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
743 return -1;
744 }
745 }
746
747 /* They are, as far as we can tell, identical.
748 Since qsort may have rearranged the table partially, there is
749 no way to tell which one was first in the opcode table as
750 written, so just say there are equal. */
751 return 0;
752 }
753
754 /* Build a hash table from the opcode table. */
755
756 static void
757 build_hash_table (table, hash_table, num_opcodes)
758 struct sparc_opcode *table;
759 struct opcode_hash **hash_table;
760 int num_opcodes;
761 {
762 int i;
763 int hash_count[HASH_SIZE];
764
765 /* Start at the end of the table and work backwards so that each
766 chain is sorted. */
767 /* ??? Do we really need to sort them now? */
768
769 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
770 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
771 for (i = num_opcodes - 1; i >= 0; --i)
772 {
773 int hash = HASH_INSN (sparc_opcodes[i].match);
774 struct opcode_hash *h = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash));
775 h->next = hash_table[hash];
776 h->opcode = &sparc_opcodes[i];
777 hash_table[hash] = h;
778 ++hash_count[hash];
779 }
780
781 #if 0 /* for debugging */
782 {
783 int min_count = num_opcodes, max_count = 0;
784 int total;
785
786 for (i = 0; i < HASH_SIZE; ++i)
787 {
788 if (hash_count[i] < min_count)
789 min_count = hash_count[i];
790 if (hash_count[i] > max_count)
791 max_count = hash_count[i];
792 total += hash_count[i];
793 }
794
795 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
796 min_count, max_count, (double) total / HASH_SIZE);
797 }
798 #endif
799 }
800
801 int
802 print_insn_sparc (memaddr, info)
803 bfd_vma memaddr;
804 disassemble_info *info;
805 {
806 /* It's not clear that we'll ever switch cpus in a running program.
807 It could theoretically happen in gdb so we handle it.
808 ??? There is currently a memory leak but it's not worth the trouble. */
809 if (sparc64_p)
810 opcodes_initialized = 0;
811 sparc64_p = 0;
812 return print_insn (memaddr, info);
813 }
814
815 int
816 print_insn_sparc64 (memaddr, info)
817 bfd_vma memaddr;
818 disassemble_info *info;
819 {
820 /* It's not clear that we'll ever switch cpus in a running program.
821 It could theoretically happen in gdb so we handle it.
822 ??? There is currently a memory leak but it's not worth the trouble. */
823 if (!sparc64_p)
824 opcodes_initialized = 0;
825 sparc64_p = 1;
826 return print_insn (memaddr, info);
827 }
This page took 0.063133 seconds and 5 git commands to generate.