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