12159047fSniklas /* Print SPARC instructions.
2b55d4692Sfgsch Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3*007c2a45Smiod 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
42159047fSniklas
52159047fSniklas This program is free software; you can redistribute it and/or modify
62159047fSniklas it under the terms of the GNU General Public License as published by
72159047fSniklas the Free Software Foundation; either version 2 of the License, or
82159047fSniklas (at your option) any later version.
92159047fSniklas
102159047fSniklas This program is distributed in the hope that it will be useful,
112159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
122159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132159047fSniklas GNU General Public License for more details.
142159047fSniklas
152159047fSniklas You should have received a copy of the GNU General Public License
162159047fSniklas along with this program; if not, write to the Free Software
172159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
182159047fSniklas
19b305b0f1Sespie #include <stdio.h>
20b305b0f1Sespie
21b305b0f1Sespie #include "sysdep.h"
222159047fSniklas #include "opcode/sparc.h"
232159047fSniklas #include "dis-asm.h"
242159047fSniklas #include "libiberty.h"
25b305b0f1Sespie #include "opintl.h"
262159047fSniklas
27c88b1d6cSniklas /* Bitmask of v9 architectures. */
28c88b1d6cSniklas #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
29b55d4692Sfgsch | (1 << SPARC_OPCODE_ARCH_V9A) \
30b55d4692Sfgsch | (1 << SPARC_OPCODE_ARCH_V9B))
31c88b1d6cSniklas /* 1 if INSN is for v9 only. */
32c88b1d6cSniklas #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
33c88b1d6cSniklas /* 1 if INSN is for v9. */
34c88b1d6cSniklas #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
35c88b1d6cSniklas
36b305b0f1Sespie /* The sorted opcode table. */
37b305b0f1Sespie static const struct sparc_opcode **sorted_opcodes;
38b305b0f1Sespie
392159047fSniklas /* For faster lookup, after insns are sorted they are hashed. */
402159047fSniklas /* ??? I think there is room for even more improvement. */
412159047fSniklas
422159047fSniklas #define HASH_SIZE 256
432159047fSniklas /* It is important that we only look at insn code bits as that is how the
442159047fSniklas opcode table is hashed. OPCODE_BITS is a table of valid bits for each
452159047fSniklas of the main types (0,1,2,3). */
462159047fSniklas static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
472159047fSniklas #define HASH_INSN(INSN) \
482159047fSniklas ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
49c074d1c9Sdrahn struct opcode_hash
50c074d1c9Sdrahn {
512159047fSniklas struct opcode_hash *next;
52b305b0f1Sespie const struct sparc_opcode *opcode;
532159047fSniklas };
542159047fSniklas static struct opcode_hash *opcode_hash_table[HASH_SIZE];
55b305b0f1Sespie
56b305b0f1Sespie static void build_hash_table
57b305b0f1Sespie PARAMS ((const struct sparc_opcode **, struct opcode_hash **, int));
58b305b0f1Sespie static int is_delayed_branch PARAMS ((unsigned long));
59b305b0f1Sespie static int compare_opcodes PARAMS ((const PTR, const PTR));
60b305b0f1Sespie static int compute_arch_mask PARAMS ((unsigned long));
612159047fSniklas
622159047fSniklas /* Sign-extend a value which is N bits long. */
632159047fSniklas #define SEX(value, bits) \
642159047fSniklas ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
652159047fSniklas >> ((8 * sizeof (int)) - bits) )
662159047fSniklas
672159047fSniklas static char *reg_names[] =
682159047fSniklas { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
692159047fSniklas "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
702159047fSniklas "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
712159047fSniklas "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
722159047fSniklas "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
732159047fSniklas "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
742159047fSniklas "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
752159047fSniklas "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
762159047fSniklas "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
772159047fSniklas "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
782159047fSniklas "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
792159047fSniklas "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
802159047fSniklas /* psr, wim, tbr, fpsr, cpsr are v8 only. */
812159047fSniklas "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
822159047fSniklas };
832159047fSniklas
842159047fSniklas #define freg_names (®_names[4 * 8])
852159047fSniklas
862159047fSniklas /* These are ordered according to there register number in
872159047fSniklas rdpr and wrpr insns. */
882159047fSniklas static char *v9_priv_reg_names[] =
892159047fSniklas {
902159047fSniklas "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
912159047fSniklas "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
922159047fSniklas "wstate", "fq"
932159047fSniklas /* "ver" - special cased */
942159047fSniklas };
952159047fSniklas
96b305b0f1Sespie /* These are ordered according to there register number in
97b305b0f1Sespie rd and wr insns (-16). */
98b305b0f1Sespie static char *v9a_asr_reg_names[] =
99b305b0f1Sespie {
100b305b0f1Sespie "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
101b55d4692Sfgsch "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr"
102b305b0f1Sespie };
103b305b0f1Sespie
1042159047fSniklas /* Macros used to extract instruction fields. Not all fields have
1052159047fSniklas macros defined here, only those which are actually used. */
1062159047fSniklas
1072159047fSniklas #define X_RD(i) (((i) >> 25) & 0x1f)
1082159047fSniklas #define X_RS1(i) (((i) >> 14) & 0x1f)
1092159047fSniklas #define X_LDST_I(i) (((i) >> 13) & 1)
1102159047fSniklas #define X_ASI(i) (((i) >> 5) & 0xff)
1112159047fSniklas #define X_RS2(i) (((i) >> 0) & 0x1f)
112c88b1d6cSniklas #define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
113c88b1d6cSniklas #define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
1142159047fSniklas #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
1152159047fSniklas #define X_IMM22(i) X_DISP22 (i)
1162159047fSniklas #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
1172159047fSniklas
1182159047fSniklas /* These are for v9. */
1192159047fSniklas #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
1202159047fSniklas #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
1212159047fSniklas #define X_MEMBAR(i) ((i) & 0x7f)
1222159047fSniklas
1232159047fSniklas /* Here is the union which was used to extract instruction fields
1242159047fSniklas before the shift and mask macros were written.
1252159047fSniklas
1262159047fSniklas union sparc_insn
1272159047fSniklas {
1282159047fSniklas unsigned long int code;
1292159047fSniklas struct
1302159047fSniklas {
1312159047fSniklas unsigned int anop:2;
1322159047fSniklas #define op ldst.anop
1332159047fSniklas unsigned int anrd:5;
1342159047fSniklas #define rd ldst.anrd
1352159047fSniklas unsigned int op3:6;
1362159047fSniklas unsigned int anrs1:5;
1372159047fSniklas #define rs1 ldst.anrs1
1382159047fSniklas unsigned int i:1;
1392159047fSniklas unsigned int anasi:8;
1402159047fSniklas #define asi ldst.anasi
1412159047fSniklas unsigned int anrs2:5;
1422159047fSniklas #define rs2 ldst.anrs2
1432159047fSniklas #define shcnt rs2
1442159047fSniklas } ldst;
1452159047fSniklas struct
1462159047fSniklas {
1472159047fSniklas unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
1482159047fSniklas unsigned int IMM13:13;
1492159047fSniklas #define imm13 IMM13.IMM13
1502159047fSniklas } IMM13;
1512159047fSniklas struct
1522159047fSniklas {
1532159047fSniklas unsigned int anop:2;
1542159047fSniklas unsigned int a:1;
1552159047fSniklas unsigned int cond:4;
1562159047fSniklas unsigned int op2:3;
1572159047fSniklas unsigned int DISP22:22;
1582159047fSniklas #define disp22 branch.DISP22
1592159047fSniklas #define imm22 disp22
1602159047fSniklas } branch;
1612159047fSniklas struct
1622159047fSniklas {
1632159047fSniklas unsigned int anop:2;
1642159047fSniklas unsigned int a:1;
1652159047fSniklas unsigned int z:1;
1662159047fSniklas unsigned int rcond:3;
1672159047fSniklas unsigned int op2:3;
1682159047fSniklas unsigned int DISP16HI:2;
1692159047fSniklas unsigned int p:1;
1702159047fSniklas unsigned int _rs1:5;
1712159047fSniklas unsigned int DISP16LO:14;
1722159047fSniklas } branch16;
1732159047fSniklas struct
1742159047fSniklas {
1752159047fSniklas unsigned int anop:2;
1762159047fSniklas unsigned int adisp30:30;
1772159047fSniklas #define disp30 call.adisp30
1782159047fSniklas } call;
1792159047fSniklas };
1802159047fSniklas
1812159047fSniklas */
1822159047fSniklas
1832159047fSniklas /* Nonzero if INSN is the opcode for a delayed branch. */
1842159047fSniklas static int
is_delayed_branch(insn)1852159047fSniklas is_delayed_branch (insn)
1862159047fSniklas unsigned long insn;
1872159047fSniklas {
1882159047fSniklas struct opcode_hash *op;
1892159047fSniklas
1902159047fSniklas for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
1912159047fSniklas {
192c074d1c9Sdrahn const struct sparc_opcode *opcode = op->opcode;
1932159047fSniklas if ((opcode->match & insn) == opcode->match
1942159047fSniklas && (opcode->lose & insn) == 0)
1952159047fSniklas return (opcode->flags & F_DELAYED);
1962159047fSniklas }
1972159047fSniklas return 0;
1982159047fSniklas }
1992159047fSniklas
2002159047fSniklas /* extern void qsort (); */
2012159047fSniklas
202c88b1d6cSniklas /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
203c88b1d6cSniklas to compare_opcodes. */
204c88b1d6cSniklas static unsigned int current_arch_mask;
205c88b1d6cSniklas
2062159047fSniklas /* Print one instruction from MEMADDR on INFO->STREAM.
2072159047fSniklas
2082159047fSniklas We suffix the instruction with a comment that gives the absolute
2092159047fSniklas address involved, as well as its symbolic form, if the instruction
2102159047fSniklas is preceded by a findable `sethi' and it either adds an immediate
2112159047fSniklas displacement to that register, or it is an `add' or `or' instruction
2122159047fSniklas on that register. */
2132159047fSniklas
214c88b1d6cSniklas int
print_insn_sparc(memaddr,info)215c88b1d6cSniklas print_insn_sparc (memaddr, info)
2162159047fSniklas bfd_vma memaddr;
2172159047fSniklas disassemble_info *info;
2182159047fSniklas {
2192159047fSniklas FILE *stream = info->stream;
2202159047fSniklas bfd_byte buffer[4];
2212159047fSniklas unsigned long insn;
2222159047fSniklas register struct opcode_hash *op;
223c88b1d6cSniklas /* Nonzero of opcode table has been initialized. */
224c88b1d6cSniklas static int opcodes_initialized = 0;
225c88b1d6cSniklas /* bfd mach number of last call. */
226c88b1d6cSniklas static unsigned long current_mach = 0;
227*007c2a45Smiod bfd_vma (*getword) (const void *);
2282159047fSniklas
229c88b1d6cSniklas if (!opcodes_initialized
230c88b1d6cSniklas || info->mach != current_mach)
2312159047fSniklas {
232b305b0f1Sespie int i;
233b305b0f1Sespie
234c88b1d6cSniklas current_arch_mask = compute_arch_mask (info->mach);
235b305b0f1Sespie
236b305b0f1Sespie if (!opcodes_initialized)
237b305b0f1Sespie sorted_opcodes = (const struct sparc_opcode **)
238b305b0f1Sespie xmalloc (sparc_num_opcodes * sizeof (struct sparc_opcode *));
239b305b0f1Sespie /* Reset the sorted table so we can resort it. */
240b305b0f1Sespie for (i = 0; i < sparc_num_opcodes; ++i)
241b305b0f1Sespie sorted_opcodes[i] = &sparc_opcodes[i];
242b305b0f1Sespie qsort ((char *) sorted_opcodes, sparc_num_opcodes,
243b305b0f1Sespie sizeof (sorted_opcodes[0]), compare_opcodes);
244b305b0f1Sespie
245b305b0f1Sespie build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
246c88b1d6cSniklas current_mach = info->mach;
2472159047fSniklas opcodes_initialized = 1;
2482159047fSniklas }
2492159047fSniklas
2502159047fSniklas {
2512159047fSniklas int status =
2522159047fSniklas (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
2532159047fSniklas if (status != 0)
2542159047fSniklas {
2552159047fSniklas (*info->memory_error_func) (status, memaddr, info);
2562159047fSniklas return -1;
2572159047fSniklas }
2582159047fSniklas }
2592159047fSniklas
260b305b0f1Sespie /* On SPARClite variants such as DANlite (sparc86x), instructions
261b305b0f1Sespie are always big-endian even when the machine is in little-endian mode. */
262b305b0f1Sespie if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
263b305b0f1Sespie getword = bfd_getb32;
2640c6d0228Sniklas else
265b305b0f1Sespie getword = bfd_getl32;
266b305b0f1Sespie
267b305b0f1Sespie insn = getword (buffer);
2682159047fSniklas
269c074d1c9Sdrahn info->insn_info_valid = 1; /* We do return this info. */
270c074d1c9Sdrahn info->insn_type = dis_nonbranch; /* Assume non branch insn. */
271c074d1c9Sdrahn info->branch_delay_insns = 0; /* Assume no delay. */
272c074d1c9Sdrahn info->target = 0; /* Assume no target known. */
2732159047fSniklas
2742159047fSniklas for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
2752159047fSniklas {
276c074d1c9Sdrahn const struct sparc_opcode *opcode = op->opcode;
2772159047fSniklas
278c88b1d6cSniklas /* If the insn isn't supported by the current architecture, skip it. */
279c88b1d6cSniklas if (! (opcode->architecture & current_arch_mask))
2802159047fSniklas continue;
2812159047fSniklas
2822159047fSniklas if ((opcode->match & insn) == opcode->match
2832159047fSniklas && (opcode->lose & insn) == 0)
2842159047fSniklas {
2852159047fSniklas /* Nonzero means that we have found an instruction which has
2862159047fSniklas the effect of adding or or'ing the imm13 field to rs1. */
2872159047fSniklas int imm_added_to_rs1 = 0;
288b305b0f1Sespie int imm_ored_to_rs1 = 0;
2892159047fSniklas
2902159047fSniklas /* Nonzero means that we have found a plus sign in the args
2912159047fSniklas field of the opcode table. */
2922159047fSniklas int found_plus = 0;
2932159047fSniklas
2942159047fSniklas /* Nonzero means we have an annulled branch. */
2952159047fSniklas int is_annulled = 0;
2962159047fSniklas
2970c6d0228Sniklas /* Do we have an `add' or `or' instruction combining an
2980c6d0228Sniklas immediate with rs1? */
299b305b0f1Sespie if (opcode->match == 0x80102000) /* or */
300b305b0f1Sespie imm_ored_to_rs1 = 1;
301b305b0f1Sespie if (opcode->match == 0x80002000) /* add */
3022159047fSniklas imm_added_to_rs1 = 1;
3032159047fSniklas
3042159047fSniklas if (X_RS1 (insn) != X_RD (insn)
3052159047fSniklas && strchr (opcode->args, 'r') != 0)
3062159047fSniklas /* Can't do simple format if source and dest are different. */
3072159047fSniklas continue;
308c88b1d6cSniklas if (X_RS2 (insn) != X_RD (insn)
309c88b1d6cSniklas && strchr (opcode->args, 'O') != 0)
310c88b1d6cSniklas /* Can't do simple format if source and dest are different. */
311c88b1d6cSniklas continue;
3122159047fSniklas
3132159047fSniklas (*info->fprintf_func) (stream, opcode->name);
3142159047fSniklas
3152159047fSniklas {
316c074d1c9Sdrahn register const char *s;
3172159047fSniklas
3182159047fSniklas if (opcode->args[0] != ',')
3192159047fSniklas (*info->fprintf_func) (stream, " ");
320c074d1c9Sdrahn
3212159047fSniklas for (s = opcode->args; *s != '\0'; ++s)
3222159047fSniklas {
3232159047fSniklas while (*s == ',')
3242159047fSniklas {
3252159047fSniklas (*info->fprintf_func) (stream, ",");
3262159047fSniklas ++s;
327c074d1c9Sdrahn switch (*s)
328c074d1c9Sdrahn {
3292159047fSniklas case 'a':
3302159047fSniklas (*info->fprintf_func) (stream, "a");
3312159047fSniklas is_annulled = 1;
3322159047fSniklas ++s;
3332159047fSniklas continue;
3342159047fSniklas case 'N':
3352159047fSniklas (*info->fprintf_func) (stream, "pn");
3362159047fSniklas ++s;
3372159047fSniklas continue;
3382159047fSniklas
3392159047fSniklas case 'T':
3402159047fSniklas (*info->fprintf_func) (stream, "pt");
3412159047fSniklas ++s;
3422159047fSniklas continue;
3432159047fSniklas
3442159047fSniklas default:
3452159047fSniklas break;
346c074d1c9Sdrahn }
347c074d1c9Sdrahn }
3482159047fSniklas
3492159047fSniklas (*info->fprintf_func) (stream, " ");
3502159047fSniklas
3512159047fSniklas switch (*s)
3522159047fSniklas {
3532159047fSniklas case '+':
3542159047fSniklas found_plus = 1;
3552159047fSniklas
3562159047fSniklas /* note fall-through */
3572159047fSniklas default:
3582159047fSniklas (*info->fprintf_func) (stream, "%c", *s);
3592159047fSniklas break;
3602159047fSniklas
3612159047fSniklas case '#':
3622159047fSniklas (*info->fprintf_func) (stream, "0");
3632159047fSniklas break;
3642159047fSniklas
3652159047fSniklas #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
3662159047fSniklas case '1':
3672159047fSniklas case 'r':
3682159047fSniklas reg (X_RS1 (insn));
3692159047fSniklas break;
3702159047fSniklas
3712159047fSniklas case '2':
372c88b1d6cSniklas case 'O':
3732159047fSniklas reg (X_RS2 (insn));
3742159047fSniklas break;
3752159047fSniklas
3762159047fSniklas case 'd':
3772159047fSniklas reg (X_RD (insn));
3782159047fSniklas break;
3792159047fSniklas #undef reg
3802159047fSniklas
3812159047fSniklas #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
3822159047fSniklas #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
3832159047fSniklas case 'e':
3842159047fSniklas freg (X_RS1 (insn));
3852159047fSniklas break;
3862159047fSniklas case 'v': /* double/even */
3872159047fSniklas case 'V': /* quad/multiple of 4 */
3882159047fSniklas fregx (X_RS1 (insn));
3892159047fSniklas break;
3902159047fSniklas
3912159047fSniklas case 'f':
3922159047fSniklas freg (X_RS2 (insn));
3932159047fSniklas break;
3942159047fSniklas case 'B': /* double/even */
3952159047fSniklas case 'R': /* quad/multiple of 4 */
3962159047fSniklas fregx (X_RS2 (insn));
3972159047fSniklas break;
3982159047fSniklas
3992159047fSniklas case 'g':
4002159047fSniklas freg (X_RD (insn));
4012159047fSniklas break;
4022159047fSniklas case 'H': /* double/even */
4032159047fSniklas case 'J': /* quad/multiple of 4 */
4042159047fSniklas fregx (X_RD (insn));
4052159047fSniklas break;
4062159047fSniklas #undef freg
4072159047fSniklas #undef fregx
4082159047fSniklas
4092159047fSniklas #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
4102159047fSniklas case 'b':
4112159047fSniklas creg (X_RS1 (insn));
4122159047fSniklas break;
4132159047fSniklas
4142159047fSniklas case 'c':
4152159047fSniklas creg (X_RS2 (insn));
4162159047fSniklas break;
4172159047fSniklas
4182159047fSniklas case 'D':
4192159047fSniklas creg (X_RD (insn));
4202159047fSniklas break;
4212159047fSniklas #undef creg
4222159047fSniklas
4232159047fSniklas case 'h':
4242159047fSniklas (*info->fprintf_func) (stream, "%%hi(%#x)",
425c074d1c9Sdrahn ((unsigned) 0xFFFFFFFF
4262159047fSniklas & ((int) X_IMM22 (insn) << 10)));
4272159047fSniklas break;
4282159047fSniklas
429c88b1d6cSniklas case 'i': /* 13 bit immediate */
430c88b1d6cSniklas case 'I': /* 11 bit immediate */
431c88b1d6cSniklas case 'j': /* 10 bit immediate */
4322159047fSniklas {
433c88b1d6cSniklas int imm;
434c88b1d6cSniklas
435c88b1d6cSniklas if (*s == 'i')
436c88b1d6cSniklas imm = X_SIMM (insn, 13);
437c88b1d6cSniklas else if (*s == 'I')
438c88b1d6cSniklas imm = X_SIMM (insn, 11);
439c88b1d6cSniklas else
440c88b1d6cSniklas imm = X_SIMM (insn, 10);
4412159047fSniklas
4422159047fSniklas /* Check to see whether we have a 1+i, and take
4432159047fSniklas note of that fact.
4442159047fSniklas
4452159047fSniklas Note: because of the way we sort the table,
4462159047fSniklas we will be matching 1+i rather than i+1,
4472159047fSniklas so it is OK to assume that i is after +,
4482159047fSniklas not before it. */
4492159047fSniklas if (found_plus)
4502159047fSniklas imm_added_to_rs1 = 1;
4512159047fSniklas
4522159047fSniklas if (imm <= 9)
4532159047fSniklas (*info->fprintf_func) (stream, "%d", imm);
4542159047fSniklas else
4552159047fSniklas (*info->fprintf_func) (stream, "%#x", imm);
4562159047fSniklas }
4572159047fSniklas break;
4582159047fSniklas
459c88b1d6cSniklas case 'X': /* 5 bit unsigned immediate */
460c88b1d6cSniklas case 'Y': /* 6 bit unsigned immediate */
4612159047fSniklas {
462c88b1d6cSniklas int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
4632159047fSniklas
4642159047fSniklas if (imm <= 9)
4652159047fSniklas (info->fprintf_func) (stream, "%d", imm);
4662159047fSniklas else
4672159047fSniklas (info->fprintf_func) (stream, "%#x", (unsigned) imm);
4682159047fSniklas }
4692159047fSniklas break;
4702159047fSniklas
471b55d4692Sfgsch case '3':
472b55d4692Sfgsch (info->fprintf_func) (stream, "%d", X_IMM (insn, 3));
473b55d4692Sfgsch break;
474b55d4692Sfgsch
4752159047fSniklas case 'K':
4762159047fSniklas {
4772159047fSniklas int mask = X_MEMBAR (insn);
4782159047fSniklas int bit = 0x40, printed_one = 0;
479b305b0f1Sespie const char *name;
4802159047fSniklas
4812159047fSniklas if (mask == 0)
4822159047fSniklas (info->fprintf_func) (stream, "0");
4832159047fSniklas else
4842159047fSniklas while (bit)
4852159047fSniklas {
4862159047fSniklas if (mask & bit)
4872159047fSniklas {
4882159047fSniklas if (printed_one)
4892159047fSniklas (info->fprintf_func) (stream, "|");
4902159047fSniklas name = sparc_decode_membar (bit);
4912159047fSniklas (info->fprintf_func) (stream, "%s", name);
4922159047fSniklas printed_one = 1;
4932159047fSniklas }
4942159047fSniklas bit >>= 1;
4952159047fSniklas }
4962159047fSniklas break;
4972159047fSniklas }
4982159047fSniklas
4992159047fSniklas case 'k':
5002159047fSniklas info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
5012159047fSniklas (*info->print_address_func) (info->target, info);
5022159047fSniklas break;
5032159047fSniklas
5042159047fSniklas case 'G':
5052159047fSniklas info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
5062159047fSniklas (*info->print_address_func) (info->target, info);
5072159047fSniklas break;
5082159047fSniklas
5092159047fSniklas case '6':
5102159047fSniklas case '7':
5112159047fSniklas case '8':
5122159047fSniklas case '9':
5132159047fSniklas (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
5142159047fSniklas break;
5152159047fSniklas
5162159047fSniklas case 'z':
5172159047fSniklas (*info->fprintf_func) (stream, "%%icc");
5182159047fSniklas break;
5192159047fSniklas
5202159047fSniklas case 'Z':
5212159047fSniklas (*info->fprintf_func) (stream, "%%xcc");
5222159047fSniklas break;
5232159047fSniklas
5242159047fSniklas case 'E':
5252159047fSniklas (*info->fprintf_func) (stream, "%%ccr");
5262159047fSniklas break;
5272159047fSniklas
5282159047fSniklas case 's':
5292159047fSniklas (*info->fprintf_func) (stream, "%%fprs");
5302159047fSniklas break;
5312159047fSniklas
5322159047fSniklas case 'o':
5332159047fSniklas (*info->fprintf_func) (stream, "%%asi");
5342159047fSniklas break;
5352159047fSniklas
5362159047fSniklas case 'W':
5372159047fSniklas (*info->fprintf_func) (stream, "%%tick");
5382159047fSniklas break;
5392159047fSniklas
5402159047fSniklas case 'P':
5412159047fSniklas (*info->fprintf_func) (stream, "%%pc");
5422159047fSniklas break;
5432159047fSniklas
5442159047fSniklas case '?':
5452159047fSniklas if (X_RS1 (insn) == 31)
5462159047fSniklas (*info->fprintf_func) (stream, "%%ver");
5472159047fSniklas else if ((unsigned) X_RS1 (insn) < 16)
5482159047fSniklas (*info->fprintf_func) (stream, "%%%s",
5492159047fSniklas v9_priv_reg_names[X_RS1 (insn)]);
5502159047fSniklas else
5512159047fSniklas (*info->fprintf_func) (stream, "%%reserved");
5522159047fSniklas break;
5532159047fSniklas
5542159047fSniklas case '!':
5552159047fSniklas if ((unsigned) X_RD (insn) < 15)
5562159047fSniklas (*info->fprintf_func) (stream, "%%%s",
5572159047fSniklas v9_priv_reg_names[X_RD (insn)]);
5582159047fSniklas else
5592159047fSniklas (*info->fprintf_func) (stream, "%%reserved");
5602159047fSniklas break;
5612159047fSniklas
562b305b0f1Sespie case '/':
563b55d4692Sfgsch if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
564b305b0f1Sespie (*info->fprintf_func) (stream, "%%reserved");
565b305b0f1Sespie else
566b305b0f1Sespie (*info->fprintf_func) (stream, "%%%s",
567b305b0f1Sespie v9a_asr_reg_names[X_RS1 (insn)-16]);
568b305b0f1Sespie break;
569b305b0f1Sespie
570b305b0f1Sespie case '_':
571b55d4692Sfgsch if (X_RD (insn) < 16 || X_RD (insn) > 25)
572b305b0f1Sespie (*info->fprintf_func) (stream, "%%reserved");
573b305b0f1Sespie else
574b305b0f1Sespie (*info->fprintf_func) (stream, "%%%s",
575b305b0f1Sespie v9a_asr_reg_names[X_RD (insn)-16]);
576b305b0f1Sespie break;
577b305b0f1Sespie
5782159047fSniklas case '*':
5792159047fSniklas {
580b305b0f1Sespie const char *name = sparc_decode_prefetch (X_RD (insn));
5812159047fSniklas
5822159047fSniklas if (name)
5832159047fSniklas (*info->fprintf_func) (stream, "%s", name);
5842159047fSniklas else
5852159047fSniklas (*info->fprintf_func) (stream, "%d", X_RD (insn));
5862159047fSniklas break;
5872159047fSniklas }
5882159047fSniklas
5892159047fSniklas case 'M':
5902159047fSniklas (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
5912159047fSniklas break;
5922159047fSniklas
5932159047fSniklas case 'm':
5942159047fSniklas (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
5952159047fSniklas break;
5962159047fSniklas
5972159047fSniklas case 'L':
5982159047fSniklas info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
5992159047fSniklas (*info->print_address_func) (info->target, info);
6002159047fSniklas break;
6012159047fSniklas
6022159047fSniklas case 'n':
6032159047fSniklas (*info->fprintf_func)
6042159047fSniklas (stream, "%#x", SEX (X_DISP22 (insn), 22));
6052159047fSniklas break;
6062159047fSniklas
6072159047fSniklas case 'l':
6082159047fSniklas info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
6092159047fSniklas (*info->print_address_func) (info->target, info);
6102159047fSniklas break;
6112159047fSniklas
6122159047fSniklas case 'A':
6132159047fSniklas {
614b305b0f1Sespie const char *name = sparc_decode_asi (X_ASI (insn));
6152159047fSniklas
6162159047fSniklas if (name)
6172159047fSniklas (*info->fprintf_func) (stream, "%s", name);
6182159047fSniklas else
6192159047fSniklas (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
6202159047fSniklas break;
6212159047fSniklas }
6222159047fSniklas
6232159047fSniklas case 'C':
6242159047fSniklas (*info->fprintf_func) (stream, "%%csr");
6252159047fSniklas break;
6262159047fSniklas
6272159047fSniklas case 'F':
6282159047fSniklas (*info->fprintf_func) (stream, "%%fsr");
6292159047fSniklas break;
6302159047fSniklas
6312159047fSniklas case 'p':
6322159047fSniklas (*info->fprintf_func) (stream, "%%psr");
6332159047fSniklas break;
6342159047fSniklas
6352159047fSniklas case 'q':
6362159047fSniklas (*info->fprintf_func) (stream, "%%fq");
6372159047fSniklas break;
6382159047fSniklas
6392159047fSniklas case 'Q':
6402159047fSniklas (*info->fprintf_func) (stream, "%%cq");
6412159047fSniklas break;
6422159047fSniklas
6432159047fSniklas case 't':
6442159047fSniklas (*info->fprintf_func) (stream, "%%tbr");
6452159047fSniklas break;
6462159047fSniklas
6472159047fSniklas case 'w':
6482159047fSniklas (*info->fprintf_func) (stream, "%%wim");
6492159047fSniklas break;
6502159047fSniklas
6512159047fSniklas case 'x':
6522159047fSniklas (*info->fprintf_func) (stream, "%d",
6532159047fSniklas ((X_LDST_I (insn) << 8)
6542159047fSniklas + X_ASI (insn)));
6552159047fSniklas break;
6562159047fSniklas
6572159047fSniklas case 'y':
6582159047fSniklas (*info->fprintf_func) (stream, "%%y");
6592159047fSniklas break;
660c88b1d6cSniklas
661c88b1d6cSniklas case 'u':
662c88b1d6cSniklas case 'U':
663c88b1d6cSniklas {
664c88b1d6cSniklas int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
665b305b0f1Sespie const char *name = sparc_decode_sparclet_cpreg (val);
666c88b1d6cSniklas
667c88b1d6cSniklas if (name)
668c88b1d6cSniklas (*info->fprintf_func) (stream, "%s", name);
669c88b1d6cSniklas else
670c88b1d6cSniklas (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
671c88b1d6cSniklas break;
672c88b1d6cSniklas }
6732159047fSniklas }
6742159047fSniklas }
6752159047fSniklas }
6762159047fSniklas
6772159047fSniklas /* If we are adding or or'ing something to rs1, then
6782159047fSniklas check to see whether the previous instruction was
6792159047fSniklas a sethi to the same register as in the sethi.
6802159047fSniklas If so, attempt to print the result of the add or
6812159047fSniklas or (in this context add and or do the same thing)
6822159047fSniklas and its symbolic value. */
683b305b0f1Sespie if (imm_ored_to_rs1 || imm_added_to_rs1)
6842159047fSniklas {
6852159047fSniklas unsigned long prev_insn;
6862159047fSniklas int errcode;
6872159047fSniklas
688eaa3acd6Sbrad if (memaddr >= 4)
6892159047fSniklas errcode =
6902159047fSniklas (*info->read_memory_func)
6912159047fSniklas (memaddr - 4, buffer, sizeof (buffer), info);
692eaa3acd6Sbrad else
693eaa3acd6Sbrad errcode = 1;
694eaa3acd6Sbrad
695b305b0f1Sespie prev_insn = getword (buffer);
6962159047fSniklas
6972159047fSniklas if (errcode == 0)
6982159047fSniklas {
6992159047fSniklas /* If it is a delayed branch, we need to look at the
7002159047fSniklas instruction before the delayed branch. This handles
701c074d1c9Sdrahn sequences such as:
7022159047fSniklas
7032159047fSniklas sethi %o1, %hi(_foo), %o1
7042159047fSniklas call _printf
705c074d1c9Sdrahn or %o1, %lo(_foo), %o1 */
7062159047fSniklas
7072159047fSniklas if (is_delayed_branch (prev_insn))
7082159047fSniklas {
709eaa3acd6Sbrad if (memaddr >= 8)
7102159047fSniklas errcode = (*info->read_memory_func)
7112159047fSniklas (memaddr - 8, buffer, sizeof (buffer), info);
712eaa3acd6Sbrad else
713eaa3acd6Sbrad errcode = 1;
714eaa3acd6Sbrad
715b305b0f1Sespie prev_insn = getword (buffer);
7162159047fSniklas }
7172159047fSniklas }
7182159047fSniklas
7192159047fSniklas /* If there was a problem reading memory, then assume
7202159047fSniklas the previous instruction was not sethi. */
7212159047fSniklas if (errcode == 0)
7222159047fSniklas {
7232159047fSniklas /* Is it sethi to the same register? */
7242159047fSniklas if ((prev_insn & 0xc1c00000) == 0x01000000
7252159047fSniklas && X_RD (prev_insn) == X_RS1 (insn))
7262159047fSniklas {
7272159047fSniklas (*info->fprintf_func) (stream, "\t! ");
7282159047fSniklas info->target =
729c074d1c9Sdrahn ((unsigned) 0xFFFFFFFF
730c074d1c9Sdrahn & ((int) X_IMM22 (prev_insn) << 10));
731b305b0f1Sespie if (imm_added_to_rs1)
732b305b0f1Sespie info->target += X_SIMM (insn, 13);
733b305b0f1Sespie else
734b305b0f1Sespie info->target |= X_SIMM (insn, 13);
7352159047fSniklas (*info->print_address_func) (info->target, info);
7362159047fSniklas info->insn_type = dis_dref;
7372159047fSniklas info->data_size = 4; /* FIXME!!! */
7382159047fSniklas }
7392159047fSniklas }
7402159047fSniklas }
7412159047fSniklas
7422159047fSniklas if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
7432159047fSniklas {
7442159047fSniklas /* FIXME -- check is_annulled flag */
7452159047fSniklas if (opcode->flags & F_UNBR)
7462159047fSniklas info->insn_type = dis_branch;
7472159047fSniklas if (opcode->flags & F_CONDBR)
7482159047fSniklas info->insn_type = dis_condbranch;
7492159047fSniklas if (opcode->flags & F_JSR)
7502159047fSniklas info->insn_type = dis_jsr;
7512159047fSniklas if (opcode->flags & F_DELAYED)
7522159047fSniklas info->branch_delay_insns = 1;
7532159047fSniklas }
7542159047fSniklas
7552159047fSniklas return sizeof (buffer);
7562159047fSniklas }
7572159047fSniklas }
7582159047fSniklas
759c074d1c9Sdrahn info->insn_type = dis_noninsn; /* Mark as non-valid instruction. */
760b305b0f1Sespie (*info->fprintf_func) (stream, _("unknown"));
7612159047fSniklas return sizeof (buffer);
7622159047fSniklas }
7632159047fSniklas
764c88b1d6cSniklas /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
765c88b1d6cSniklas
766c88b1d6cSniklas static int
compute_arch_mask(mach)767c88b1d6cSniklas compute_arch_mask (mach)
768c88b1d6cSniklas unsigned long mach;
769c88b1d6cSniklas {
770c88b1d6cSniklas switch (mach)
771c88b1d6cSniklas {
772c88b1d6cSniklas case 0 :
773c88b1d6cSniklas case bfd_mach_sparc :
774c88b1d6cSniklas return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
775c88b1d6cSniklas case bfd_mach_sparc_sparclet :
776c88b1d6cSniklas return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
777c88b1d6cSniklas case bfd_mach_sparc_sparclite :
778b305b0f1Sespie case bfd_mach_sparc_sparclite_le :
779c88b1d6cSniklas /* sparclites insns are recognized by default (because that's how
780c88b1d6cSniklas they've always been treated, for better or worse). Kludge this by
781c88b1d6cSniklas indicating generic v8 is also selected. */
782c88b1d6cSniklas return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
783c88b1d6cSniklas | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
784c88b1d6cSniklas case bfd_mach_sparc_v8plus :
785c88b1d6cSniklas case bfd_mach_sparc_v9 :
786c88b1d6cSniklas return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
787c88b1d6cSniklas case bfd_mach_sparc_v8plusa :
788c88b1d6cSniklas case bfd_mach_sparc_v9a :
789c88b1d6cSniklas return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
790b55d4692Sfgsch case bfd_mach_sparc_v8plusb :
791b55d4692Sfgsch case bfd_mach_sparc_v9b :
792b55d4692Sfgsch return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
793c88b1d6cSniklas }
794c88b1d6cSniklas abort ();
795c88b1d6cSniklas }
796c88b1d6cSniklas
7972159047fSniklas /* Compare opcodes A and B. */
7982159047fSniklas
7992159047fSniklas static int
compare_opcodes(a,b)8002159047fSniklas compare_opcodes (a, b)
801b305b0f1Sespie const PTR a;
802b305b0f1Sespie const PTR b;
8032159047fSniklas {
804b305b0f1Sespie struct sparc_opcode *op0 = * (struct sparc_opcode **) a;
805b305b0f1Sespie struct sparc_opcode *op1 = * (struct sparc_opcode **) b;
8062159047fSniklas unsigned long int match0 = op0->match, match1 = op1->match;
8072159047fSniklas unsigned long int lose0 = op0->lose, lose1 = op1->lose;
8082159047fSniklas register unsigned int i;
8092159047fSniklas
810c88b1d6cSniklas /* If one (and only one) insn isn't supported by the current architecture,
811c88b1d6cSniklas prefer the one that is. If neither are supported, but they're both for
812c88b1d6cSniklas the same architecture, continue processing. Otherwise (both unsupported
813c88b1d6cSniklas and for different architectures), prefer lower numbered arch's (fudged
814c88b1d6cSniklas by comparing the bitmasks). */
815c88b1d6cSniklas if (op0->architecture & current_arch_mask)
816c88b1d6cSniklas {
817c88b1d6cSniklas if (! (op1->architecture & current_arch_mask))
818c88b1d6cSniklas return -1;
819c88b1d6cSniklas }
820c88b1d6cSniklas else
821c88b1d6cSniklas {
822c88b1d6cSniklas if (op1->architecture & current_arch_mask)
823c88b1d6cSniklas return 1;
824c88b1d6cSniklas else if (op0->architecture != op1->architecture)
825c88b1d6cSniklas return op0->architecture - op1->architecture;
826c88b1d6cSniklas }
827c88b1d6cSniklas
8282159047fSniklas /* If a bit is set in both match and lose, there is something
8292159047fSniklas wrong with the opcode table. */
8302159047fSniklas if (match0 & lose0)
8312159047fSniklas {
832b305b0f1Sespie fprintf
833b305b0f1Sespie (stderr,
834b305b0f1Sespie /* xgettext:c-format */
835b305b0f1Sespie _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
8362159047fSniklas op0->name, match0, lose0);
8372159047fSniklas op0->lose &= ~op0->match;
8382159047fSniklas lose0 = op0->lose;
8392159047fSniklas }
8402159047fSniklas
8412159047fSniklas if (match1 & lose1)
8422159047fSniklas {
843b305b0f1Sespie fprintf
844b305b0f1Sespie (stderr,
845b305b0f1Sespie /* xgettext:c-format */
846b305b0f1Sespie _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
8472159047fSniklas op1->name, match1, lose1);
8482159047fSniklas op1->lose &= ~op1->match;
8492159047fSniklas lose1 = op1->lose;
8502159047fSniklas }
8512159047fSniklas
8522159047fSniklas /* Because the bits that are variable in one opcode are constant in
8532159047fSniklas another, it is important to order the opcodes in the right order. */
8542159047fSniklas for (i = 0; i < 32; ++i)
8552159047fSniklas {
8562159047fSniklas unsigned long int x = 1 << i;
8572159047fSniklas int x0 = (match0 & x) != 0;
8582159047fSniklas int x1 = (match1 & x) != 0;
8592159047fSniklas
8602159047fSniklas if (x0 != x1)
8612159047fSniklas return x1 - x0;
8622159047fSniklas }
8632159047fSniklas
8642159047fSniklas for (i = 0; i < 32; ++i)
8652159047fSniklas {
8662159047fSniklas unsigned long int x = 1 << i;
8672159047fSniklas int x0 = (lose0 & x) != 0;
8682159047fSniklas int x1 = (lose1 & x) != 0;
8692159047fSniklas
8702159047fSniklas if (x0 != x1)
8712159047fSniklas return x1 - x0;
8722159047fSniklas }
8732159047fSniklas
8742159047fSniklas /* They are functionally equal. So as long as the opcode table is
8752159047fSniklas valid, we can put whichever one first we want, on aesthetic grounds. */
8762159047fSniklas
8772159047fSniklas /* Our first aesthetic ground is that aliases defer to real insns. */
8782159047fSniklas {
8792159047fSniklas int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
8802159047fSniklas if (alias_diff != 0)
8812159047fSniklas /* Put the one that isn't an alias first. */
8822159047fSniklas return alias_diff;
8832159047fSniklas }
8842159047fSniklas
8852159047fSniklas /* Except for aliases, two "identical" instructions had
8862159047fSniklas better have the same opcode. This is a sanity check on the table. */
8872159047fSniklas i = strcmp (op0->name, op1->name);
8882159047fSniklas if (i)
889c88b1d6cSniklas {
8902159047fSniklas if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
8912159047fSniklas return i;
8922159047fSniklas else
8932159047fSniklas fprintf (stderr,
894b305b0f1Sespie /* xgettext:c-format */
895b305b0f1Sespie _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
8962159047fSniklas op0->name, op1->name);
897c88b1d6cSniklas }
8982159047fSniklas
8992159047fSniklas /* Fewer arguments are preferred. */
9002159047fSniklas {
9012159047fSniklas int length_diff = strlen (op0->args) - strlen (op1->args);
9022159047fSniklas if (length_diff != 0)
9032159047fSniklas /* Put the one with fewer arguments first. */
9042159047fSniklas return length_diff;
9052159047fSniklas }
9062159047fSniklas
9072159047fSniklas /* Put 1+i before i+1. */
9082159047fSniklas {
9092159047fSniklas char *p0 = (char *) strchr (op0->args, '+');
9102159047fSniklas char *p1 = (char *) strchr (op1->args, '+');
9112159047fSniklas
9122159047fSniklas if (p0 && p1)
9132159047fSniklas {
9142159047fSniklas /* There is a plus in both operands. Note that a plus
9152159047fSniklas sign cannot be the first character in args,
9162159047fSniklas so the following [-1]'s are valid. */
9172159047fSniklas if (p0[-1] == 'i' && p1[1] == 'i')
9182159047fSniklas /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
9192159047fSniklas return 1;
9202159047fSniklas if (p0[1] == 'i' && p1[-1] == 'i')
9212159047fSniklas /* op0 is 1+i and op1 is i+1, so op0 goes first. */
9222159047fSniklas return -1;
9232159047fSniklas }
9242159047fSniklas }
9252159047fSniklas
9262159047fSniklas /* Put 1,i before i,1. */
9272159047fSniklas {
9282159047fSniklas int i0 = strncmp (op0->args, "i,1", 3) == 0;
9292159047fSniklas int i1 = strncmp (op1->args, "i,1", 3) == 0;
9302159047fSniklas
9312159047fSniklas if (i0 ^ i1)
9322159047fSniklas return i0 - i1;
9332159047fSniklas }
9342159047fSniklas
9352159047fSniklas /* They are, as far as we can tell, identical.
9362159047fSniklas Since qsort may have rearranged the table partially, there is
9372159047fSniklas no way to tell which one was first in the opcode table as
9382159047fSniklas written, so just say there are equal. */
939b305b0f1Sespie /* ??? This is no longer true now that we sort a vector of pointers,
940b305b0f1Sespie not the table itself. */
9412159047fSniklas return 0;
9422159047fSniklas }
9432159047fSniklas
944b305b0f1Sespie /* Build a hash table from the opcode table.
945b305b0f1Sespie OPCODE_TABLE is a sorted list of pointers into the opcode table. */
9462159047fSniklas
9472159047fSniklas static void
build_hash_table(opcode_table,hash_table,num_opcodes)948b305b0f1Sespie build_hash_table (opcode_table, hash_table, num_opcodes)
949b305b0f1Sespie const struct sparc_opcode **opcode_table;
9502159047fSniklas struct opcode_hash **hash_table;
9512159047fSniklas int num_opcodes;
9522159047fSniklas {
9532159047fSniklas register int i;
9542159047fSniklas int hash_count[HASH_SIZE];
9552159047fSniklas static struct opcode_hash *hash_buf = NULL;
9562159047fSniklas
9572159047fSniklas /* Start at the end of the table and work backwards so that each
9582159047fSniklas chain is sorted. */
9592159047fSniklas
9602159047fSniklas memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
9612159047fSniklas memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
9622159047fSniklas if (hash_buf != NULL)
9632159047fSniklas free (hash_buf);
9642159047fSniklas hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
9652159047fSniklas for (i = num_opcodes - 1; i >= 0; --i)
9662159047fSniklas {
967b305b0f1Sespie register int hash = HASH_INSN (opcode_table[i]->match);
9682159047fSniklas register struct opcode_hash *h = &hash_buf[i];
9692159047fSniklas h->next = hash_table[hash];
970b305b0f1Sespie h->opcode = opcode_table[i];
9712159047fSniklas hash_table[hash] = h;
9722159047fSniklas ++hash_count[hash];
9732159047fSniklas }
9742159047fSniklas
9752159047fSniklas #if 0 /* for debugging */
9762159047fSniklas {
9772159047fSniklas int min_count = num_opcodes, max_count = 0;
9782159047fSniklas int total;
9792159047fSniklas
9802159047fSniklas for (i = 0; i < HASH_SIZE; ++i)
9812159047fSniklas {
9822159047fSniklas if (hash_count[i] < min_count)
9832159047fSniklas min_count = hash_count[i];
9842159047fSniklas if (hash_count[i] > max_count)
9852159047fSniklas max_count = hash_count[i];
9862159047fSniklas total += hash_count[i];
9872159047fSniklas }
9882159047fSniklas
9892159047fSniklas printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
9902159047fSniklas min_count, max_count, (double) total / HASH_SIZE);
9912159047fSniklas }
9922159047fSniklas #endif
9932159047fSniklas }
994