xref: /openbsd-src/gnu/usr.bin/binutils/opcodes/sparc-dis.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
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	(&reg_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