Back to index

cell-binutils  2.17cvs20070401
sparc-dis.c
Go to the documentation of this file.
00001 /* Print SPARC instructions.
00002    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 2 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00018    MA 02110-1301, USA.  */
00019 
00020 #include <stdio.h>
00021 
00022 #include "sysdep.h"
00023 #include "opcode/sparc.h"
00024 #include "dis-asm.h"
00025 #include "libiberty.h"
00026 #include "opintl.h"
00027 
00028 /* Bitmask of v9 architectures.  */
00029 #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
00030                | (1 << SPARC_OPCODE_ARCH_V9A) \
00031                | (1 << SPARC_OPCODE_ARCH_V9B))
00032 /* 1 if INSN is for v9 only.  */
00033 #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
00034 /* 1 if INSN is for v9.  */
00035 #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
00036 
00037 /* The sorted opcode table.  */
00038 static const sparc_opcode **sorted_opcodes;
00039 
00040 /* For faster lookup, after insns are sorted they are hashed.  */
00041 /* ??? I think there is room for even more improvement.  */
00042 
00043 #define HASH_SIZE 256
00044 /* It is important that we only look at insn code bits as that is how the
00045    opcode table is hashed.  OPCODE_BITS is a table of valid bits for each
00046    of the main types (0,1,2,3).  */
00047 static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
00048 #define HASH_INSN(INSN) \
00049   ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
00050 typedef struct sparc_opcode_hash
00051 {
00052   struct sparc_opcode_hash *next;
00053   const sparc_opcode *opcode;
00054 } sparc_opcode_hash;
00055 
00056 static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
00057 
00058 /* Sign-extend a value which is N bits long.  */
00059 #define       SEX(value, bits) \
00060        ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
00061                       >> ((8 * sizeof (int)) - bits) )
00062 
00063 static  char *reg_names[] =
00064 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
00065   "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
00066   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
00067   "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
00068   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
00069   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00070   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
00071   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
00072   "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
00073   "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
00074   "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
00075   "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
00076 /* psr, wim, tbr, fpsr, cpsr are v8 only.  */
00077   "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
00078 };
00079 
00080 #define       freg_names    (&reg_names[4 * 8])
00081 
00082 /* These are ordered according to there register number in
00083    rdpr and wrpr insns.  */
00084 static char *v9_priv_reg_names[] =
00085 {
00086   "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
00087   "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
00088   "wstate", "fq", "gl"
00089   /* "ver" - special cased */
00090 };
00091 
00092 /* These are ordered according to there register number in
00093    rdhpr and wrhpr insns.  */
00094 static char *v9_hpriv_reg_names[] =
00095 {
00096   "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
00097   "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13", 
00098   "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
00099   "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
00100   "resv28", "resv29", "resv30", "hstick_cmpr"
00101 };
00102 
00103 /* These are ordered according to there register number in
00104    rd and wr insns (-16).  */
00105 static char *v9a_asr_reg_names[] =
00106 {
00107   "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
00108   "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr"
00109 };
00110 
00111 /* Macros used to extract instruction fields.  Not all fields have
00112    macros defined here, only those which are actually used.  */
00113 
00114 #define X_RD(i)      (((i) >> 25) & 0x1f)
00115 #define X_RS1(i)     (((i) >> 14) & 0x1f)
00116 #define X_LDST_I(i)  (((i) >> 13) & 1)
00117 #define X_ASI(i)     (((i) >> 5) & 0xff)
00118 #define X_RS2(i)     (((i) >> 0) & 0x1f)
00119 #define X_IMM(i,n)   (((i) >> 0) & ((1 << (n)) - 1))
00120 #define X_SIMM(i,n)  SEX (X_IMM ((i), (n)), (n))
00121 #define X_DISP22(i)  (((i) >> 0) & 0x3fffff)
00122 #define X_IMM22(i)   X_DISP22 (i)
00123 #define X_DISP30(i)  (((i) >> 0) & 0x3fffffff)
00124 
00125 /* These are for v9.  */
00126 #define X_DISP16(i)  (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
00127 #define X_DISP19(i)  (((i) >> 0) & 0x7ffff)
00128 #define X_MEMBAR(i)  ((i) & 0x7f)
00129 
00130 /* Here is the union which was used to extract instruction fields
00131    before the shift and mask macros were written.
00132 
00133    union sparc_insn
00134      {
00135        unsigned long int code;
00136        struct
00137         {
00138           unsigned int anop:2;
00139           #define    op     ldst.anop
00140           unsigned int anrd:5;
00141           #define    rd     ldst.anrd
00142           unsigned int op3:6;
00143           unsigned int anrs1:5;
00144           #define    rs1    ldst.anrs1
00145           unsigned int i:1;
00146           unsigned int anasi:8;
00147           #define    asi    ldst.anasi
00148           unsigned int anrs2:5;
00149           #define    rs2    ldst.anrs2
00150           #define    shcnt  rs2
00151         } ldst;
00152        struct
00153         {
00154           unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
00155           unsigned int IMM13:13;
00156           #define    imm13  IMM13.IMM13
00157         } IMM13;
00158        struct
00159         {
00160           unsigned int anop:2;
00161           unsigned int a:1;
00162           unsigned int cond:4;
00163           unsigned int op2:3;
00164           unsigned int DISP22:22;
00165           #define    disp22 branch.DISP22
00166           #define    imm22  disp22
00167         } branch;
00168        struct
00169         {
00170           unsigned int anop:2;
00171           unsigned int a:1;
00172           unsigned int z:1;
00173           unsigned int rcond:3;
00174           unsigned int op2:3;
00175           unsigned int DISP16HI:2;
00176           unsigned int p:1;
00177           unsigned int _rs1:5;
00178           unsigned int DISP16LO:14;
00179         } branch16;
00180        struct
00181         {
00182           unsigned int anop:2;
00183           unsigned int adisp30:30;
00184           #define    disp30 call.adisp30
00185         } call;
00186      };  */
00187 
00188 /* Nonzero if INSN is the opcode for a delayed branch.  */
00189 
00190 static int
00191 is_delayed_branch (unsigned long insn)
00192 {
00193   sparc_opcode_hash *op;
00194 
00195   for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
00196     {
00197       const sparc_opcode *opcode = op->opcode;
00198 
00199       if ((opcode->match & insn) == opcode->match
00200          && (opcode->lose & insn) == 0)
00201        return opcode->flags & F_DELAYED;
00202     }
00203   return 0;
00204 }
00205 
00206 /* extern void qsort (); */
00207 
00208 /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
00209    to compare_opcodes.  */
00210 static unsigned int current_arch_mask;
00211 
00212 /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values.  */
00213 
00214 static int
00215 compute_arch_mask (unsigned long mach)
00216 {
00217   switch (mach)
00218     {
00219     case 0 :
00220     case bfd_mach_sparc :
00221       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
00222     case bfd_mach_sparc_sparclet :
00223       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
00224     case bfd_mach_sparc_sparclite :
00225     case bfd_mach_sparc_sparclite_le :
00226       /* sparclites insns are recognized by default (because that's how
00227         they've always been treated, for better or worse).  Kludge this by
00228         indicating generic v8 is also selected.  */
00229       return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
00230              | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
00231     case bfd_mach_sparc_v8plus :
00232     case bfd_mach_sparc_v9 :
00233       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
00234     case bfd_mach_sparc_v8plusa :
00235     case bfd_mach_sparc_v9a :
00236       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
00237     case bfd_mach_sparc_v8plusb :
00238     case bfd_mach_sparc_v9b :
00239       return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
00240     }
00241   abort ();
00242 }
00243 
00244 /* Compare opcodes A and B.  */
00245 
00246 static int
00247 compare_opcodes (const void * a, const void * b)
00248 {
00249   sparc_opcode *op0 = * (sparc_opcode **) a;
00250   sparc_opcode *op1 = * (sparc_opcode **) b;
00251   unsigned long int match0 = op0->match, match1 = op1->match;
00252   unsigned long int lose0 = op0->lose, lose1 = op1->lose;
00253   register unsigned int i;
00254 
00255   /* If one (and only one) insn isn't supported by the current architecture,
00256      prefer the one that is.  If neither are supported, but they're both for
00257      the same architecture, continue processing.  Otherwise (both unsupported
00258      and for different architectures), prefer lower numbered arch's (fudged
00259      by comparing the bitmasks).  */
00260   if (op0->architecture & current_arch_mask)
00261     {
00262       if (! (op1->architecture & current_arch_mask))
00263        return -1;
00264     }
00265   else
00266     {
00267       if (op1->architecture & current_arch_mask)
00268        return 1;
00269       else if (op0->architecture != op1->architecture)
00270        return op0->architecture - op1->architecture;
00271     }
00272 
00273   /* If a bit is set in both match and lose, there is something
00274      wrong with the opcode table.  */
00275   if (match0 & lose0)
00276     {
00277       fprintf
00278        (stderr,
00279         /* xgettext:c-format */
00280         _("Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
00281         op0->name, match0, lose0);
00282       op0->lose &= ~op0->match;
00283       lose0 = op0->lose;
00284     }
00285 
00286   if (match1 & lose1)
00287     {
00288       fprintf
00289        (stderr,
00290         /* xgettext:c-format */
00291         _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
00292         op1->name, match1, lose1);
00293       op1->lose &= ~op1->match;
00294       lose1 = op1->lose;
00295     }
00296 
00297   /* Because the bits that are variable in one opcode are constant in
00298      another, it is important to order the opcodes in the right order.  */
00299   for (i = 0; i < 32; ++i)
00300     {
00301       unsigned long int x = 1 << i;
00302       int x0 = (match0 & x) != 0;
00303       int x1 = (match1 & x) != 0;
00304 
00305       if (x0 != x1)
00306        return x1 - x0;
00307     }
00308 
00309   for (i = 0; i < 32; ++i)
00310     {
00311       unsigned long int x = 1 << i;
00312       int x0 = (lose0 & x) != 0;
00313       int x1 = (lose1 & x) != 0;
00314 
00315       if (x0 != x1)
00316        return x1 - x0;
00317     }
00318 
00319   /* They are functionally equal.  So as long as the opcode table is
00320      valid, we can put whichever one first we want, on aesthetic grounds.  */
00321 
00322   /* Our first aesthetic ground is that aliases defer to real insns.  */
00323   {
00324     int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
00325 
00326     if (alias_diff != 0)
00327       /* Put the one that isn't an alias first.  */
00328       return alias_diff;
00329   }
00330 
00331   /* Except for aliases, two "identical" instructions had
00332      better have the same opcode.  This is a sanity check on the table.  */
00333   i = strcmp (op0->name, op1->name);
00334   if (i)
00335     {
00336       if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary.  */
00337        return i;
00338       else
00339        fprintf (stderr,
00340                /* xgettext:c-format */
00341                _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
00342                op0->name, op1->name);
00343     }
00344 
00345   /* Fewer arguments are preferred.  */
00346   {
00347     int length_diff = strlen (op0->args) - strlen (op1->args);
00348 
00349     if (length_diff != 0)
00350       /* Put the one with fewer arguments first.  */
00351       return length_diff;
00352   }
00353 
00354   /* Put 1+i before i+1.  */
00355   {
00356     char *p0 = (char *) strchr (op0->args, '+');
00357     char *p1 = (char *) strchr (op1->args, '+');
00358 
00359     if (p0 && p1)
00360       {
00361        /* There is a plus in both operands.  Note that a plus
00362           sign cannot be the first character in args,
00363           so the following [-1]'s are valid.  */
00364        if (p0[-1] == 'i' && p1[1] == 'i')
00365          /* op0 is i+1 and op1 is 1+i, so op1 goes first.  */
00366          return 1;
00367        if (p0[1] == 'i' && p1[-1] == 'i')
00368          /* op0 is 1+i and op1 is i+1, so op0 goes first.  */
00369          return -1;
00370       }
00371   }
00372 
00373   /* Put 1,i before i,1.  */
00374   {
00375     int i0 = strncmp (op0->args, "i,1", 3) == 0;
00376     int i1 = strncmp (op1->args, "i,1", 3) == 0;
00377 
00378     if (i0 ^ i1)
00379       return i0 - i1;
00380   }
00381 
00382   /* They are, as far as we can tell, identical.
00383      Since qsort may have rearranged the table partially, there is
00384      no way to tell which one was first in the opcode table as
00385      written, so just say there are equal.  */
00386   /* ??? This is no longer true now that we sort a vector of pointers,
00387      not the table itself.  */
00388   return 0;
00389 }
00390 
00391 /* Build a hash table from the opcode table.
00392    OPCODE_TABLE is a sorted list of pointers into the opcode table.  */
00393 
00394 static void
00395 build_hash_table (const sparc_opcode **opcode_table,
00396                 sparc_opcode_hash **hash_table,
00397                 int num_opcodes)
00398 {
00399   int i;
00400   int hash_count[HASH_SIZE];
00401   static sparc_opcode_hash *hash_buf = NULL;
00402 
00403   /* Start at the end of the table and work backwards so that each
00404      chain is sorted.  */
00405 
00406   memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
00407   memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
00408   if (hash_buf != NULL)
00409     free (hash_buf);
00410   hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
00411   for (i = num_opcodes - 1; i >= 0; --i)
00412     {
00413       int hash = HASH_INSN (opcode_table[i]->match);
00414       sparc_opcode_hash *h = &hash_buf[i];
00415 
00416       h->next = hash_table[hash];
00417       h->opcode = opcode_table[i];
00418       hash_table[hash] = h;
00419       ++hash_count[hash];
00420     }
00421 
00422 #if 0 /* for debugging */
00423   {
00424     int min_count = num_opcodes, max_count = 0;
00425     int total;
00426 
00427     for (i = 0; i < HASH_SIZE; ++i)
00428       {
00429         if (hash_count[i] < min_count)
00430          min_count = hash_count[i];
00431        if (hash_count[i] > max_count)
00432          max_count = hash_count[i];
00433        total += hash_count[i];
00434       }
00435 
00436     printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
00437            min_count, max_count, (double) total / HASH_SIZE);
00438   }
00439 #endif
00440 }
00441 
00442 /* Print one instruction from MEMADDR on INFO->STREAM.
00443 
00444    We suffix the instruction with a comment that gives the absolute
00445    address involved, as well as its symbolic form, if the instruction
00446    is preceded by a findable `sethi' and it either adds an immediate
00447    displacement to that register, or it is an `add' or `or' instruction
00448    on that register.  */
00449 
00450 int
00451 print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
00452 {
00453   FILE *stream = info->stream;
00454   bfd_byte buffer[4];
00455   unsigned long insn;
00456   sparc_opcode_hash *op;
00457   /* Nonzero of opcode table has been initialized.  */
00458   static int opcodes_initialized = 0;
00459   /* bfd mach number of last call.  */
00460   static unsigned long current_mach = 0;
00461   bfd_vma (*getword) (const void *);
00462 
00463   if (!opcodes_initialized
00464       || info->mach != current_mach)
00465     {
00466       int i;
00467 
00468       current_arch_mask = compute_arch_mask (info->mach);
00469 
00470       if (!opcodes_initialized)
00471        sorted_opcodes =
00472          xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
00473       /* Reset the sorted table so we can resort it.  */
00474       for (i = 0; i < sparc_num_opcodes; ++i)
00475        sorted_opcodes[i] = &sparc_opcodes[i];
00476       qsort ((char *) sorted_opcodes, sparc_num_opcodes,
00477             sizeof (sorted_opcodes[0]), compare_opcodes);
00478 
00479       build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
00480       current_mach = info->mach;
00481       opcodes_initialized = 1;
00482     }
00483 
00484   {
00485     int status =
00486       (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
00487 
00488     if (status != 0)
00489       {
00490        (*info->memory_error_func) (status, memaddr, info);
00491        return -1;
00492       }
00493   }
00494 
00495   /* On SPARClite variants such as DANlite (sparc86x), instructions
00496      are always big-endian even when the machine is in little-endian mode.  */
00497   if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
00498     getword = bfd_getb32;
00499   else
00500     getword = bfd_getl32;
00501 
00502   insn = getword (buffer);
00503 
00504   info->insn_info_valid = 1;                     /* We do return this info.  */
00505   info->insn_type = dis_nonbranch;        /* Assume non branch insn.  */
00506   info->branch_delay_insns = 0;                  /* Assume no delay.  */
00507   info->target = 0;                       /* Assume no target known.  */
00508 
00509   for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
00510     {
00511       const sparc_opcode *opcode = op->opcode;
00512 
00513       /* If the insn isn't supported by the current architecture, skip it.  */
00514       if (! (opcode->architecture & current_arch_mask))
00515        continue;
00516 
00517       if ((opcode->match & insn) == opcode->match
00518          && (opcode->lose & insn) == 0)
00519        {
00520          /* Nonzero means that we have found an instruction which has
00521             the effect of adding or or'ing the imm13 field to rs1.  */
00522          int imm_added_to_rs1 = 0;
00523          int imm_ored_to_rs1 = 0;
00524 
00525          /* Nonzero means that we have found a plus sign in the args
00526             field of the opcode table.  */
00527          int found_plus = 0;
00528 
00529          /* Nonzero means we have an annulled branch.  */
00530          int is_annulled = 0;
00531 
00532          /* Do we have an `add' or `or' instruction combining an
00533              immediate with rs1?  */
00534          if (opcode->match == 0x80102000) /* or */
00535            imm_ored_to_rs1 = 1;
00536          if (opcode->match == 0x80002000) /* add */
00537            imm_added_to_rs1 = 1;
00538 
00539          if (X_RS1 (insn) != X_RD (insn)
00540              && strchr (opcode->args, 'r') != 0)
00541              /* Can't do simple format if source and dest are different.  */
00542              continue;
00543          if (X_RS2 (insn) != X_RD (insn)
00544              && strchr (opcode->args, 'O') != 0)
00545              /* Can't do simple format if source and dest are different.  */
00546              continue;
00547 
00548          (*info->fprintf_func) (stream, opcode->name);
00549 
00550          {
00551            const char *s;
00552 
00553            if (opcode->args[0] != ',')
00554              (*info->fprintf_func) (stream, " ");
00555 
00556            for (s = opcode->args; *s != '\0'; ++s)
00557              {
00558               while (*s == ',')
00559                 {
00560                   (*info->fprintf_func) (stream, ",");
00561                   ++s;
00562                   switch (*s)
00563                     {
00564                     case 'a':
00565                      (*info->fprintf_func) (stream, "a");
00566                      is_annulled = 1;
00567                      ++s;
00568                      continue;
00569                     case 'N':
00570                      (*info->fprintf_func) (stream, "pn");
00571                      ++s;
00572                      continue;
00573 
00574                     case 'T':
00575                      (*info->fprintf_func) (stream, "pt");
00576                      ++s;
00577                      continue;
00578 
00579                     default:
00580                      break;
00581                     }
00582                 }
00583 
00584               (*info->fprintf_func) (stream, " ");
00585 
00586               switch (*s)
00587                 {
00588                 case '+':
00589                   found_plus = 1;
00590                   /* Fall through.  */
00591 
00592                 default:
00593                   (*info->fprintf_func) (stream, "%c", *s);
00594                   break;
00595 
00596                 case '#':
00597                   (*info->fprintf_func) (stream, "0");
00598                   break;
00599 
00600 #define       reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
00601                 case '1':
00602                 case 'r':
00603                   reg (X_RS1 (insn));
00604                   break;
00605 
00606                 case '2':
00607                 case 'O':
00608                   reg (X_RS2 (insn));
00609                   break;
00610 
00611                 case 'd':
00612                   reg (X_RD (insn));
00613                   break;
00614 #undef reg
00615 
00616 #define       freg(n)              (*info->fprintf_func) (stream, "%%%s", freg_names[n])
00617 #define       fregx(n)      (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
00618                 case 'e':
00619                   freg (X_RS1 (insn));
00620                   break;
00621                 case 'v':   /* Double/even.  */
00622                 case 'V':   /* Quad/multiple of 4.  */
00623                   fregx (X_RS1 (insn));
00624                   break;
00625 
00626                 case 'f':
00627                   freg (X_RS2 (insn));
00628                   break;
00629                 case 'B':   /* Double/even.  */
00630                 case 'R':   /* Quad/multiple of 4.  */
00631                   fregx (X_RS2 (insn));
00632                   break;
00633 
00634                 case 'g':
00635                   freg (X_RD (insn));
00636                   break;
00637                 case 'H':   /* Double/even.  */
00638                 case 'J':   /* Quad/multiple of 4.  */
00639                   fregx (X_RD (insn));
00640                   break;
00641 #undef freg
00642 #undef fregx
00643 
00644 #define       creg(n)       (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
00645                 case 'b':
00646                   creg (X_RS1 (insn));
00647                   break;
00648 
00649                 case 'c':
00650                   creg (X_RS2 (insn));
00651                   break;
00652 
00653                 case 'D':
00654                   creg (X_RD (insn));
00655                   break;
00656 #undef creg
00657 
00658                 case 'h':
00659                   (*info->fprintf_func) (stream, "%%hi(%#x)",
00660                                       ((unsigned) 0xFFFFFFFF
00661                                        & ((int) X_IMM22 (insn) << 10)));
00662                   break;
00663 
00664                 case 'i':   /* 13 bit immediate.  */
00665                 case 'I':   /* 11 bit immediate.  */
00666                 case 'j':   /* 10 bit immediate.  */
00667                   {
00668                     int imm;
00669 
00670                     if (*s == 'i')
00671                       imm = X_SIMM (insn, 13);
00672                     else if (*s == 'I')
00673                      imm = X_SIMM (insn, 11);
00674                     else
00675                      imm = X_SIMM (insn, 10);
00676 
00677                     /* Check to see whether we have a 1+i, and take
00678                       note of that fact.
00679 
00680                       Note: because of the way we sort the table,
00681                       we will be matching 1+i rather than i+1,
00682                       so it is OK to assume that i is after +,
00683                       not before it.  */
00684                     if (found_plus)
00685                      imm_added_to_rs1 = 1;
00686 
00687                     if (imm <= 9)
00688                      (*info->fprintf_func) (stream, "%d", imm);
00689                     else
00690                      (*info->fprintf_func) (stream, "%#x", imm);
00691                   }
00692                   break;
00693 
00694                 case 'X':   /* 5 bit unsigned immediate.  */
00695                 case 'Y':   /* 6 bit unsigned immediate.  */
00696                   {
00697                     int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
00698 
00699                     if (imm <= 9)
00700                      (info->fprintf_func) (stream, "%d", imm);
00701                     else
00702                      (info->fprintf_func) (stream, "%#x", (unsigned) imm);
00703                   }
00704                   break;
00705 
00706                 case '3':
00707                   (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
00708                   break;
00709 
00710                 case 'K':
00711                   {
00712                     int mask = X_MEMBAR (insn);
00713                     int bit = 0x40, printed_one = 0;
00714                     const char *name;
00715 
00716                     if (mask == 0)
00717                      (info->fprintf_func) (stream, "0");
00718                     else
00719                      while (bit)
00720                        {
00721                          if (mask & bit)
00722                            {
00723                             if (printed_one)
00724                               (info->fprintf_func) (stream, "|");
00725                             name = sparc_decode_membar (bit);
00726                             (info->fprintf_func) (stream, "%s", name);
00727                             printed_one = 1;
00728                            }
00729                          bit >>= 1;
00730                        }
00731                     break;
00732                   }
00733 
00734                 case 'k':
00735                   info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
00736                   (*info->print_address_func) (info->target, info);
00737                   break;
00738 
00739                 case 'G':
00740                   info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
00741                   (*info->print_address_func) (info->target, info);
00742                   break;
00743 
00744                 case '6':
00745                 case '7':
00746                 case '8':
00747                 case '9':
00748                   (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
00749                   break;
00750 
00751                 case 'z':
00752                   (*info->fprintf_func) (stream, "%%icc");
00753                   break;
00754 
00755                 case 'Z':
00756                   (*info->fprintf_func) (stream, "%%xcc");
00757                   break;
00758 
00759                 case 'E':
00760                   (*info->fprintf_func) (stream, "%%ccr");
00761                   break;
00762 
00763                 case 's':
00764                   (*info->fprintf_func) (stream, "%%fprs");
00765                   break;
00766 
00767                 case 'o':
00768                   (*info->fprintf_func) (stream, "%%asi");
00769                   break;
00770 
00771                 case 'W':
00772                   (*info->fprintf_func) (stream, "%%tick");
00773                   break;
00774 
00775                 case 'P':
00776                   (*info->fprintf_func) (stream, "%%pc");
00777                   break;
00778 
00779                 case '?':
00780                   if (X_RS1 (insn) == 31)
00781                     (*info->fprintf_func) (stream, "%%ver");
00782                   else if ((unsigned) X_RS1 (insn) < 17)
00783                     (*info->fprintf_func) (stream, "%%%s",
00784                                         v9_priv_reg_names[X_RS1 (insn)]);
00785                   else
00786                     (*info->fprintf_func) (stream, "%%reserved");
00787                   break;
00788 
00789                 case '!':
00790                   if ((unsigned) X_RD (insn) < 17)
00791                     (*info->fprintf_func) (stream, "%%%s",
00792                                         v9_priv_reg_names[X_RD (insn)]);
00793                   else
00794                     (*info->fprintf_func) (stream, "%%reserved");
00795                   break;
00796 
00797                 case '$':
00798                   if ((unsigned) X_RS1 (insn) < 32)
00799                     (*info->fprintf_func) (stream, "%%%s",
00800                                         v9_hpriv_reg_names[X_RS1 (insn)]);
00801                   else
00802                     (*info->fprintf_func) (stream, "%%reserved");
00803                   break;
00804 
00805                 case '%':
00806                   if ((unsigned) X_RD (insn) < 32)
00807                     (*info->fprintf_func) (stream, "%%%s",
00808                                         v9_hpriv_reg_names[X_RD (insn)]);
00809                   else
00810                     (*info->fprintf_func) (stream, "%%reserved");
00811                   break;
00812 
00813                 case '/':
00814                   if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
00815                     (*info->fprintf_func) (stream, "%%reserved");
00816                   else
00817                     (*info->fprintf_func) (stream, "%%%s",
00818                                         v9a_asr_reg_names[X_RS1 (insn)-16]);
00819                   break;
00820 
00821                 case '_':
00822                   if (X_RD (insn) < 16 || X_RD (insn) > 25)
00823                     (*info->fprintf_func) (stream, "%%reserved");
00824                   else
00825                     (*info->fprintf_func) (stream, "%%%s",
00826                                         v9a_asr_reg_names[X_RD (insn)-16]);
00827                   break;
00828 
00829                 case '*':
00830                   {
00831                     const char *name = sparc_decode_prefetch (X_RD (insn));
00832 
00833                     if (name)
00834                      (*info->fprintf_func) (stream, "%s", name);
00835                     else
00836                      (*info->fprintf_func) (stream, "%ld", X_RD (insn));
00837                     break;
00838                   }
00839 
00840                 case 'M':
00841                   (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
00842                   break;
00843 
00844                 case 'm':
00845                   (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
00846                   break;
00847 
00848                 case 'L':
00849                   info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
00850                   (*info->print_address_func) (info->target, info);
00851                   break;
00852 
00853                 case 'n':
00854                   (*info->fprintf_func)
00855                     (stream, "%#x", SEX (X_DISP22 (insn), 22));
00856                   break;
00857 
00858                 case 'l':
00859                   info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
00860                   (*info->print_address_func) (info->target, info);
00861                   break;
00862 
00863                 case 'A':
00864                   {
00865                     const char *name = sparc_decode_asi (X_ASI (insn));
00866 
00867                     if (name)
00868                      (*info->fprintf_func) (stream, "%s", name);
00869                     else
00870                      (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
00871                     break;
00872                   }
00873 
00874                 case 'C':
00875                   (*info->fprintf_func) (stream, "%%csr");
00876                   break;
00877 
00878                 case 'F':
00879                   (*info->fprintf_func) (stream, "%%fsr");
00880                   break;
00881 
00882                 case 'p':
00883                   (*info->fprintf_func) (stream, "%%psr");
00884                   break;
00885 
00886                 case 'q':
00887                   (*info->fprintf_func) (stream, "%%fq");
00888                   break;
00889 
00890                 case 'Q':
00891                   (*info->fprintf_func) (stream, "%%cq");
00892                   break;
00893 
00894                 case 't':
00895                   (*info->fprintf_func) (stream, "%%tbr");
00896                   break;
00897 
00898                 case 'w':
00899                   (*info->fprintf_func) (stream, "%%wim");
00900                   break;
00901 
00902                 case 'x':
00903                   (*info->fprintf_func) (stream, "%ld",
00904                                       ((X_LDST_I (insn) << 8)
00905                                        + X_ASI (insn)));
00906                   break;
00907 
00908                 case 'y':
00909                   (*info->fprintf_func) (stream, "%%y");
00910                   break;
00911 
00912                 case 'u':
00913                 case 'U':
00914                   {
00915                     int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
00916                     const char *name = sparc_decode_sparclet_cpreg (val);
00917 
00918                     if (name)
00919                      (*info->fprintf_func) (stream, "%s", name);
00920                     else
00921                      (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
00922                     break;
00923                   }
00924                 }
00925              }
00926          }
00927 
00928          /* If we are adding or or'ing something to rs1, then
00929             check to see whether the previous instruction was
00930             a sethi to the same register as in the sethi.
00931             If so, attempt to print the result of the add or
00932             or (in this context add and or do the same thing)
00933             and its symbolic value.  */
00934          if (imm_ored_to_rs1 || imm_added_to_rs1)
00935            {
00936              unsigned long prev_insn;
00937              int errcode;
00938 
00939              if (memaddr >= 4)
00940               errcode =
00941                 (*info->read_memory_func)
00942                 (memaddr - 4, buffer, sizeof (buffer), info);
00943              else
00944               errcode = 1;
00945 
00946              prev_insn = getword (buffer);
00947 
00948              if (errcode == 0)
00949               {
00950                 /* If it is a delayed branch, we need to look at the
00951                    instruction before the delayed branch.  This handles
00952                    sequences such as:
00953 
00954                    sethi %o1, %hi(_foo), %o1
00955                    call _printf
00956                    or %o1, %lo(_foo), %o1  */
00957 
00958                 if (is_delayed_branch (prev_insn))
00959                   {
00960                     if (memaddr >= 8)
00961                      errcode = (*info->read_memory_func)
00962                        (memaddr - 8, buffer, sizeof (buffer), info);
00963                     else
00964                      errcode = 1;
00965 
00966                     prev_insn = getword (buffer);
00967                   }
00968               }
00969 
00970              /* If there was a problem reading memory, then assume
00971                the previous instruction was not sethi.  */
00972              if (errcode == 0)
00973               {
00974                 /* Is it sethi to the same register?  */
00975                 if ((prev_insn & 0xc1c00000) == 0x01000000
00976                     && X_RD (prev_insn) == X_RS1 (insn))
00977                   {
00978                     (*info->fprintf_func) (stream, "\t! ");
00979                     info->target =
00980                      ((unsigned) 0xFFFFFFFF
00981                       & ((int) X_IMM22 (prev_insn) << 10));
00982                     if (imm_added_to_rs1)
00983                      info->target += X_SIMM (insn, 13);
00984                     else
00985                      info->target |= X_SIMM (insn, 13);
00986                     (*info->print_address_func) (info->target, info);
00987                     info->insn_type = dis_dref;
00988                     info->data_size = 4;  /* FIXME!!! */
00989                   }
00990               }
00991            }
00992 
00993          if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
00994            {
00995               /* FIXME -- check is_annulled flag.  */
00996              if (opcode->flags & F_UNBR)
00997               info->insn_type = dis_branch;
00998              if (opcode->flags & F_CONDBR)
00999               info->insn_type = dis_condbranch;
01000              if (opcode->flags & F_JSR)
01001               info->insn_type = dis_jsr;
01002              if (opcode->flags & F_DELAYED)
01003               info->branch_delay_insns = 1;
01004            }
01005 
01006          return sizeof (buffer);
01007        }
01008     }
01009 
01010   info->insn_type = dis_noninsn;   /* Mark as non-valid instruction.  */
01011   (*info->fprintf_func) (stream, _("unknown"));
01012   return sizeof (buffer);
01013 }