1 /* Print SPARC instructions.
2 Copyright (C) 1989, 91-93, 1995, 1996 Free Software Foundation, Inc.
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.
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.
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. */
19 #include "opcode/sparc.h"
21 #include "libiberty.h"
24 /* Bitmask of v9 architectures. */
25 #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
26 | (1 << SPARC_OPCODE_ARCH_V9A))
27 /* 1 if INSN is for v9 only. */
28 #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
29 /* 1 if INSN is for v9. */
30 #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
32 /* For faster lookup, after insns are sorted they are hashed. */
33 /* ??? I think there is room for even more improvement. */
36 /* It is important that we only look at insn code bits as that is how the
37 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
38 of the main types (0,1,2,3). */
39 static int opcode_bits
[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
40 #define HASH_INSN(INSN) \
41 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
43 struct opcode_hash
*next
;
44 struct sparc_opcode
*opcode
;
46 static struct opcode_hash
*opcode_hash_table
[HASH_SIZE
];
47 static void build_hash_table ();
49 /* Sign-extend a value which is N bits long. */
50 #define SEX(value, bits) \
51 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
52 >> ((8 * sizeof (int)) - bits) )
54 static char *reg_names
[] =
55 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
56 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
57 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
58 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
59 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
60 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
61 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
62 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
63 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
64 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
65 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
66 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
67 /* psr, wim, tbr, fpsr, cpsr are v8 only. */
68 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
71 #define freg_names (®_names[4 * 8])
73 /* These are ordered according to there register number in
74 rdpr and wrpr insns. */
75 static char *v9_priv_reg_names
[] =
77 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
78 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
80 /* "ver" - special cased */
83 /* Macros used to extract instruction fields. Not all fields have
84 macros defined here, only those which are actually used. */
86 #define X_RD(i) (((i) >> 25) & 0x1f)
87 #define X_RS1(i) (((i) >> 14) & 0x1f)
88 #define X_LDST_I(i) (((i) >> 13) & 1)
89 #define X_ASI(i) (((i) >> 5) & 0xff)
90 #define X_RS2(i) (((i) >> 0) & 0x1f)
91 #define X_IMM13(i) (((i) >> 0) & 0x1fff)
92 #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
93 #define X_IMM22(i) X_DISP22 (i)
94 #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
96 /* These are for v9. */
97 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
98 #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
99 #define X_MEMBAR(i) ((i) & 0x7f)
101 /* Here is the union which was used to extract instruction fields
102 before the shift and mask macros were written.
106 unsigned long int code;
114 unsigned int anrs1:5;
115 #define rs1 ldst.anrs1
117 unsigned int anasi:8;
118 #define asi ldst.anasi
119 unsigned int anrs2:5;
120 #define rs2 ldst.anrs2
125 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
126 unsigned int IMM13:13;
127 #define imm13 IMM13.IMM13
135 unsigned int DISP22:22;
136 #define disp22 branch.DISP22
144 unsigned int rcond:3;
146 unsigned int DISP16HI:2;
149 unsigned int DISP16LO:14;
154 unsigned int adisp30:30;
155 #define disp30 call.adisp30
161 /* Nonzero if INSN is the opcode for a delayed branch. */
163 is_delayed_branch (insn
)
166 struct opcode_hash
*op
;
168 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
170 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
171 if ((opcode
->match
& insn
) == opcode
->match
172 && (opcode
->lose
& insn
) == 0)
173 return (opcode
->flags
& F_DELAYED
);
178 /* extern void qsort (); */
179 static int compare_opcodes ();
181 /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
182 to compare_opcodes. */
183 static unsigned int current_arch_mask
;
184 static int compute_arch_mask ();
186 /* Print one instruction from MEMADDR on INFO->STREAM.
188 We suffix the instruction with a comment that gives the absolute
189 address involved, as well as its symbolic form, if the instruction
190 is preceded by a findable `sethi' and it either adds an immediate
191 displacement to that register, or it is an `add' or `or' instruction
195 print_insn_sparc (memaddr
, info
)
197 disassemble_info
*info
;
199 FILE *stream
= info
->stream
;
202 register unsigned int i
;
203 register struct opcode_hash
*op
;
204 /* Nonzero of opcode table has been initialized. */
205 static int opcodes_initialized
= 0;
206 /* bfd mach number of last call. */
207 static unsigned long current_mach
= 0;
209 if (!opcodes_initialized
210 || info
->mach
!= current_mach
)
212 current_arch_mask
= compute_arch_mask (info
->mach
);
213 qsort ((char *) sparc_opcodes
, sparc_num_opcodes
,
214 sizeof (sparc_opcodes
[0]), compare_opcodes
);
215 build_hash_table (sparc_opcodes
, opcode_hash_table
, sparc_num_opcodes
);
216 current_mach
= info
->mach
;
217 opcodes_initialized
= 1;
222 (*info
->read_memory_func
) (memaddr
, buffer
, sizeof (buffer
), info
);
225 (*info
->memory_error_func
) (status
, memaddr
, info
);
230 insn
= bfd_getb32 (buffer
);
232 info
->insn_info_valid
= 1; /* We do return this info */
233 info
->insn_type
= dis_nonbranch
; /* Assume non branch insn */
234 info
->branch_delay_insns
= 0; /* Assume no delay */
235 info
->target
= 0; /* Assume no target known */
237 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
239 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
241 /* If the insn isn't supported by the current architecture, skip it. */
242 if (! (opcode
->architecture
& current_arch_mask
))
245 if ((opcode
->match
& insn
) == opcode
->match
246 && (opcode
->lose
& insn
) == 0)
248 /* Nonzero means that we have found an instruction which has
249 the effect of adding or or'ing the imm13 field to rs1. */
250 int imm_added_to_rs1
= 0;
252 /* Nonzero means that we have found a plus sign in the args
253 field of the opcode table. */
256 /* Nonzero means we have an annulled branch. */
259 /* Do we have an `add' or `or' instruction where rs1 is the same
260 as rsd, and which has the i bit set? */
261 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
263 && X_RS1 (insn
) == X_RD (insn
))
264 imm_added_to_rs1
= 1;
266 if (X_RS1 (insn
) != X_RD (insn
)
267 && strchr (opcode
->args
, 'r') != 0)
268 /* Can't do simple format if source and dest are different. */
270 if (X_RS2 (insn
) != X_RD (insn
)
271 && strchr (opcode
->args
, 'O') != 0)
272 /* Can't do simple format if source and dest are different. */
275 (*info
->fprintf_func
) (stream
, opcode
->name
);
278 register CONST
char *s
;
280 if (opcode
->args
[0] != ',')
281 (*info
->fprintf_func
) (stream
, " ");
282 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
286 (*info
->fprintf_func
) (stream
, ",");
290 (*info
->fprintf_func
) (stream
, "a");
295 (*info
->fprintf_func
) (stream
, "pn");
300 (*info
->fprintf_func
) (stream
, "pt");
306 } /* switch on arg */
307 } /* while there are comma started args */
309 (*info
->fprintf_func
) (stream
, " ");
316 /* note fall-through */
318 (*info
->fprintf_func
) (stream
, "%c", *s
);
322 (*info
->fprintf_func
) (stream
, "0");
325 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
341 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
342 #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
346 case 'v': /* double/even */
347 case 'V': /* quad/multiple of 4 */
348 fregx (X_RS1 (insn
));
354 case 'B': /* double/even */
355 case 'R': /* quad/multiple of 4 */
356 fregx (X_RS2 (insn
));
362 case 'H': /* double/even */
363 case 'J': /* quad/multiple of 4 */
369 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
384 (*info
->fprintf_func
) (stream
, "%%hi(%#x)",
386 & ((int) X_IMM22 (insn
) << 10)));
391 int imm
= SEX (X_IMM13 (insn
), 13);
393 /* Check to see whether we have a 1+i, and take
396 Note: because of the way we sort the table,
397 we will be matching 1+i rather than i+1,
398 so it is OK to assume that i is after +,
401 imm_added_to_rs1
= 1;
404 (*info
->fprintf_func
) (stream
, "%d", imm
);
406 (*info
->fprintf_func
) (stream
, "%#x", imm
);
410 case 'I': /* 11 bit immediate. */
411 case 'j': /* 10 bit immediate. */
416 imm
= SEX (X_IMM13 (insn
), 11);
418 imm
= SEX (X_IMM13 (insn
), 10);
420 /* Check to see whether we have a 1+i, and take
423 Note: because of the way we sort the table,
424 we will be matching 1+i rather than i+1,
425 so it is OK to assume that i is after +,
428 imm_added_to_rs1
= 1;
431 (info
->fprintf_func
) (stream
, "%d", imm
);
433 (info
->fprintf_func
) (stream
, "%#x", (unsigned) imm
);
439 int mask
= X_MEMBAR (insn
);
440 int bit
= 0x40, printed_one
= 0;
444 (info
->fprintf_func
) (stream
, "0");
451 (info
->fprintf_func
) (stream
, "|");
452 name
= sparc_decode_membar (bit
);
453 (info
->fprintf_func
) (stream
, "%s", name
);
462 info
->target
= memaddr
+ SEX (X_DISP16 (insn
), 16) * 4;
463 (*info
->print_address_func
) (info
->target
, info
);
467 info
->target
= memaddr
+ SEX (X_DISP19 (insn
), 19) * 4;
468 (*info
->print_address_func
) (info
->target
, info
);
475 (*info
->fprintf_func
) (stream
, "%%fcc%c", *s
- '6' + '0');
479 (*info
->fprintf_func
) (stream
, "%%icc");
483 (*info
->fprintf_func
) (stream
, "%%xcc");
487 (*info
->fprintf_func
) (stream
, "%%ccr");
491 (*info
->fprintf_func
) (stream
, "%%fprs");
495 (*info
->fprintf_func
) (stream
, "%%asi");
499 (*info
->fprintf_func
) (stream
, "%%tick");
503 (*info
->fprintf_func
) (stream
, "%%pc");
507 if (X_RS1 (insn
) == 31)
508 (*info
->fprintf_func
) (stream
, "%%ver");
509 else if ((unsigned) X_RS1 (insn
) < 16)
510 (*info
->fprintf_func
) (stream
, "%%%s",
511 v9_priv_reg_names
[X_RS1 (insn
)]);
513 (*info
->fprintf_func
) (stream
, "%%reserved");
517 if ((unsigned) X_RD (insn
) < 15)
518 (*info
->fprintf_func
) (stream
, "%%%s",
519 v9_priv_reg_names
[X_RD (insn
)]);
521 (*info
->fprintf_func
) (stream
, "%%reserved");
526 char *name
= sparc_decode_prefetch (X_RD (insn
));
529 (*info
->fprintf_func
) (stream
, "%s", name
);
531 (*info
->fprintf_func
) (stream
, "%d", X_RD (insn
));
536 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RS1 (insn
));
540 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RD (insn
));
544 info
->target
= memaddr
+ SEX (X_DISP30 (insn
), 30) * 4;
545 (*info
->print_address_func
) (info
->target
, info
);
549 (*info
->fprintf_func
)
550 (stream
, "%#x", SEX (X_DISP22 (insn
), 22));
554 info
->target
= memaddr
+ SEX (X_DISP22 (insn
), 22) * 4;
555 (*info
->print_address_func
) (info
->target
, info
);
560 char *name
= sparc_decode_asi (X_ASI (insn
));
563 (*info
->fprintf_func
) (stream
, "%s", name
);
565 (*info
->fprintf_func
) (stream
, "(%d)", X_ASI (insn
));
570 (*info
->fprintf_func
) (stream
, "%%csr");
574 (*info
->fprintf_func
) (stream
, "%%fsr");
578 (*info
->fprintf_func
) (stream
, "%%psr");
582 (*info
->fprintf_func
) (stream
, "%%fq");
586 (*info
->fprintf_func
) (stream
, "%%cq");
590 (*info
->fprintf_func
) (stream
, "%%tbr");
594 (*info
->fprintf_func
) (stream
, "%%wim");
598 (*info
->fprintf_func
) (stream
, "%d",
599 ((X_LDST_I (insn
) << 8)
604 (*info
->fprintf_func
) (stream
, "%%y");
610 int val
= *s
== 'U' ? X_RS1 (insn
) : X_RD (insn
);
611 char *name
= sparc_decode_sparclet_cpreg (val
);
614 (*info
->fprintf_func
) (stream
, "%s", name
);
616 (*info
->fprintf_func
) (stream
, "%%cpreg(%d)", val
);
623 /* If we are adding or or'ing something to rs1, then
624 check to see whether the previous instruction was
625 a sethi to the same register as in the sethi.
626 If so, attempt to print the result of the add or
627 or (in this context add and or do the same thing)
628 and its symbolic value. */
629 if (imm_added_to_rs1
)
631 unsigned long prev_insn
;
635 (*info
->read_memory_func
)
636 (memaddr
- 4, buffer
, sizeof (buffer
), info
);
637 prev_insn
= bfd_getb32 (buffer
);
641 /* If it is a delayed branch, we need to look at the
642 instruction before the delayed branch. This handles
645 sethi %o1, %hi(_foo), %o1
647 or %o1, %lo(_foo), %o1
650 if (is_delayed_branch (prev_insn
))
652 errcode
= (*info
->read_memory_func
)
653 (memaddr
- 8, buffer
, sizeof (buffer
), info
);
654 prev_insn
= bfd_getb32 (buffer
);
658 /* If there was a problem reading memory, then assume
659 the previous instruction was not sethi. */
662 /* Is it sethi to the same register? */
663 if ((prev_insn
& 0xc1c00000) == 0x01000000
664 && X_RD (prev_insn
) == X_RS1 (insn
))
666 (*info
->fprintf_func
) (stream
, "\t! ");
668 (0xFFFFFFFF & (int) X_IMM22 (prev_insn
) << 10)
669 | SEX (X_IMM13 (insn
), 13);
670 (*info
->print_address_func
) (info
->target
, info
);
671 info
->insn_type
= dis_dref
;
672 info
->data_size
= 4; /* FIXME!!! */
677 if (opcode
->flags
& (F_UNBR
|F_CONDBR
|F_JSR
))
679 /* FIXME -- check is_annulled flag */
680 if (opcode
->flags
& F_UNBR
)
681 info
->insn_type
= dis_branch
;
682 if (opcode
->flags
& F_CONDBR
)
683 info
->insn_type
= dis_condbranch
;
684 if (opcode
->flags
& F_JSR
)
685 info
->insn_type
= dis_jsr
;
686 if (opcode
->flags
& F_DELAYED
)
687 info
->branch_delay_insns
= 1;
690 return sizeof (buffer
);
694 info
->insn_type
= dis_noninsn
; /* Mark as non-valid instruction */
695 (*info
->fprintf_func
) (stream
, "unknown");
696 return sizeof (buffer
);
699 /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
702 compute_arch_mask (mach
)
708 case bfd_mach_sparc
:
709 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8
);
710 case bfd_mach_sparc_sparclet
:
711 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET
);
712 case bfd_mach_sparc_sparclite
:
713 /* sparclites insns are recognized by default (because that's how
714 they've always been treated, for better or worse). Kludge this by
715 indicating generic v8 is also selected. */
716 return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE
)
717 | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8
));
718 case bfd_mach_sparc_v8plus
:
719 case bfd_mach_sparc_v9
:
720 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9
);
721 case bfd_mach_sparc_v8plusa
:
722 case bfd_mach_sparc_v9a
:
723 return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A
);
728 /* Compare opcodes A and B. */
731 compare_opcodes (a
, b
)
734 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
735 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
736 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
737 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
738 register unsigned int i
;
740 /* If one (and only one) insn isn't supported by the current architecture,
741 prefer the one that is. If neither are supported, but they're both for
742 the same architecture, continue processing. Otherwise (both unsupported
743 and for different architectures), prefer lower numbered arch's (fudged
744 by comparing the bitmasks). */
745 if (op0
->architecture
& current_arch_mask
)
747 if (! (op1
->architecture
& current_arch_mask
))
752 if (op1
->architecture
& current_arch_mask
)
754 else if (op0
->architecture
!= op1
->architecture
)
755 return op0
->architecture
- op1
->architecture
;
758 /* If a bit is set in both match and lose, there is something
759 wrong with the opcode table. */
762 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
763 op0
->name
, match0
, lose0
);
764 op0
->lose
&= ~op0
->match
;
770 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
771 op1
->name
, match1
, lose1
);
772 op1
->lose
&= ~op1
->match
;
776 /* Because the bits that are variable in one opcode are constant in
777 another, it is important to order the opcodes in the right order. */
778 for (i
= 0; i
< 32; ++i
)
780 unsigned long int x
= 1 << i
;
781 int x0
= (match0
& x
) != 0;
782 int x1
= (match1
& x
) != 0;
788 for (i
= 0; i
< 32; ++i
)
790 unsigned long int x
= 1 << i
;
791 int x0
= (lose0
& x
) != 0;
792 int x1
= (lose1
& x
) != 0;
798 /* They are functionally equal. So as long as the opcode table is
799 valid, we can put whichever one first we want, on aesthetic grounds. */
801 /* Our first aesthetic ground is that aliases defer to real insns. */
803 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
805 /* Put the one that isn't an alias first. */
809 /* Except for aliases, two "identical" instructions had
810 better have the same opcode. This is a sanity check on the table. */
811 i
= strcmp (op0
->name
, op1
->name
);
814 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
818 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
819 op0
->name
, op1
->name
);
822 /* Fewer arguments are preferred. */
824 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
825 if (length_diff
!= 0)
826 /* Put the one with fewer arguments first. */
830 /* Put 1+i before i+1. */
832 char *p0
= (char *) strchr(op0
->args
, '+');
833 char *p1
= (char *) strchr(op1
->args
, '+');
837 /* There is a plus in both operands. Note that a plus
838 sign cannot be the first character in args,
839 so the following [-1]'s are valid. */
840 if (p0
[-1] == 'i' && p1
[1] == 'i')
841 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
843 if (p0
[1] == 'i' && p1
[-1] == 'i')
844 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
849 /* Put 1,i before i,1. */
851 int i0
= strncmp (op0
->args
, "i,1", 3) == 0;
852 int i1
= strncmp (op1
->args
, "i,1", 3) == 0;
858 /* They are, as far as we can tell, identical.
859 Since qsort may have rearranged the table partially, there is
860 no way to tell which one was first in the opcode table as
861 written, so just say there are equal. */
865 /* Build a hash table from the opcode table. */
868 build_hash_table (table
, hash_table
, num_opcodes
)
869 struct sparc_opcode
*table
;
870 struct opcode_hash
**hash_table
;
874 int hash_count
[HASH_SIZE
];
875 static struct opcode_hash
*hash_buf
= NULL
;
877 /* Start at the end of the table and work backwards so that each
880 memset (hash_table
, 0, HASH_SIZE
* sizeof (hash_table
[0]));
881 memset (hash_count
, 0, HASH_SIZE
* sizeof (hash_count
[0]));
882 if (hash_buf
!= NULL
)
884 hash_buf
= (struct opcode_hash
*) xmalloc (sizeof (struct opcode_hash
) * num_opcodes
);
885 for (i
= num_opcodes
- 1; i
>= 0; --i
)
887 register int hash
= HASH_INSN (sparc_opcodes
[i
].match
);
888 register struct opcode_hash
*h
= &hash_buf
[i
];
889 h
->next
= hash_table
[hash
];
890 h
->opcode
= &sparc_opcodes
[i
];
891 hash_table
[hash
] = h
;
895 #if 0 /* for debugging */
897 int min_count
= num_opcodes
, max_count
= 0;
900 for (i
= 0; i
< HASH_SIZE
; ++i
)
902 if (hash_count
[i
] < min_count
)
903 min_count
= hash_count
[i
];
904 if (hash_count
[i
] > max_count
)
905 max_count
= hash_count
[i
];
906 total
+= hash_count
[i
];
909 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
910 min_count
, max_count
, (double) total
/ HASH_SIZE
);