Home | History | Annotate | Line # | Download | only in opcodes
sparc-dis.c revision 1.1
      1  1.1  christos /* Print SPARC instructions.
      2  1.1  christos    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
      3  1.1  christos    2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
      4  1.1  christos    Free Software Foundation, Inc.
      5  1.1  christos 
      6  1.1  christos    This file is part of the GNU opcodes library.
      7  1.1  christos 
      8  1.1  christos    This library is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     11  1.1  christos    any later version.
     12  1.1  christos 
     13  1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT
     14  1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15  1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16  1.1  christos    License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program; if not, write to the Free Software
     20  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21  1.1  christos    MA 02110-1301, USA.  */
     22  1.1  christos 
     23  1.1  christos #include <stdio.h>
     24  1.1  christos 
     25  1.1  christos #include "sysdep.h"
     26  1.1  christos #include "opcode/sparc.h"
     27  1.1  christos #include "dis-asm.h"
     28  1.1  christos #include "libiberty.h"
     29  1.1  christos #include "opintl.h"
     30  1.1  christos 
     31  1.1  christos /* Bitmask of v9 architectures.  */
     32  1.1  christos #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
     33  1.1  christos 		 | (1 << SPARC_OPCODE_ARCH_V9A) \
     34  1.1  christos 		 | (1 << SPARC_OPCODE_ARCH_V9B))
     35  1.1  christos /* 1 if INSN is for v9 only.  */
     36  1.1  christos #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
     37  1.1  christos /* 1 if INSN is for v9.  */
     38  1.1  christos #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
     39  1.1  christos 
     40  1.1  christos /* The sorted opcode table.  */
     41  1.1  christos static const sparc_opcode **sorted_opcodes;
     42  1.1  christos 
     43  1.1  christos /* For faster lookup, after insns are sorted they are hashed.  */
     44  1.1  christos /* ??? I think there is room for even more improvement.  */
     45  1.1  christos 
     46  1.1  christos #define HASH_SIZE 256
     47  1.1  christos /* It is important that we only look at insn code bits as that is how the
     48  1.1  christos    opcode table is hashed.  OPCODE_BITS is a table of valid bits for each
     49  1.1  christos    of the main types (0,1,2,3).  */
     50  1.1  christos static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
     51  1.1  christos #define HASH_INSN(INSN) \
     52  1.1  christos   ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
     53  1.1  christos typedef struct sparc_opcode_hash
     54  1.1  christos {
     55  1.1  christos   struct sparc_opcode_hash *next;
     56  1.1  christos   const sparc_opcode *opcode;
     57  1.1  christos } sparc_opcode_hash;
     58  1.1  christos 
     59  1.1  christos static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
     60  1.1  christos 
     61  1.1  christos /* Sign-extend a value which is N bits long.  */
     62  1.1  christos #define	SEX(value, bits) \
     63  1.1  christos 	((((int)(value)) << ((8 * sizeof (int)) - bits))	\
     64  1.1  christos 			 >> ((8 * sizeof (int)) - bits) )
     65  1.1  christos 
     66  1.1  christos static  char *reg_names[] =
     67  1.1  christos { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
     68  1.1  christos   "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
     69  1.1  christos   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
     70  1.1  christos   "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
     71  1.1  christos   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
     72  1.1  christos   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
     73  1.1  christos   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
     74  1.1  christos   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
     75  1.1  christos   "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
     76  1.1  christos   "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
     77  1.1  christos   "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
     78  1.1  christos   "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
     79  1.1  christos /* psr, wim, tbr, fpsr, cpsr are v8 only.  */
     80  1.1  christos   "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
     81  1.1  christos };
     82  1.1  christos 
     83  1.1  christos #define	freg_names	(&reg_names[4 * 8])
     84  1.1  christos 
     85  1.1  christos /* These are ordered according to there register number in
     86  1.1  christos    rdpr and wrpr insns.  */
     87  1.1  christos static char *v9_priv_reg_names[] =
     88  1.1  christos {
     89  1.1  christos   "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
     90  1.1  christos   "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
     91  1.1  christos   "wstate", "fq", "gl"
     92  1.1  christos   /* "ver" - special cased */
     93  1.1  christos };
     94  1.1  christos 
     95  1.1  christos /* These are ordered according to there register number in
     96  1.1  christos    rdhpr and wrhpr insns.  */
     97  1.1  christos static char *v9_hpriv_reg_names[] =
     98  1.1  christos {
     99  1.1  christos   "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
    100  1.1  christos   "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
    101  1.1  christos   "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
    102  1.1  christos   "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
    103  1.1  christos   "resv28", "resv29", "resv30", "hstick_cmpr"
    104  1.1  christos };
    105  1.1  christos 
    106  1.1  christos /* These are ordered according to there register number in
    107  1.1  christos    rd and wr insns (-16).  */
    108  1.1  christos static char *v9a_asr_reg_names[] =
    109  1.1  christos {
    110  1.1  christos   "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
    111  1.1  christos   "softint", "tick_cmpr", "stick", "stick_cmpr"
    112  1.1  christos };
    113  1.1  christos 
    114  1.1  christos /* Macros used to extract instruction fields.  Not all fields have
    115  1.1  christos    macros defined here, only those which are actually used.  */
    116  1.1  christos 
    117  1.1  christos #define X_RD(i)      (((i) >> 25) & 0x1f)
    118  1.1  christos #define X_RS1(i)     (((i) >> 14) & 0x1f)
    119  1.1  christos #define X_LDST_I(i)  (((i) >> 13) & 1)
    120  1.1  christos #define X_ASI(i)     (((i) >> 5) & 0xff)
    121  1.1  christos #define X_RS2(i)     (((i) >> 0) & 0x1f)
    122  1.1  christos #define X_IMM(i,n)   (((i) >> 0) & ((1 << (n)) - 1))
    123  1.1  christos #define X_SIMM(i,n)  SEX (X_IMM ((i), (n)), (n))
    124  1.1  christos #define X_DISP22(i)  (((i) >> 0) & 0x3fffff)
    125  1.1  christos #define X_IMM22(i)   X_DISP22 (i)
    126  1.1  christos #define X_DISP30(i)  (((i) >> 0) & 0x3fffffff)
    127  1.1  christos 
    128  1.1  christos /* These are for v9.  */
    129  1.1  christos #define X_DISP16(i)  (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
    130  1.1  christos #define X_DISP19(i)  (((i) >> 0) & 0x7ffff)
    131  1.1  christos #define X_MEMBAR(i)  ((i) & 0x7f)
    132  1.1  christos 
    133  1.1  christos /* Here is the union which was used to extract instruction fields
    134  1.1  christos    before the shift and mask macros were written.
    135  1.1  christos 
    136  1.1  christos    union sparc_insn
    137  1.1  christos      {
    138  1.1  christos        unsigned long int code;
    139  1.1  christos        struct
    140  1.1  christos 	 {
    141  1.1  christos 	   unsigned int anop:2;
    142  1.1  christos 	   #define	op	ldst.anop
    143  1.1  christos 	   unsigned int anrd:5;
    144  1.1  christos 	   #define	rd	ldst.anrd
    145  1.1  christos 	   unsigned int op3:6;
    146  1.1  christos 	   unsigned int anrs1:5;
    147  1.1  christos 	   #define	rs1	ldst.anrs1
    148  1.1  christos 	   unsigned int i:1;
    149  1.1  christos 	   unsigned int anasi:8;
    150  1.1  christos 	   #define	asi	ldst.anasi
    151  1.1  christos 	   unsigned int anrs2:5;
    152  1.1  christos 	   #define	rs2	ldst.anrs2
    153  1.1  christos 	   #define	shcnt	rs2
    154  1.1  christos 	 } ldst;
    155  1.1  christos        struct
    156  1.1  christos 	 {
    157  1.1  christos 	   unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
    158  1.1  christos 	   unsigned int IMM13:13;
    159  1.1  christos 	   #define	imm13	IMM13.IMM13
    160  1.1  christos 	 } IMM13;
    161  1.1  christos        struct
    162  1.1  christos 	 {
    163  1.1  christos 	   unsigned int anop:2;
    164  1.1  christos 	   unsigned int a:1;
    165  1.1  christos 	   unsigned int cond:4;
    166  1.1  christos 	   unsigned int op2:3;
    167  1.1  christos 	   unsigned int DISP22:22;
    168  1.1  christos 	   #define	disp22	branch.DISP22
    169  1.1  christos 	   #define	imm22	disp22
    170  1.1  christos 	 } branch;
    171  1.1  christos        struct
    172  1.1  christos 	 {
    173  1.1  christos 	   unsigned int anop:2;
    174  1.1  christos 	   unsigned int a:1;
    175  1.1  christos 	   unsigned int z:1;
    176  1.1  christos 	   unsigned int rcond:3;
    177  1.1  christos 	   unsigned int op2:3;
    178  1.1  christos 	   unsigned int DISP16HI:2;
    179  1.1  christos 	   unsigned int p:1;
    180  1.1  christos 	   unsigned int _rs1:5;
    181  1.1  christos 	   unsigned int DISP16LO:14;
    182  1.1  christos 	 } branch16;
    183  1.1  christos        struct
    184  1.1  christos 	 {
    185  1.1  christos 	   unsigned int anop:2;
    186  1.1  christos 	   unsigned int adisp30:30;
    187  1.1  christos 	   #define	disp30	call.adisp30
    188  1.1  christos 	 } call;
    189  1.1  christos      };  */
    190  1.1  christos 
    191  1.1  christos /* Nonzero if INSN is the opcode for a delayed branch.  */
    192  1.1  christos 
    193  1.1  christos static int
    194  1.1  christos is_delayed_branch (unsigned long insn)
    195  1.1  christos {
    196  1.1  christos   sparc_opcode_hash *op;
    197  1.1  christos 
    198  1.1  christos   for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
    199  1.1  christos     {
    200  1.1  christos       const sparc_opcode *opcode = op->opcode;
    201  1.1  christos 
    202  1.1  christos       if ((opcode->match & insn) == opcode->match
    203  1.1  christos 	  && (opcode->lose & insn) == 0)
    204  1.1  christos 	return opcode->flags & F_DELAYED;
    205  1.1  christos     }
    206  1.1  christos   return 0;
    207  1.1  christos }
    208  1.1  christos 
    209  1.1  christos /* extern void qsort (); */
    210  1.1  christos 
    211  1.1  christos /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
    212  1.1  christos    to compare_opcodes.  */
    213  1.1  christos static unsigned int current_arch_mask;
    214  1.1  christos 
    215  1.1  christos /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values.  */
    216  1.1  christos 
    217  1.1  christos static int
    218  1.1  christos compute_arch_mask (unsigned long mach)
    219  1.1  christos {
    220  1.1  christos   switch (mach)
    221  1.1  christos     {
    222  1.1  christos     case 0 :
    223  1.1  christos     case bfd_mach_sparc :
    224  1.1  christos       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
    225  1.1  christos     case bfd_mach_sparc_sparclet :
    226  1.1  christos       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
    227  1.1  christos     case bfd_mach_sparc_sparclite :
    228  1.1  christos     case bfd_mach_sparc_sparclite_le :
    229  1.1  christos       /* sparclites insns are recognized by default (because that's how
    230  1.1  christos 	 they've always been treated, for better or worse).  Kludge this by
    231  1.1  christos 	 indicating generic v8 is also selected.  */
    232  1.1  christos       return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
    233  1.1  christos 	      | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
    234  1.1  christos     case bfd_mach_sparc_v8plus :
    235  1.1  christos     case bfd_mach_sparc_v9 :
    236  1.1  christos       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
    237  1.1  christos     case bfd_mach_sparc_v8plusa :
    238  1.1  christos     case bfd_mach_sparc_v9a :
    239  1.1  christos       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
    240  1.1  christos     case bfd_mach_sparc_v8plusb :
    241  1.1  christos     case bfd_mach_sparc_v9b :
    242  1.1  christos       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
    243  1.1  christos     }
    244  1.1  christos   abort ();
    245  1.1  christos }
    246  1.1  christos 
    247  1.1  christos /* Compare opcodes A and B.  */
    248  1.1  christos 
    249  1.1  christos static int
    250  1.1  christos compare_opcodes (const void * a, const void * b)
    251  1.1  christos {
    252  1.1  christos   sparc_opcode *op0 = * (sparc_opcode **) a;
    253  1.1  christos   sparc_opcode *op1 = * (sparc_opcode **) b;
    254  1.1  christos   unsigned long int match0 = op0->match, match1 = op1->match;
    255  1.1  christos   unsigned long int lose0 = op0->lose, lose1 = op1->lose;
    256  1.1  christos   register unsigned int i;
    257  1.1  christos 
    258  1.1  christos   /* If one (and only one) insn isn't supported by the current architecture,
    259  1.1  christos      prefer the one that is.  If neither are supported, but they're both for
    260  1.1  christos      the same architecture, continue processing.  Otherwise (both unsupported
    261  1.1  christos      and for different architectures), prefer lower numbered arch's (fudged
    262  1.1  christos      by comparing the bitmasks).  */
    263  1.1  christos   if (op0->architecture & current_arch_mask)
    264  1.1  christos     {
    265  1.1  christos       if (! (op1->architecture & current_arch_mask))
    266  1.1  christos 	return -1;
    267  1.1  christos     }
    268  1.1  christos   else
    269  1.1  christos     {
    270  1.1  christos       if (op1->architecture & current_arch_mask)
    271  1.1  christos 	return 1;
    272  1.1  christos       else if (op0->architecture != op1->architecture)
    273  1.1  christos 	return op0->architecture - op1->architecture;
    274  1.1  christos     }
    275  1.1  christos 
    276  1.1  christos   /* If a bit is set in both match and lose, there is something
    277  1.1  christos      wrong with the opcode table.  */
    278  1.1  christos   if (match0 & lose0)
    279  1.1  christos     {
    280  1.1  christos       fprintf
    281  1.1  christos 	(stderr,
    282  1.1  christos 	 /* xgettext:c-format */
    283  1.1  christos 	 _("Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
    284  1.1  christos 	 op0->name, match0, lose0);
    285  1.1  christos       op0->lose &= ~op0->match;
    286  1.1  christos       lose0 = op0->lose;
    287  1.1  christos     }
    288  1.1  christos 
    289  1.1  christos   if (match1 & lose1)
    290  1.1  christos     {
    291  1.1  christos       fprintf
    292  1.1  christos 	(stderr,
    293  1.1  christos 	 /* xgettext:c-format */
    294  1.1  christos 	 _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
    295  1.1  christos 	 op1->name, match1, lose1);
    296  1.1  christos       op1->lose &= ~op1->match;
    297  1.1  christos       lose1 = op1->lose;
    298  1.1  christos     }
    299  1.1  christos 
    300  1.1  christos   /* Because the bits that are variable in one opcode are constant in
    301  1.1  christos      another, it is important to order the opcodes in the right order.  */
    302  1.1  christos   for (i = 0; i < 32; ++i)
    303  1.1  christos     {
    304  1.1  christos       unsigned long int x = 1 << i;
    305  1.1  christos       int x0 = (match0 & x) != 0;
    306  1.1  christos       int x1 = (match1 & x) != 0;
    307  1.1  christos 
    308  1.1  christos       if (x0 != x1)
    309  1.1  christos 	return x1 - x0;
    310  1.1  christos     }
    311  1.1  christos 
    312  1.1  christos   for (i = 0; i < 32; ++i)
    313  1.1  christos     {
    314  1.1  christos       unsigned long int x = 1 << i;
    315  1.1  christos       int x0 = (lose0 & x) != 0;
    316  1.1  christos       int x1 = (lose1 & x) != 0;
    317  1.1  christos 
    318  1.1  christos       if (x0 != x1)
    319  1.1  christos 	return x1 - x0;
    320  1.1  christos     }
    321  1.1  christos 
    322  1.1  christos   /* They are functionally equal.  So as long as the opcode table is
    323  1.1  christos      valid, we can put whichever one first we want, on aesthetic grounds.  */
    324  1.1  christos 
    325  1.1  christos   /* Our first aesthetic ground is that aliases defer to real insns.  */
    326  1.1  christos   {
    327  1.1  christos     int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
    328  1.1  christos 
    329  1.1  christos     if (alias_diff != 0)
    330  1.1  christos       /* Put the one that isn't an alias first.  */
    331  1.1  christos       return alias_diff;
    332  1.1  christos   }
    333  1.1  christos 
    334  1.1  christos   /* Except for aliases, two "identical" instructions had
    335  1.1  christos      better have the same opcode.  This is a sanity check on the table.  */
    336  1.1  christos   i = strcmp (op0->name, op1->name);
    337  1.1  christos   if (i)
    338  1.1  christos     {
    339  1.1  christos       if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary.  */
    340  1.1  christos 	return i;
    341  1.1  christos       else
    342  1.1  christos 	fprintf (stderr,
    343  1.1  christos 		 /* xgettext:c-format */
    344  1.1  christos 		 _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
    345  1.1  christos 		 op0->name, op1->name);
    346  1.1  christos     }
    347  1.1  christos 
    348  1.1  christos   /* Fewer arguments are preferred.  */
    349  1.1  christos   {
    350  1.1  christos     int length_diff = strlen (op0->args) - strlen (op1->args);
    351  1.1  christos 
    352  1.1  christos     if (length_diff != 0)
    353  1.1  christos       /* Put the one with fewer arguments first.  */
    354  1.1  christos       return length_diff;
    355  1.1  christos   }
    356  1.1  christos 
    357  1.1  christos   /* Put 1+i before i+1.  */
    358  1.1  christos   {
    359  1.1  christos     char *p0 = (char *) strchr (op0->args, '+');
    360  1.1  christos     char *p1 = (char *) strchr (op1->args, '+');
    361  1.1  christos 
    362  1.1  christos     if (p0 && p1)
    363  1.1  christos       {
    364  1.1  christos 	/* There is a plus in both operands.  Note that a plus
    365  1.1  christos 	   sign cannot be the first character in args,
    366  1.1  christos 	   so the following [-1]'s are valid.  */
    367  1.1  christos 	if (p0[-1] == 'i' && p1[1] == 'i')
    368  1.1  christos 	  /* op0 is i+1 and op1 is 1+i, so op1 goes first.  */
    369  1.1  christos 	  return 1;
    370  1.1  christos 	if (p0[1] == 'i' && p1[-1] == 'i')
    371  1.1  christos 	  /* op0 is 1+i and op1 is i+1, so op0 goes first.  */
    372  1.1  christos 	  return -1;
    373  1.1  christos       }
    374  1.1  christos   }
    375  1.1  christos 
    376  1.1  christos   /* Put 1,i before i,1.  */
    377  1.1  christos   {
    378  1.1  christos     int i0 = strncmp (op0->args, "i,1", 3) == 0;
    379  1.1  christos     int i1 = strncmp (op1->args, "i,1", 3) == 0;
    380  1.1  christos 
    381  1.1  christos     if (i0 ^ i1)
    382  1.1  christos       return i0 - i1;
    383  1.1  christos   }
    384  1.1  christos 
    385  1.1  christos   /* They are, as far as we can tell, identical.
    386  1.1  christos      Since qsort may have rearranged the table partially, there is
    387  1.1  christos      no way to tell which one was first in the opcode table as
    388  1.1  christos      written, so just say there are equal.  */
    389  1.1  christos   /* ??? This is no longer true now that we sort a vector of pointers,
    390  1.1  christos      not the table itself.  */
    391  1.1  christos   return 0;
    392  1.1  christos }
    393  1.1  christos 
    394  1.1  christos /* Build a hash table from the opcode table.
    395  1.1  christos    OPCODE_TABLE is a sorted list of pointers into the opcode table.  */
    396  1.1  christos 
    397  1.1  christos static void
    398  1.1  christos build_hash_table (const sparc_opcode **opcode_table,
    399  1.1  christos 		  sparc_opcode_hash **hash_table,
    400  1.1  christos 		  int num_opcodes)
    401  1.1  christos {
    402  1.1  christos   int i;
    403  1.1  christos   int hash_count[HASH_SIZE];
    404  1.1  christos   static sparc_opcode_hash *hash_buf = NULL;
    405  1.1  christos 
    406  1.1  christos   /* Start at the end of the table and work backwards so that each
    407  1.1  christos      chain is sorted.  */
    408  1.1  christos 
    409  1.1  christos   memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
    410  1.1  christos   memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
    411  1.1  christos   if (hash_buf != NULL)
    412  1.1  christos     free (hash_buf);
    413  1.1  christos   hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
    414  1.1  christos   for (i = num_opcodes - 1; i >= 0; --i)
    415  1.1  christos     {
    416  1.1  christos       int hash = HASH_INSN (opcode_table[i]->match);
    417  1.1  christos       sparc_opcode_hash *h = &hash_buf[i];
    418  1.1  christos 
    419  1.1  christos       h->next = hash_table[hash];
    420  1.1  christos       h->opcode = opcode_table[i];
    421  1.1  christos       hash_table[hash] = h;
    422  1.1  christos       ++hash_count[hash];
    423  1.1  christos     }
    424  1.1  christos 
    425  1.1  christos #if 0 /* for debugging */
    426  1.1  christos   {
    427  1.1  christos     int min_count = num_opcodes, max_count = 0;
    428  1.1  christos     int total;
    429  1.1  christos 
    430  1.1  christos     for (i = 0; i < HASH_SIZE; ++i)
    431  1.1  christos       {
    432  1.1  christos         if (hash_count[i] < min_count)
    433  1.1  christos 	  min_count = hash_count[i];
    434  1.1  christos 	if (hash_count[i] > max_count)
    435  1.1  christos 	  max_count = hash_count[i];
    436  1.1  christos 	total += hash_count[i];
    437  1.1  christos       }
    438  1.1  christos 
    439  1.1  christos     printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
    440  1.1  christos 	    min_count, max_count, (double) total / HASH_SIZE);
    441  1.1  christos   }
    442  1.1  christos #endif
    443  1.1  christos }
    444  1.1  christos 
    445  1.1  christos /* Print one instruction from MEMADDR on INFO->STREAM.
    446  1.1  christos 
    447  1.1  christos    We suffix the instruction with a comment that gives the absolute
    448  1.1  christos    address involved, as well as its symbolic form, if the instruction
    449  1.1  christos    is preceded by a findable `sethi' and it either adds an immediate
    450  1.1  christos    displacement to that register, or it is an `add' or `or' instruction
    451  1.1  christos    on that register.  */
    452  1.1  christos 
    453  1.1  christos int
    454  1.1  christos print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
    455  1.1  christos {
    456  1.1  christos   FILE *stream = info->stream;
    457  1.1  christos   bfd_byte buffer[4];
    458  1.1  christos   unsigned long insn;
    459  1.1  christos   sparc_opcode_hash *op;
    460  1.1  christos   /* Nonzero of opcode table has been initialized.  */
    461  1.1  christos   static int opcodes_initialized = 0;
    462  1.1  christos   /* bfd mach number of last call.  */
    463  1.1  christos   static unsigned long current_mach = 0;
    464  1.1  christos   bfd_vma (*getword) (const void *);
    465  1.1  christos 
    466  1.1  christos   if (!opcodes_initialized
    467  1.1  christos       || info->mach != current_mach)
    468  1.1  christos     {
    469  1.1  christos       int i;
    470  1.1  christos 
    471  1.1  christos       current_arch_mask = compute_arch_mask (info->mach);
    472  1.1  christos 
    473  1.1  christos       if (!opcodes_initialized)
    474  1.1  christos 	sorted_opcodes =
    475  1.1  christos 	  xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
    476  1.1  christos       /* Reset the sorted table so we can resort it.  */
    477  1.1  christos       for (i = 0; i < sparc_num_opcodes; ++i)
    478  1.1  christos 	sorted_opcodes[i] = &sparc_opcodes[i];
    479  1.1  christos       qsort ((char *) sorted_opcodes, sparc_num_opcodes,
    480  1.1  christos 	     sizeof (sorted_opcodes[0]), compare_opcodes);
    481  1.1  christos 
    482  1.1  christos       build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
    483  1.1  christos       current_mach = info->mach;
    484  1.1  christos       opcodes_initialized = 1;
    485  1.1  christos     }
    486  1.1  christos 
    487  1.1  christos   {
    488  1.1  christos     int status =
    489  1.1  christos       (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
    490  1.1  christos 
    491  1.1  christos     if (status != 0)
    492  1.1  christos       {
    493  1.1  christos 	(*info->memory_error_func) (status, memaddr, info);
    494  1.1  christos 	return -1;
    495  1.1  christos       }
    496  1.1  christos   }
    497  1.1  christos 
    498  1.1  christos   /* On SPARClite variants such as DANlite (sparc86x), instructions
    499  1.1  christos      are always big-endian even when the machine is in little-endian mode.  */
    500  1.1  christos   if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
    501  1.1  christos     getword = bfd_getb32;
    502  1.1  christos   else
    503  1.1  christos     getword = bfd_getl32;
    504  1.1  christos 
    505  1.1  christos   insn = getword (buffer);
    506  1.1  christos 
    507  1.1  christos   info->insn_info_valid = 1;			/* We do return this info.  */
    508  1.1  christos   info->insn_type = dis_nonbranch;		/* Assume non branch insn.  */
    509  1.1  christos   info->branch_delay_insns = 0;			/* Assume no delay.  */
    510  1.1  christos   info->target = 0;				/* Assume no target known.  */
    511  1.1  christos 
    512  1.1  christos   for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
    513  1.1  christos     {
    514  1.1  christos       const sparc_opcode *opcode = op->opcode;
    515  1.1  christos 
    516  1.1  christos       /* If the insn isn't supported by the current architecture, skip it.  */
    517  1.1  christos       if (! (opcode->architecture & current_arch_mask))
    518  1.1  christos 	continue;
    519  1.1  christos 
    520  1.1  christos       if ((opcode->match & insn) == opcode->match
    521  1.1  christos 	  && (opcode->lose & insn) == 0)
    522  1.1  christos 	{
    523  1.1  christos 	  /* Nonzero means that we have found an instruction which has
    524  1.1  christos 	     the effect of adding or or'ing the imm13 field to rs1.  */
    525  1.1  christos 	  int imm_added_to_rs1 = 0;
    526  1.1  christos 	  int imm_ored_to_rs1 = 0;
    527  1.1  christos 
    528  1.1  christos 	  /* Nonzero means that we have found a plus sign in the args
    529  1.1  christos 	     field of the opcode table.  */
    530  1.1  christos 	  int found_plus = 0;
    531  1.1  christos 
    532  1.1  christos 	  /* Nonzero means we have an annulled branch.  */
    533  1.1  christos 	  int is_annulled = 0;
    534  1.1  christos 
    535  1.1  christos 	  /* Do we have an `add' or `or' instruction combining an
    536  1.1  christos              immediate with rs1?  */
    537  1.1  christos 	  if (opcode->match == 0x80102000) /* or */
    538  1.1  christos 	    imm_ored_to_rs1 = 1;
    539  1.1  christos 	  if (opcode->match == 0x80002000) /* add */
    540  1.1  christos 	    imm_added_to_rs1 = 1;
    541  1.1  christos 
    542  1.1  christos 	  if (X_RS1 (insn) != X_RD (insn)
    543  1.1  christos 	      && strchr (opcode->args, 'r') != 0)
    544  1.1  christos 	      /* Can't do simple format if source and dest are different.  */
    545  1.1  christos 	      continue;
    546  1.1  christos 	  if (X_RS2 (insn) != X_RD (insn)
    547  1.1  christos 	      && strchr (opcode->args, 'O') != 0)
    548  1.1  christos 	      /* Can't do simple format if source and dest are different.  */
    549  1.1  christos 	      continue;
    550  1.1  christos 
    551  1.1  christos 	  (*info->fprintf_func) (stream, opcode->name);
    552  1.1  christos 
    553  1.1  christos 	  {
    554  1.1  christos 	    const char *s;
    555  1.1  christos 
    556  1.1  christos 	    if (opcode->args[0] != ',')
    557  1.1  christos 	      (*info->fprintf_func) (stream, " ");
    558  1.1  christos 
    559  1.1  christos 	    for (s = opcode->args; *s != '\0'; ++s)
    560  1.1  christos 	      {
    561  1.1  christos 		while (*s == ',')
    562  1.1  christos 		  {
    563  1.1  christos 		    (*info->fprintf_func) (stream, ",");
    564  1.1  christos 		    ++s;
    565  1.1  christos 		    switch (*s)
    566  1.1  christos 		      {
    567  1.1  christos 		      case 'a':
    568  1.1  christos 			(*info->fprintf_func) (stream, "a");
    569  1.1  christos 			is_annulled = 1;
    570  1.1  christos 			++s;
    571  1.1  christos 			continue;
    572  1.1  christos 		      case 'N':
    573  1.1  christos 			(*info->fprintf_func) (stream, "pn");
    574  1.1  christos 			++s;
    575  1.1  christos 			continue;
    576  1.1  christos 
    577  1.1  christos 		      case 'T':
    578  1.1  christos 			(*info->fprintf_func) (stream, "pt");
    579  1.1  christos 			++s;
    580  1.1  christos 			continue;
    581  1.1  christos 
    582  1.1  christos 		      default:
    583  1.1  christos 			break;
    584  1.1  christos 		      }
    585  1.1  christos 		  }
    586  1.1  christos 
    587  1.1  christos 		(*info->fprintf_func) (stream, " ");
    588  1.1  christos 
    589  1.1  christos 		switch (*s)
    590  1.1  christos 		  {
    591  1.1  christos 		  case '+':
    592  1.1  christos 		    found_plus = 1;
    593  1.1  christos 		    /* Fall through.  */
    594  1.1  christos 
    595  1.1  christos 		  default:
    596  1.1  christos 		    (*info->fprintf_func) (stream, "%c", *s);
    597  1.1  christos 		    break;
    598  1.1  christos 
    599  1.1  christos 		  case '#':
    600  1.1  christos 		    (*info->fprintf_func) (stream, "0");
    601  1.1  christos 		    break;
    602  1.1  christos 
    603  1.1  christos #define	reg(n)	(*info->fprintf_func) (stream, "%%%s", reg_names[n])
    604  1.1  christos 		  case '1':
    605  1.1  christos 		  case 'r':
    606  1.1  christos 		    reg (X_RS1 (insn));
    607  1.1  christos 		    break;
    608  1.1  christos 
    609  1.1  christos 		  case '2':
    610  1.1  christos 		  case 'O':
    611  1.1  christos 		    reg (X_RS2 (insn));
    612  1.1  christos 		    break;
    613  1.1  christos 
    614  1.1  christos 		  case 'd':
    615  1.1  christos 		    reg (X_RD (insn));
    616  1.1  christos 		    break;
    617  1.1  christos #undef	reg
    618  1.1  christos 
    619  1.1  christos #define	freg(n)		(*info->fprintf_func) (stream, "%%%s", freg_names[n])
    620  1.1  christos #define	fregx(n)	(*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
    621  1.1  christos 		  case 'e':
    622  1.1  christos 		    freg (X_RS1 (insn));
    623  1.1  christos 		    break;
    624  1.1  christos 		  case 'v':	/* Double/even.  */
    625  1.1  christos 		  case 'V':	/* Quad/multiple of 4.  */
    626  1.1  christos 		    fregx (X_RS1 (insn));
    627  1.1  christos 		    break;
    628  1.1  christos 
    629  1.1  christos 		  case 'f':
    630  1.1  christos 		    freg (X_RS2 (insn));
    631  1.1  christos 		    break;
    632  1.1  christos 		  case 'B':	/* Double/even.  */
    633  1.1  christos 		  case 'R':	/* Quad/multiple of 4.  */
    634  1.1  christos 		    fregx (X_RS2 (insn));
    635  1.1  christos 		    break;
    636  1.1  christos 
    637  1.1  christos 		  case 'g':
    638  1.1  christos 		    freg (X_RD (insn));
    639  1.1  christos 		    break;
    640  1.1  christos 		  case 'H':	/* Double/even.  */
    641  1.1  christos 		  case 'J':	/* Quad/multiple of 4.  */
    642  1.1  christos 		    fregx (X_RD (insn));
    643  1.1  christos 		    break;
    644  1.1  christos #undef	freg
    645  1.1  christos #undef	fregx
    646  1.1  christos 
    647  1.1  christos #define	creg(n)	(*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
    648  1.1  christos 		  case 'b':
    649  1.1  christos 		    creg (X_RS1 (insn));
    650  1.1  christos 		    break;
    651  1.1  christos 
    652  1.1  christos 		  case 'c':
    653  1.1  christos 		    creg (X_RS2 (insn));
    654  1.1  christos 		    break;
    655  1.1  christos 
    656  1.1  christos 		  case 'D':
    657  1.1  christos 		    creg (X_RD (insn));
    658  1.1  christos 		    break;
    659  1.1  christos #undef	creg
    660  1.1  christos 
    661  1.1  christos 		  case 'h':
    662  1.1  christos 		    (*info->fprintf_func) (stream, "%%hi(%#x)",
    663  1.1  christos 					   ((unsigned) 0xFFFFFFFF
    664  1.1  christos 					    & ((int) X_IMM22 (insn) << 10)));
    665  1.1  christos 		    break;
    666  1.1  christos 
    667  1.1  christos 		  case 'i':	/* 13 bit immediate.  */
    668  1.1  christos 		  case 'I':	/* 11 bit immediate.  */
    669  1.1  christos 		  case 'j':	/* 10 bit immediate.  */
    670  1.1  christos 		    {
    671  1.1  christos 		      int imm;
    672  1.1  christos 
    673  1.1  christos 		      if (*s == 'i')
    674  1.1  christos 		        imm = X_SIMM (insn, 13);
    675  1.1  christos 		      else if (*s == 'I')
    676  1.1  christos 			imm = X_SIMM (insn, 11);
    677  1.1  christos 		      else
    678  1.1  christos 			imm = X_SIMM (insn, 10);
    679  1.1  christos 
    680  1.1  christos 		      /* Check to see whether we have a 1+i, and take
    681  1.1  christos 			 note of that fact.
    682  1.1  christos 
    683  1.1  christos 			 Note: because of the way we sort the table,
    684  1.1  christos 			 we will be matching 1+i rather than i+1,
    685  1.1  christos 			 so it is OK to assume that i is after +,
    686  1.1  christos 			 not before it.  */
    687  1.1  christos 		      if (found_plus)
    688  1.1  christos 			imm_added_to_rs1 = 1;
    689  1.1  christos 
    690  1.1  christos 		      if (imm <= 9)
    691  1.1  christos 			(*info->fprintf_func) (stream, "%d", imm);
    692  1.1  christos 		      else
    693  1.1  christos 			(*info->fprintf_func) (stream, "%#x", imm);
    694  1.1  christos 		    }
    695  1.1  christos 		    break;
    696  1.1  christos 
    697  1.1  christos 		  case 'X':	/* 5 bit unsigned immediate.  */
    698  1.1  christos 		  case 'Y':	/* 6 bit unsigned immediate.  */
    699  1.1  christos 		    {
    700  1.1  christos 		      int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
    701  1.1  christos 
    702  1.1  christos 		      if (imm <= 9)
    703  1.1  christos 			(info->fprintf_func) (stream, "%d", imm);
    704  1.1  christos 		      else
    705  1.1  christos 			(info->fprintf_func) (stream, "%#x", (unsigned) imm);
    706  1.1  christos 		    }
    707  1.1  christos 		    break;
    708  1.1  christos 
    709  1.1  christos 		  case '3':
    710  1.1  christos 		    (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
    711  1.1  christos 		    break;
    712  1.1  christos 
    713  1.1  christos 		  case 'K':
    714  1.1  christos 		    {
    715  1.1  christos 		      int mask = X_MEMBAR (insn);
    716  1.1  christos 		      int bit = 0x40, printed_one = 0;
    717  1.1  christos 		      const char *name;
    718  1.1  christos 
    719  1.1  christos 		      if (mask == 0)
    720  1.1  christos 			(info->fprintf_func) (stream, "0");
    721  1.1  christos 		      else
    722  1.1  christos 			while (bit)
    723  1.1  christos 			  {
    724  1.1  christos 			    if (mask & bit)
    725  1.1  christos 			      {
    726  1.1  christos 				if (printed_one)
    727  1.1  christos 				  (info->fprintf_func) (stream, "|");
    728  1.1  christos 				name = sparc_decode_membar (bit);
    729  1.1  christos 				(info->fprintf_func) (stream, "%s", name);
    730  1.1  christos 				printed_one = 1;
    731  1.1  christos 			      }
    732  1.1  christos 			    bit >>= 1;
    733  1.1  christos 			  }
    734  1.1  christos 		      break;
    735  1.1  christos 		    }
    736  1.1  christos 
    737  1.1  christos 		  case 'k':
    738  1.1  christos 		    info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
    739  1.1  christos 		    (*info->print_address_func) (info->target, info);
    740  1.1  christos 		    break;
    741  1.1  christos 
    742  1.1  christos 		  case 'G':
    743  1.1  christos 		    info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
    744  1.1  christos 		    (*info->print_address_func) (info->target, info);
    745  1.1  christos 		    break;
    746  1.1  christos 
    747  1.1  christos 		  case '6':
    748  1.1  christos 		  case '7':
    749  1.1  christos 		  case '8':
    750  1.1  christos 		  case '9':
    751  1.1  christos 		    (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
    752  1.1  christos 		    break;
    753  1.1  christos 
    754  1.1  christos 		  case 'z':
    755  1.1  christos 		    (*info->fprintf_func) (stream, "%%icc");
    756  1.1  christos 		    break;
    757  1.1  christos 
    758  1.1  christos 		  case 'Z':
    759  1.1  christos 		    (*info->fprintf_func) (stream, "%%xcc");
    760  1.1  christos 		    break;
    761  1.1  christos 
    762  1.1  christos 		  case 'E':
    763  1.1  christos 		    (*info->fprintf_func) (stream, "%%ccr");
    764  1.1  christos 		    break;
    765  1.1  christos 
    766  1.1  christos 		  case 's':
    767  1.1  christos 		    (*info->fprintf_func) (stream, "%%fprs");
    768  1.1  christos 		    break;
    769  1.1  christos 
    770  1.1  christos 		  case 'o':
    771  1.1  christos 		    (*info->fprintf_func) (stream, "%%asi");
    772  1.1  christos 		    break;
    773  1.1  christos 
    774  1.1  christos 		  case 'W':
    775  1.1  christos 		    (*info->fprintf_func) (stream, "%%tick");
    776  1.1  christos 		    break;
    777  1.1  christos 
    778  1.1  christos 		  case 'P':
    779  1.1  christos 		    (*info->fprintf_func) (stream, "%%pc");
    780  1.1  christos 		    break;
    781  1.1  christos 
    782  1.1  christos 		  case '?':
    783  1.1  christos 		    if (X_RS1 (insn) == 31)
    784  1.1  christos 		      (*info->fprintf_func) (stream, "%%ver");
    785  1.1  christos 		    else if ((unsigned) X_RS1 (insn) < 17)
    786  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    787  1.1  christos 					     v9_priv_reg_names[X_RS1 (insn)]);
    788  1.1  christos 		    else
    789  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    790  1.1  christos 		    break;
    791  1.1  christos 
    792  1.1  christos 		  case '!':
    793  1.1  christos 		    if ((unsigned) X_RD (insn) < 17)
    794  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    795  1.1  christos 					     v9_priv_reg_names[X_RD (insn)]);
    796  1.1  christos 		    else
    797  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    798  1.1  christos 		    break;
    799  1.1  christos 
    800  1.1  christos 		  case '$':
    801  1.1  christos 		    if ((unsigned) X_RS1 (insn) < 32)
    802  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    803  1.1  christos 					     v9_hpriv_reg_names[X_RS1 (insn)]);
    804  1.1  christos 		    else
    805  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    806  1.1  christos 		    break;
    807  1.1  christos 
    808  1.1  christos 		  case '%':
    809  1.1  christos 		    if ((unsigned) X_RD (insn) < 32)
    810  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    811  1.1  christos 					     v9_hpriv_reg_names[X_RD (insn)]);
    812  1.1  christos 		    else
    813  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    814  1.1  christos 		    break;
    815  1.1  christos 
    816  1.1  christos 		  case '/':
    817  1.1  christos 		    if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
    818  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    819  1.1  christos 		    else
    820  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    821  1.1  christos 					     v9a_asr_reg_names[X_RS1 (insn)-16]);
    822  1.1  christos 		    break;
    823  1.1  christos 
    824  1.1  christos 		  case '_':
    825  1.1  christos 		    if (X_RD (insn) < 16 || X_RD (insn) > 25)
    826  1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    827  1.1  christos 		    else
    828  1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    829  1.1  christos 					     v9a_asr_reg_names[X_RD (insn)-16]);
    830  1.1  christos 		    break;
    831  1.1  christos 
    832  1.1  christos 		  case '*':
    833  1.1  christos 		    {
    834  1.1  christos 		      const char *name = sparc_decode_prefetch (X_RD (insn));
    835  1.1  christos 
    836  1.1  christos 		      if (name)
    837  1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    838  1.1  christos 		      else
    839  1.1  christos 			(*info->fprintf_func) (stream, "%ld", X_RD (insn));
    840  1.1  christos 		      break;
    841  1.1  christos 		    }
    842  1.1  christos 
    843  1.1  christos 		  case 'M':
    844  1.1  christos 		    (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
    845  1.1  christos 		    break;
    846  1.1  christos 
    847  1.1  christos 		  case 'm':
    848  1.1  christos 		    (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
    849  1.1  christos 		    break;
    850  1.1  christos 
    851  1.1  christos 		  case 'L':
    852  1.1  christos 		    info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
    853  1.1  christos 		    (*info->print_address_func) (info->target, info);
    854  1.1  christos 		    break;
    855  1.1  christos 
    856  1.1  christos 		  case 'n':
    857  1.1  christos 		    (*info->fprintf_func)
    858  1.1  christos 		      (stream, "%#x", SEX (X_DISP22 (insn), 22));
    859  1.1  christos 		    break;
    860  1.1  christos 
    861  1.1  christos 		  case 'l':
    862  1.1  christos 		    info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
    863  1.1  christos 		    (*info->print_address_func) (info->target, info);
    864  1.1  christos 		    break;
    865  1.1  christos 
    866  1.1  christos 		  case 'A':
    867  1.1  christos 		    {
    868  1.1  christos 		      const char *name = sparc_decode_asi (X_ASI (insn));
    869  1.1  christos 
    870  1.1  christos 		      if (name)
    871  1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    872  1.1  christos 		      else
    873  1.1  christos 			(*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
    874  1.1  christos 		      break;
    875  1.1  christos 		    }
    876  1.1  christos 
    877  1.1  christos 		  case 'C':
    878  1.1  christos 		    (*info->fprintf_func) (stream, "%%csr");
    879  1.1  christos 		    break;
    880  1.1  christos 
    881  1.1  christos 		  case 'F':
    882  1.1  christos 		    (*info->fprintf_func) (stream, "%%fsr");
    883  1.1  christos 		    break;
    884  1.1  christos 
    885  1.1  christos 		  case 'p':
    886  1.1  christos 		    (*info->fprintf_func) (stream, "%%psr");
    887  1.1  christos 		    break;
    888  1.1  christos 
    889  1.1  christos 		  case 'q':
    890  1.1  christos 		    (*info->fprintf_func) (stream, "%%fq");
    891  1.1  christos 		    break;
    892  1.1  christos 
    893  1.1  christos 		  case 'Q':
    894  1.1  christos 		    (*info->fprintf_func) (stream, "%%cq");
    895  1.1  christos 		    break;
    896  1.1  christos 
    897  1.1  christos 		  case 't':
    898  1.1  christos 		    (*info->fprintf_func) (stream, "%%tbr");
    899  1.1  christos 		    break;
    900  1.1  christos 
    901  1.1  christos 		  case 'w':
    902  1.1  christos 		    (*info->fprintf_func) (stream, "%%wim");
    903  1.1  christos 		    break;
    904  1.1  christos 
    905  1.1  christos 		  case 'x':
    906  1.1  christos 		    (*info->fprintf_func) (stream, "%ld",
    907  1.1  christos 					   ((X_LDST_I (insn) << 8)
    908  1.1  christos 					    + X_ASI (insn)));
    909  1.1  christos 		    break;
    910  1.1  christos 
    911  1.1  christos 		  case 'y':
    912  1.1  christos 		    (*info->fprintf_func) (stream, "%%y");
    913  1.1  christos 		    break;
    914  1.1  christos 
    915  1.1  christos 		  case 'u':
    916  1.1  christos 		  case 'U':
    917  1.1  christos 		    {
    918  1.1  christos 		      int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
    919  1.1  christos 		      const char *name = sparc_decode_sparclet_cpreg (val);
    920  1.1  christos 
    921  1.1  christos 		      if (name)
    922  1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    923  1.1  christos 		      else
    924  1.1  christos 			(*info->fprintf_func) (stream, "%%cpreg(%d)", val);
    925  1.1  christos 		      break;
    926  1.1  christos 		    }
    927  1.1  christos 		  }
    928  1.1  christos 	      }
    929  1.1  christos 	  }
    930  1.1  christos 
    931  1.1  christos 	  /* If we are adding or or'ing something to rs1, then
    932  1.1  christos 	     check to see whether the previous instruction was
    933  1.1  christos 	     a sethi to the same register as in the sethi.
    934  1.1  christos 	     If so, attempt to print the result of the add or
    935  1.1  christos 	     or (in this context add and or do the same thing)
    936  1.1  christos 	     and its symbolic value.  */
    937  1.1  christos 	  if (imm_ored_to_rs1 || imm_added_to_rs1)
    938  1.1  christos 	    {
    939  1.1  christos 	      unsigned long prev_insn;
    940  1.1  christos 	      int errcode;
    941  1.1  christos 
    942  1.1  christos 	      if (memaddr >= 4)
    943  1.1  christos 		errcode =
    944  1.1  christos 		  (*info->read_memory_func)
    945  1.1  christos 		  (memaddr - 4, buffer, sizeof (buffer), info);
    946  1.1  christos 	      else
    947  1.1  christos 		errcode = 1;
    948  1.1  christos 
    949  1.1  christos 	      prev_insn = getword (buffer);
    950  1.1  christos 
    951  1.1  christos 	      if (errcode == 0)
    952  1.1  christos 		{
    953  1.1  christos 		  /* If it is a delayed branch, we need to look at the
    954  1.1  christos 		     instruction before the delayed branch.  This handles
    955  1.1  christos 		     sequences such as:
    956  1.1  christos 
    957  1.1  christos 		     sethi %o1, %hi(_foo), %o1
    958  1.1  christos 		     call _printf
    959  1.1  christos 		     or %o1, %lo(_foo), %o1  */
    960  1.1  christos 
    961  1.1  christos 		  if (is_delayed_branch (prev_insn))
    962  1.1  christos 		    {
    963  1.1  christos 		      if (memaddr >= 8)
    964  1.1  christos 			errcode = (*info->read_memory_func)
    965  1.1  christos 			  (memaddr - 8, buffer, sizeof (buffer), info);
    966  1.1  christos 		      else
    967  1.1  christos 			errcode = 1;
    968  1.1  christos 
    969  1.1  christos 		      prev_insn = getword (buffer);
    970  1.1  christos 		    }
    971  1.1  christos 		}
    972  1.1  christos 
    973  1.1  christos 	      /* If there was a problem reading memory, then assume
    974  1.1  christos 		 the previous instruction was not sethi.  */
    975  1.1  christos 	      if (errcode == 0)
    976  1.1  christos 		{
    977  1.1  christos 		  /* Is it sethi to the same register?  */
    978  1.1  christos 		  if ((prev_insn & 0xc1c00000) == 0x01000000
    979  1.1  christos 		      && X_RD (prev_insn) == X_RS1 (insn))
    980  1.1  christos 		    {
    981  1.1  christos 		      (*info->fprintf_func) (stream, "\t! ");
    982  1.1  christos 		      info->target =
    983  1.1  christos 			((unsigned) 0xFFFFFFFF
    984  1.1  christos 			 & ((int) X_IMM22 (prev_insn) << 10));
    985  1.1  christos 		      if (imm_added_to_rs1)
    986  1.1  christos 			info->target += X_SIMM (insn, 13);
    987  1.1  christos 		      else
    988  1.1  christos 			info->target |= X_SIMM (insn, 13);
    989  1.1  christos 		      (*info->print_address_func) (info->target, info);
    990  1.1  christos 		      info->insn_type = dis_dref;
    991  1.1  christos 		      info->data_size = 4;  /* FIXME!!! */
    992  1.1  christos 		    }
    993  1.1  christos 		}
    994  1.1  christos 	    }
    995  1.1  christos 
    996  1.1  christos 	  if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
    997  1.1  christos 	    {
    998  1.1  christos 	      /* FIXME -- check is_annulled flag.  */
    999  1.1  christos 	      (void) is_annulled;
   1000  1.1  christos 	      if (opcode->flags & F_UNBR)
   1001  1.1  christos 		info->insn_type = dis_branch;
   1002  1.1  christos 	      if (opcode->flags & F_CONDBR)
   1003  1.1  christos 		info->insn_type = dis_condbranch;
   1004  1.1  christos 	      if (opcode->flags & F_JSR)
   1005  1.1  christos 		info->insn_type = dis_jsr;
   1006  1.1  christos 	      if (opcode->flags & F_DELAYED)
   1007  1.1  christos 		info->branch_delay_insns = 1;
   1008  1.1  christos 	    }
   1009  1.1  christos 
   1010  1.1  christos 	  return sizeof (buffer);
   1011  1.1  christos 	}
   1012  1.1  christos     }
   1013  1.1  christos 
   1014  1.1  christos   info->insn_type = dis_noninsn;	/* Mark as non-valid instruction.  */
   1015  1.1  christos   (*info->fprintf_func) (stream, _("unknown"));
   1016  1.1  christos   return sizeof (buffer);
   1017  1.1  christos }
   1018