Home | History | Annotate | Line # | Download | only in opcodes
      1       1.1  christos /* Print SPARC instructions.
      2  1.1.1.11  christos    Copyright (C) 1989-2025 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.1.11  christos   /* They are, as far as we can tell, identical.  Keep the order in
    391  1.1.1.11  christos      the sparc_opcodes table.  */
    392  1.1.1.11  christos   if (op0 < op1)
    393  1.1.1.11  christos     return -1;
    394  1.1.1.11  christos   if (op0 > op1)
    395  1.1.1.11  christos     return 1;
    396       1.1  christos   return 0;
    397       1.1  christos }
    398       1.1  christos 
    399       1.1  christos /* Build a hash table from the opcode table.
    400       1.1  christos    OPCODE_TABLE is a sorted list of pointers into the opcode table.  */
    401       1.1  christos 
    402       1.1  christos static void
    403       1.1  christos build_hash_table (const sparc_opcode **opcode_table,
    404       1.1  christos 		  sparc_opcode_hash **hash_table,
    405       1.1  christos 		  int num_opcodes)
    406       1.1  christos {
    407       1.1  christos   int i;
    408       1.1  christos   int hash_count[HASH_SIZE];
    409       1.1  christos   static sparc_opcode_hash *hash_buf = NULL;
    410       1.1  christos 
    411       1.1  christos   /* Start at the end of the table and work backwards so that each
    412       1.1  christos      chain is sorted.  */
    413       1.1  christos 
    414       1.1  christos   memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
    415       1.1  christos   memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
    416   1.1.1.8  christos   free (hash_buf);
    417       1.1  christos   hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
    418       1.1  christos   for (i = num_opcodes - 1; i >= 0; --i)
    419       1.1  christos     {
    420       1.1  christos       int hash = HASH_INSN (opcode_table[i]->match);
    421       1.1  christos       sparc_opcode_hash *h = &hash_buf[i];
    422       1.1  christos 
    423       1.1  christos       h->next = hash_table[hash];
    424       1.1  christos       h->opcode = opcode_table[i];
    425       1.1  christos       hash_table[hash] = h;
    426       1.1  christos       ++hash_count[hash];
    427       1.1  christos     }
    428       1.1  christos 
    429       1.1  christos #if 0 /* for debugging */
    430       1.1  christos   {
    431       1.1  christos     int min_count = num_opcodes, max_count = 0;
    432       1.1  christos     int total;
    433       1.1  christos 
    434       1.1  christos     for (i = 0; i < HASH_SIZE; ++i)
    435       1.1  christos       {
    436       1.1  christos         if (hash_count[i] < min_count)
    437       1.1  christos 	  min_count = hash_count[i];
    438       1.1  christos 	if (hash_count[i] > max_count)
    439       1.1  christos 	  max_count = hash_count[i];
    440       1.1  christos 	total += hash_count[i];
    441       1.1  christos       }
    442       1.1  christos 
    443       1.1  christos     printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
    444       1.1  christos 	    min_count, max_count, (double) total / HASH_SIZE);
    445       1.1  christos   }
    446       1.1  christos #endif
    447       1.1  christos }
    448       1.1  christos 
    449       1.1  christos /* Print one instruction from MEMADDR on INFO->STREAM.
    450       1.1  christos 
    451       1.1  christos    We suffix the instruction with a comment that gives the absolute
    452       1.1  christos    address involved, as well as its symbolic form, if the instruction
    453       1.1  christos    is preceded by a findable `sethi' and it either adds an immediate
    454       1.1  christos    displacement to that register, or it is an `add' or `or' instruction
    455       1.1  christos    on that register.  */
    456       1.1  christos 
    457       1.1  christos int
    458       1.1  christos print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
    459       1.1  christos {
    460       1.1  christos   FILE *stream = info->stream;
    461       1.1  christos   bfd_byte buffer[4];
    462       1.1  christos   unsigned long insn;
    463       1.1  christos   sparc_opcode_hash *op;
    464       1.1  christos   /* Nonzero of opcode table has been initialized.  */
    465       1.1  christos   static int opcodes_initialized = 0;
    466       1.1  christos   /* bfd mach number of last call.  */
    467       1.1  christos   static unsigned long current_mach = 0;
    468       1.1  christos   bfd_vma (*getword) (const void *);
    469       1.1  christos 
    470       1.1  christos   if (!opcodes_initialized
    471       1.1  christos       || info->mach != current_mach)
    472       1.1  christos     {
    473       1.1  christos       int i;
    474       1.1  christos 
    475       1.1  christos       current_arch_mask = compute_arch_mask (info->mach);
    476       1.1  christos 
    477       1.1  christos       if (!opcodes_initialized)
    478       1.1  christos 	sorted_opcodes =
    479       1.1  christos 	  xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
    480       1.1  christos       /* Reset the sorted table so we can resort it.  */
    481       1.1  christos       for (i = 0; i < sparc_num_opcodes; ++i)
    482       1.1  christos 	sorted_opcodes[i] = &sparc_opcodes[i];
    483       1.1  christos       qsort ((char *) sorted_opcodes, sparc_num_opcodes,
    484       1.1  christos 	     sizeof (sorted_opcodes[0]), compare_opcodes);
    485       1.1  christos 
    486       1.1  christos       build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
    487       1.1  christos       current_mach = info->mach;
    488       1.1  christos       opcodes_initialized = 1;
    489       1.1  christos     }
    490       1.1  christos 
    491       1.1  christos   {
    492       1.1  christos     int status =
    493       1.1  christos       (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
    494       1.1  christos 
    495       1.1  christos     if (status != 0)
    496       1.1  christos       {
    497       1.1  christos 	(*info->memory_error_func) (status, memaddr, info);
    498       1.1  christos 	return -1;
    499       1.1  christos       }
    500       1.1  christos   }
    501       1.1  christos 
    502       1.1  christos   /* On SPARClite variants such as DANlite (sparc86x), instructions
    503       1.1  christos      are always big-endian even when the machine is in little-endian mode.  */
    504       1.1  christos   if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
    505       1.1  christos     getword = bfd_getb32;
    506       1.1  christos   else
    507       1.1  christos     getword = bfd_getl32;
    508       1.1  christos 
    509       1.1  christos   insn = getword (buffer);
    510       1.1  christos 
    511       1.1  christos   info->insn_info_valid = 1;			/* We do return this info.  */
    512       1.1  christos   info->insn_type = dis_nonbranch;		/* Assume non branch insn.  */
    513       1.1  christos   info->branch_delay_insns = 0;			/* Assume no delay.  */
    514       1.1  christos   info->target = 0;				/* Assume no target known.  */
    515       1.1  christos 
    516       1.1  christos   for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
    517       1.1  christos     {
    518       1.1  christos       const sparc_opcode *opcode = op->opcode;
    519       1.1  christos 
    520       1.1  christos       /* If the insn isn't supported by the current architecture, skip it.  */
    521       1.1  christos       if (! (opcode->architecture & current_arch_mask))
    522       1.1  christos 	continue;
    523       1.1  christos 
    524       1.1  christos       if ((opcode->match & insn) == opcode->match
    525       1.1  christos 	  && (opcode->lose & insn) == 0)
    526       1.1  christos 	{
    527       1.1  christos 	  /* Nonzero means that we have found an instruction which has
    528       1.1  christos 	     the effect of adding or or'ing the imm13 field to rs1.  */
    529       1.1  christos 	  int imm_added_to_rs1 = 0;
    530       1.1  christos 	  int imm_ored_to_rs1 = 0;
    531       1.1  christos 
    532       1.1  christos 	  /* Nonzero means that we have found a plus sign in the args
    533       1.1  christos 	     field of the opcode table.  */
    534       1.1  christos 	  int found_plus = 0;
    535       1.1  christos 
    536       1.1  christos 	  /* Nonzero means we have an annulled branch.  */
    537       1.1  christos 	  int is_annulled = 0;
    538       1.1  christos 
    539       1.1  christos 	  /* Do we have an `add' or `or' instruction combining an
    540       1.1  christos              immediate with rs1?  */
    541       1.1  christos 	  if (opcode->match == 0x80102000) /* or */
    542       1.1  christos 	    imm_ored_to_rs1 = 1;
    543       1.1  christos 	  if (opcode->match == 0x80002000) /* add */
    544       1.1  christos 	    imm_added_to_rs1 = 1;
    545       1.1  christos 
    546       1.1  christos 	  if (X_RS1 (insn) != X_RD (insn)
    547       1.1  christos 	      && strchr (opcode->args, 'r') != 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 	  if (X_RS2 (insn) != X_RD (insn)
    551       1.1  christos 	      && strchr (opcode->args, 'O') != 0)
    552       1.1  christos 	      /* Can't do simple format if source and dest are different.  */
    553       1.1  christos 	      continue;
    554       1.1  christos 
    555   1.1.1.2  christos 	  (*info->fprintf_func) (stream, "%s", opcode->name);
    556       1.1  christos 
    557       1.1  christos 	  {
    558       1.1  christos 	    const char *s;
    559       1.1  christos 
    560       1.1  christos 	    if (opcode->args[0] != ',')
    561       1.1  christos 	      (*info->fprintf_func) (stream, " ");
    562       1.1  christos 
    563       1.1  christos 	    for (s = opcode->args; *s != '\0'; ++s)
    564       1.1  christos 	      {
    565       1.1  christos 		while (*s == ',')
    566       1.1  christos 		  {
    567       1.1  christos 		    (*info->fprintf_func) (stream, ",");
    568       1.1  christos 		    ++s;
    569       1.1  christos 		    switch (*s)
    570       1.1  christos 		      {
    571       1.1  christos 		      case 'a':
    572       1.1  christos 			(*info->fprintf_func) (stream, "a");
    573       1.1  christos 			is_annulled = 1;
    574       1.1  christos 			++s;
    575       1.1  christos 			continue;
    576       1.1  christos 		      case 'N':
    577       1.1  christos 			(*info->fprintf_func) (stream, "pn");
    578       1.1  christos 			++s;
    579       1.1  christos 			continue;
    580       1.1  christos 
    581       1.1  christos 		      case 'T':
    582       1.1  christos 			(*info->fprintf_func) (stream, "pt");
    583       1.1  christos 			++s;
    584       1.1  christos 			continue;
    585       1.1  christos 
    586       1.1  christos 		      default:
    587       1.1  christos 			break;
    588       1.1  christos 		      }
    589       1.1  christos 		  }
    590       1.1  christos 
    591       1.1  christos 		(*info->fprintf_func) (stream, " ");
    592       1.1  christos 
    593       1.1  christos 		switch (*s)
    594       1.1  christos 		  {
    595       1.1  christos 		  case '+':
    596       1.1  christos 		    found_plus = 1;
    597       1.1  christos 		    /* Fall through.  */
    598       1.1  christos 
    599       1.1  christos 		  default:
    600       1.1  christos 		    (*info->fprintf_func) (stream, "%c", *s);
    601       1.1  christos 		    break;
    602       1.1  christos 
    603       1.1  christos 		  case '#':
    604       1.1  christos 		    (*info->fprintf_func) (stream, "0");
    605       1.1  christos 		    break;
    606       1.1  christos 
    607       1.1  christos #define	reg(n)	(*info->fprintf_func) (stream, "%%%s", reg_names[n])
    608       1.1  christos 		  case '1':
    609       1.1  christos 		  case 'r':
    610       1.1  christos 		    reg (X_RS1 (insn));
    611       1.1  christos 		    break;
    612       1.1  christos 
    613       1.1  christos 		  case '2':
    614       1.1  christos 		  case 'O':
    615       1.1  christos 		    reg (X_RS2 (insn));
    616       1.1  christos 		    break;
    617       1.1  christos 
    618       1.1  christos 		  case 'd':
    619       1.1  christos 		    reg (X_RD (insn));
    620       1.1  christos 		    break;
    621       1.1  christos #undef	reg
    622       1.1  christos 
    623       1.1  christos #define	freg(n)		(*info->fprintf_func) (stream, "%%%s", freg_names[n])
    624       1.1  christos #define	fregx(n)	(*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
    625       1.1  christos 		  case 'e':
    626       1.1  christos 		    freg (X_RS1 (insn));
    627       1.1  christos 		    break;
    628       1.1  christos 		  case 'v':	/* Double/even.  */
    629       1.1  christos 		  case 'V':	/* Quad/multiple of 4.  */
    630   1.1.1.7  christos                   case ';':	/* Double/even multiple of 8 doubles.  */
    631       1.1  christos 		    fregx (X_RS1 (insn));
    632       1.1  christos 		    break;
    633       1.1  christos 
    634       1.1  christos 		  case 'f':
    635       1.1  christos 		    freg (X_RS2 (insn));
    636       1.1  christos 		    break;
    637       1.1  christos 		  case 'B':	/* Double/even.  */
    638       1.1  christos 		  case 'R':	/* Quad/multiple of 4.  */
    639   1.1.1.7  christos                   case ':':	/* Double/even multiple of 8 doubles.  */
    640       1.1  christos 		    fregx (X_RS2 (insn));
    641       1.1  christos 		    break;
    642       1.1  christos 
    643   1.1.1.2  christos 		  case '4':
    644   1.1.1.2  christos 		    freg (X_RS3 (insn));
    645   1.1.1.2  christos 		    break;
    646   1.1.1.2  christos 		  case '5':	/* Double/even.  */
    647   1.1.1.2  christos 		    fregx (X_RS3 (insn));
    648   1.1.1.2  christos 		    break;
    649   1.1.1.2  christos 
    650       1.1  christos 		  case 'g':
    651       1.1  christos 		    freg (X_RD (insn));
    652       1.1  christos 		    break;
    653       1.1  christos 		  case 'H':	/* Double/even.  */
    654       1.1  christos 		  case 'J':	/* Quad/multiple of 4.  */
    655   1.1.1.4  christos 		  case '}':     /* Double/even.  */
    656       1.1  christos 		    fregx (X_RD (insn));
    657       1.1  christos 		    break;
    658   1.1.1.7  christos 
    659   1.1.1.7  christos                   case '^':	/* Double/even multiple of 8 doubles.  */
    660   1.1.1.7  christos                     fregx (X_RD (insn) & ~0x6);
    661   1.1.1.7  christos                     break;
    662   1.1.1.7  christos 
    663   1.1.1.7  christos                   case '\'':	/* Double/even in FPCMPSHL.  */
    664   1.1.1.7  christos                     fregx (X_RS2 (insn | 0x11));
    665   1.1.1.7  christos                     break;
    666   1.1.1.7  christos 
    667       1.1  christos #undef	freg
    668       1.1  christos #undef	fregx
    669       1.1  christos 
    670       1.1  christos #define	creg(n)	(*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
    671       1.1  christos 		  case 'b':
    672       1.1  christos 		    creg (X_RS1 (insn));
    673       1.1  christos 		    break;
    674       1.1  christos 
    675       1.1  christos 		  case 'c':
    676       1.1  christos 		    creg (X_RS2 (insn));
    677       1.1  christos 		    break;
    678       1.1  christos 
    679       1.1  christos 		  case 'D':
    680       1.1  christos 		    creg (X_RD (insn));
    681       1.1  christos 		    break;
    682       1.1  christos #undef	creg
    683       1.1  christos 
    684       1.1  christos 		  case 'h':
    685       1.1  christos 		    (*info->fprintf_func) (stream, "%%hi(%#x)",
    686   1.1.1.8  christos 					   (unsigned) X_IMM22 (insn) << 10);
    687       1.1  christos 		    break;
    688       1.1  christos 
    689       1.1  christos 		  case 'i':	/* 13 bit immediate.  */
    690       1.1  christos 		  case 'I':	/* 11 bit immediate.  */
    691       1.1  christos 		  case 'j':	/* 10 bit immediate.  */
    692       1.1  christos 		    {
    693       1.1  christos 		      int imm;
    694       1.1  christos 
    695       1.1  christos 		      if (*s == 'i')
    696       1.1  christos 		        imm = X_SIMM (insn, 13);
    697       1.1  christos 		      else if (*s == 'I')
    698       1.1  christos 			imm = X_SIMM (insn, 11);
    699       1.1  christos 		      else
    700       1.1  christos 			imm = X_SIMM (insn, 10);
    701       1.1  christos 
    702       1.1  christos 		      /* Check to see whether we have a 1+i, and take
    703       1.1  christos 			 note of that fact.
    704       1.1  christos 
    705       1.1  christos 			 Note: because of the way we sort the table,
    706       1.1  christos 			 we will be matching 1+i rather than i+1,
    707       1.1  christos 			 so it is OK to assume that i is after +,
    708       1.1  christos 			 not before it.  */
    709       1.1  christos 		      if (found_plus)
    710       1.1  christos 			imm_added_to_rs1 = 1;
    711       1.1  christos 
    712       1.1  christos 		      if (imm <= 9)
    713       1.1  christos 			(*info->fprintf_func) (stream, "%d", imm);
    714       1.1  christos 		      else
    715       1.1  christos 			(*info->fprintf_func) (stream, "%#x", imm);
    716       1.1  christos 		    }
    717       1.1  christos 		    break;
    718       1.1  christos 
    719   1.1.1.2  christos 		  case ')':	/* 5 bit unsigned immediate from RS3.  */
    720   1.1.1.2  christos 		    (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
    721   1.1.1.2  christos 		    break;
    722   1.1.1.2  christos 
    723       1.1  christos 		  case 'X':	/* 5 bit unsigned immediate.  */
    724       1.1  christos 		  case 'Y':	/* 6 bit unsigned immediate.  */
    725       1.1  christos 		    {
    726       1.1  christos 		      int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
    727       1.1  christos 
    728       1.1  christos 		      if (imm <= 9)
    729       1.1  christos 			(info->fprintf_func) (stream, "%d", imm);
    730       1.1  christos 		      else
    731       1.1  christos 			(info->fprintf_func) (stream, "%#x", (unsigned) imm);
    732       1.1  christos 		    }
    733       1.1  christos 		    break;
    734       1.1  christos 
    735       1.1  christos 		  case '3':
    736       1.1  christos 		    (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
    737       1.1  christos 		    break;
    738       1.1  christos 
    739       1.1  christos 		  case 'K':
    740       1.1  christos 		    {
    741       1.1  christos 		      int mask = X_MEMBAR (insn);
    742       1.1  christos 		      int bit = 0x40, printed_one = 0;
    743       1.1  christos 		      const char *name;
    744       1.1  christos 
    745       1.1  christos 		      if (mask == 0)
    746       1.1  christos 			(info->fprintf_func) (stream, "0");
    747       1.1  christos 		      else
    748       1.1  christos 			while (bit)
    749       1.1  christos 			  {
    750       1.1  christos 			    if (mask & bit)
    751       1.1  christos 			      {
    752       1.1  christos 				if (printed_one)
    753       1.1  christos 				  (info->fprintf_func) (stream, "|");
    754       1.1  christos 				name = sparc_decode_membar (bit);
    755       1.1  christos 				(info->fprintf_func) (stream, "%s", name);
    756       1.1  christos 				printed_one = 1;
    757       1.1  christos 			      }
    758       1.1  christos 			    bit >>= 1;
    759       1.1  christos 			  }
    760       1.1  christos 		      break;
    761       1.1  christos 		    }
    762       1.1  christos 
    763   1.1.1.2  christos 		  case '=':
    764   1.1.1.2  christos 		    info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
    765   1.1.1.2  christos 		    (*info->print_address_func) (info->target, info);
    766   1.1.1.2  christos 		    break;
    767   1.1.1.2  christos 
    768       1.1  christos 		  case 'k':
    769       1.1  christos 		    info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
    770       1.1  christos 		    (*info->print_address_func) (info->target, info);
    771       1.1  christos 		    break;
    772       1.1  christos 
    773       1.1  christos 		  case 'G':
    774       1.1  christos 		    info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
    775       1.1  christos 		    (*info->print_address_func) (info->target, info);
    776       1.1  christos 		    break;
    777       1.1  christos 
    778       1.1  christos 		  case '6':
    779       1.1  christos 		  case '7':
    780       1.1  christos 		  case '8':
    781       1.1  christos 		  case '9':
    782       1.1  christos 		    (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
    783       1.1  christos 		    break;
    784       1.1  christos 
    785       1.1  christos 		  case 'z':
    786       1.1  christos 		    (*info->fprintf_func) (stream, "%%icc");
    787       1.1  christos 		    break;
    788       1.1  christos 
    789       1.1  christos 		  case 'Z':
    790       1.1  christos 		    (*info->fprintf_func) (stream, "%%xcc");
    791       1.1  christos 		    break;
    792       1.1  christos 
    793       1.1  christos 		  case 'E':
    794       1.1  christos 		    (*info->fprintf_func) (stream, "%%ccr");
    795       1.1  christos 		    break;
    796       1.1  christos 
    797       1.1  christos 		  case 's':
    798       1.1  christos 		    (*info->fprintf_func) (stream, "%%fprs");
    799       1.1  christos 		    break;
    800       1.1  christos 
    801   1.1.1.4  christos 		  case '{':
    802   1.1.1.4  christos 		    (*info->fprintf_func) (stream, "%%mcdper");
    803   1.1.1.4  christos 		    break;
    804   1.1.1.4  christos 
    805   1.1.1.7  christos                   case '&':
    806   1.1.1.7  christos                     (*info->fprintf_func) (stream, "%%entropy");
    807   1.1.1.7  christos                     break;
    808   1.1.1.7  christos 
    809       1.1  christos 		  case 'o':
    810       1.1  christos 		    (*info->fprintf_func) (stream, "%%asi");
    811       1.1  christos 		    break;
    812       1.1  christos 
    813       1.1  christos 		  case 'W':
    814       1.1  christos 		    (*info->fprintf_func) (stream, "%%tick");
    815       1.1  christos 		    break;
    816       1.1  christos 
    817       1.1  christos 		  case 'P':
    818       1.1  christos 		    (*info->fprintf_func) (stream, "%%pc");
    819       1.1  christos 		    break;
    820       1.1  christos 
    821       1.1  christos 		  case '?':
    822       1.1  christos 		    if (X_RS1 (insn) == 31)
    823       1.1  christos 		      (*info->fprintf_func) (stream, "%%ver");
    824   1.1.1.5  christos 		    else if (X_RS1 (insn) == 23)
    825   1.1.1.5  christos 		      (*info->fprintf_func) (stream, "%%pmcdper");
    826       1.1  christos 		    else if ((unsigned) X_RS1 (insn) < 17)
    827       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    828       1.1  christos 					     v9_priv_reg_names[X_RS1 (insn)]);
    829       1.1  christos 		    else
    830       1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    831       1.1  christos 		    break;
    832       1.1  christos 
    833       1.1  christos 		  case '!':
    834   1.1.1.5  christos                     if (X_RD (insn) == 31)
    835   1.1.1.5  christos                       (*info->fprintf_func) (stream, "%%ver");
    836   1.1.1.5  christos 		    else if (X_RD (insn) == 23)
    837   1.1.1.5  christos 		      (*info->fprintf_func) (stream, "%%pmcdper");
    838   1.1.1.5  christos 		    else if ((unsigned) X_RD (insn) < 17)
    839       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    840       1.1  christos 					     v9_priv_reg_names[X_RD (insn)]);
    841       1.1  christos 		    else
    842       1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    843       1.1  christos 		    break;
    844       1.1  christos 
    845       1.1  christos 		  case '$':
    846       1.1  christos 		    if ((unsigned) X_RS1 (insn) < 32)
    847       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    848       1.1  christos 					     v9_hpriv_reg_names[X_RS1 (insn)]);
    849       1.1  christos 		    else
    850       1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    851       1.1  christos 		    break;
    852       1.1  christos 
    853       1.1  christos 		  case '%':
    854       1.1  christos 		    if ((unsigned) X_RD (insn) < 32)
    855       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    856       1.1  christos 					     v9_hpriv_reg_names[X_RD (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.2  christos 		    if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
    863       1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    864       1.1  christos 		    else
    865       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    866       1.1  christos 					     v9a_asr_reg_names[X_RS1 (insn)-16]);
    867       1.1  christos 		    break;
    868       1.1  christos 
    869       1.1  christos 		  case '_':
    870   1.1.1.2  christos 		    if (X_RD (insn) < 16 || X_RD (insn) > 28)
    871       1.1  christos 		      (*info->fprintf_func) (stream, "%%reserved");
    872       1.1  christos 		    else
    873       1.1  christos 		      (*info->fprintf_func) (stream, "%%%s",
    874       1.1  christos 					     v9a_asr_reg_names[X_RD (insn)-16]);
    875       1.1  christos 		    break;
    876       1.1  christos 
    877       1.1  christos 		  case '*':
    878       1.1  christos 		    {
    879       1.1  christos 		      const char *name = sparc_decode_prefetch (X_RD (insn));
    880       1.1  christos 
    881       1.1  christos 		      if (name)
    882       1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    883       1.1  christos 		      else
    884       1.1  christos 			(*info->fprintf_func) (stream, "%ld", X_RD (insn));
    885       1.1  christos 		      break;
    886       1.1  christos 		    }
    887       1.1  christos 
    888       1.1  christos 		  case 'M':
    889       1.1  christos 		    (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
    890       1.1  christos 		    break;
    891       1.1  christos 
    892       1.1  christos 		  case 'm':
    893       1.1  christos 		    (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
    894       1.1  christos 		    break;
    895       1.1  christos 
    896       1.1  christos 		  case 'L':
    897       1.1  christos 		    info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
    898       1.1  christos 		    (*info->print_address_func) (info->target, info);
    899       1.1  christos 		    break;
    900       1.1  christos 
    901       1.1  christos 		  case 'n':
    902       1.1  christos 		    (*info->fprintf_func)
    903       1.1  christos 		      (stream, "%#x", SEX (X_DISP22 (insn), 22));
    904       1.1  christos 		    break;
    905       1.1  christos 
    906       1.1  christos 		  case 'l':
    907       1.1  christos 		    info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
    908       1.1  christos 		    (*info->print_address_func) (info->target, info);
    909       1.1  christos 		    break;
    910       1.1  christos 
    911       1.1  christos 		  case 'A':
    912       1.1  christos 		    {
    913       1.1  christos 		      const char *name = sparc_decode_asi (X_ASI (insn));
    914       1.1  christos 
    915       1.1  christos 		      if (name)
    916       1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    917       1.1  christos 		      else
    918       1.1  christos 			(*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
    919       1.1  christos 		      break;
    920       1.1  christos 		    }
    921       1.1  christos 
    922       1.1  christos 		  case 'C':
    923       1.1  christos 		    (*info->fprintf_func) (stream, "%%csr");
    924       1.1  christos 		    break;
    925       1.1  christos 
    926       1.1  christos 		  case 'F':
    927       1.1  christos 		    (*info->fprintf_func) (stream, "%%fsr");
    928       1.1  christos 		    break;
    929       1.1  christos 
    930   1.1.1.2  christos 		  case '(':
    931   1.1.1.2  christos 		    (*info->fprintf_func) (stream, "%%efsr");
    932   1.1.1.2  christos 		    break;
    933   1.1.1.2  christos 
    934       1.1  christos 		  case 'p':
    935       1.1  christos 		    (*info->fprintf_func) (stream, "%%psr");
    936       1.1  christos 		    break;
    937       1.1  christos 
    938       1.1  christos 		  case 'q':
    939       1.1  christos 		    (*info->fprintf_func) (stream, "%%fq");
    940       1.1  christos 		    break;
    941       1.1  christos 
    942       1.1  christos 		  case 'Q':
    943       1.1  christos 		    (*info->fprintf_func) (stream, "%%cq");
    944       1.1  christos 		    break;
    945       1.1  christos 
    946       1.1  christos 		  case 't':
    947       1.1  christos 		    (*info->fprintf_func) (stream, "%%tbr");
    948       1.1  christos 		    break;
    949       1.1  christos 
    950       1.1  christos 		  case 'w':
    951       1.1  christos 		    (*info->fprintf_func) (stream, "%%wim");
    952       1.1  christos 		    break;
    953       1.1  christos 
    954       1.1  christos 		  case 'x':
    955       1.1  christos 		    (*info->fprintf_func) (stream, "%ld",
    956       1.1  christos 					   ((X_LDST_I (insn) << 8)
    957       1.1  christos 					    + X_ASI (insn)));
    958       1.1  christos 		    break;
    959       1.1  christos 
    960   1.1.1.7  christos                   case '|': /* 2-bit immediate  */
    961   1.1.1.7  christos                     (*info->fprintf_func) (stream, "%ld", X_IMM2 (insn));
    962   1.1.1.7  christos                     break;
    963   1.1.1.7  christos 
    964       1.1  christos 		  case 'y':
    965       1.1  christos 		    (*info->fprintf_func) (stream, "%%y");
    966       1.1  christos 		    break;
    967       1.1  christos 
    968       1.1  christos 		  case 'u':
    969       1.1  christos 		  case 'U':
    970       1.1  christos 		    {
    971       1.1  christos 		      int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
    972       1.1  christos 		      const char *name = sparc_decode_sparclet_cpreg (val);
    973       1.1  christos 
    974       1.1  christos 		      if (name)
    975       1.1  christos 			(*info->fprintf_func) (stream, "%s", name);
    976       1.1  christos 		      else
    977       1.1  christos 			(*info->fprintf_func) (stream, "%%cpreg(%d)", val);
    978       1.1  christos 		      break;
    979       1.1  christos 		    }
    980       1.1  christos 		  }
    981       1.1  christos 	      }
    982       1.1  christos 	  }
    983       1.1  christos 
    984       1.1  christos 	  /* If we are adding or or'ing something to rs1, then
    985       1.1  christos 	     check to see whether the previous instruction was
    986       1.1  christos 	     a sethi to the same register as in the sethi.
    987       1.1  christos 	     If so, attempt to print the result of the add or
    988       1.1  christos 	     or (in this context add and or do the same thing)
    989       1.1  christos 	     and its symbolic value.  */
    990       1.1  christos 	  if (imm_ored_to_rs1 || imm_added_to_rs1)
    991       1.1  christos 	    {
    992       1.1  christos 	      unsigned long prev_insn;
    993       1.1  christos 	      int errcode;
    994       1.1  christos 
    995       1.1  christos 	      if (memaddr >= 4)
    996       1.1  christos 		errcode =
    997       1.1  christos 		  (*info->read_memory_func)
    998       1.1  christos 		  (memaddr - 4, buffer, sizeof (buffer), info);
    999       1.1  christos 	      else
   1000       1.1  christos 		errcode = 1;
   1001       1.1  christos 
   1002       1.1  christos 	      prev_insn = getword (buffer);
   1003       1.1  christos 
   1004       1.1  christos 	      if (errcode == 0)
   1005       1.1  christos 		{
   1006       1.1  christos 		  /* If it is a delayed branch, we need to look at the
   1007       1.1  christos 		     instruction before the delayed branch.  This handles
   1008       1.1  christos 		     sequences such as:
   1009       1.1  christos 
   1010       1.1  christos 		     sethi %o1, %hi(_foo), %o1
   1011       1.1  christos 		     call _printf
   1012       1.1  christos 		     or %o1, %lo(_foo), %o1  */
   1013       1.1  christos 
   1014       1.1  christos 		  if (is_delayed_branch (prev_insn))
   1015       1.1  christos 		    {
   1016       1.1  christos 		      if (memaddr >= 8)
   1017       1.1  christos 			errcode = (*info->read_memory_func)
   1018       1.1  christos 			  (memaddr - 8, buffer, sizeof (buffer), info);
   1019       1.1  christos 		      else
   1020       1.1  christos 			errcode = 1;
   1021       1.1  christos 
   1022       1.1  christos 		      prev_insn = getword (buffer);
   1023       1.1  christos 		    }
   1024       1.1  christos 		}
   1025       1.1  christos 
   1026       1.1  christos 	      /* If there was a problem reading memory, then assume
   1027       1.1  christos 		 the previous instruction was not sethi.  */
   1028       1.1  christos 	      if (errcode == 0)
   1029       1.1  christos 		{
   1030       1.1  christos 		  /* Is it sethi to the same register?  */
   1031       1.1  christos 		  if ((prev_insn & 0xc1c00000) == 0x01000000
   1032       1.1  christos 		      && X_RD (prev_insn) == X_RS1 (insn))
   1033       1.1  christos 		    {
   1034       1.1  christos 		      (*info->fprintf_func) (stream, "\t! ");
   1035   1.1.1.8  christos 		      info->target = (unsigned) X_IMM22 (prev_insn) << 10;
   1036       1.1  christos 		      if (imm_added_to_rs1)
   1037       1.1  christos 			info->target += X_SIMM (insn, 13);
   1038       1.1  christos 		      else
   1039       1.1  christos 			info->target |= X_SIMM (insn, 13);
   1040       1.1  christos 		      (*info->print_address_func) (info->target, info);
   1041       1.1  christos 		      info->insn_type = dis_dref;
   1042       1.1  christos 		      info->data_size = 4;  /* FIXME!!! */
   1043       1.1  christos 		    }
   1044       1.1  christos 		}
   1045       1.1  christos 	    }
   1046       1.1  christos 
   1047       1.1  christos 	  if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
   1048       1.1  christos 	    {
   1049       1.1  christos 	      /* FIXME -- check is_annulled flag.  */
   1050       1.1  christos 	      (void) is_annulled;
   1051       1.1  christos 	      if (opcode->flags & F_UNBR)
   1052       1.1  christos 		info->insn_type = dis_branch;
   1053       1.1  christos 	      if (opcode->flags & F_CONDBR)
   1054       1.1  christos 		info->insn_type = dis_condbranch;
   1055       1.1  christos 	      if (opcode->flags & F_JSR)
   1056       1.1  christos 		info->insn_type = dis_jsr;
   1057       1.1  christos 	      if (opcode->flags & F_DELAYED)
   1058       1.1  christos 		info->branch_delay_insns = 1;
   1059       1.1  christos 	    }
   1060       1.1  christos 
   1061       1.1  christos 	  return sizeof (buffer);
   1062       1.1  christos 	}
   1063       1.1  christos     }
   1064       1.1  christos 
   1065       1.1  christos   info->insn_type = dis_noninsn;	/* Mark as non-valid instruction.  */
   1066       1.1  christos   (*info->fprintf_func) (stream, _("unknown"));
   1067       1.1  christos   return sizeof (buffer);
   1068       1.1  christos }
   1069