Back to index

cell-binutils  2.17cvs20070401
hppa-dis.c
Go to the documentation of this file.
00001 /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
00002    Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003,
00003    2005 Free Software Foundation, Inc.
00004 
00005    Contributed by the Center for Software Science at the
00006    University of Utah (pa-gdb-bugs@cs.utah.edu).
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00021    MA 02110-1301, USA.  */
00022 
00023 #include "sysdep.h"
00024 #include "dis-asm.h"
00025 #include "libhppa.h"
00026 #include "opcode/hppa.h"
00027 
00028 /* Integer register names, indexed by the numbers which appear in the
00029    opcodes.  */
00030 static const char *const reg_names[] =
00031 {
00032   "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
00033   "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
00034   "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
00035   "sp", "r31"
00036 };
00037 
00038 /* Floating point register names, indexed by the numbers which appear in the
00039    opcodes.  */
00040 static const char *const fp_reg_names[] =
00041 {
00042   "fpsr", "fpe2", "fpe4", "fpe6",
00043   "fr4", "fr5", "fr6", "fr7", "fr8",
00044   "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
00045   "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
00046   "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"
00047 };
00048 
00049 typedef unsigned int CORE_ADDR;
00050 
00051 /* Get at various relevent fields of an instruction word.  */
00052 
00053 #define MASK_5  0x1f
00054 #define MASK_10 0x3ff
00055 #define MASK_11 0x7ff
00056 #define MASK_14 0x3fff
00057 #define MASK_16 0xffff
00058 #define MASK_21 0x1fffff
00059 
00060 /* These macros get bit fields using HP's numbering (MSB = 0).  */
00061 
00062 #define GET_FIELD(X, FROM, TO) \
00063   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
00064 
00065 #define GET_BIT(X, WHICH) \
00066   GET_FIELD (X, WHICH, WHICH)
00067 
00068 /* Some of these have been converted to 2-d arrays because they
00069    consume less storage this way.  If the maintenance becomes a
00070    problem, convert them back to const 1-d pointer arrays.  */
00071 static const char *const control_reg[] =
00072 {
00073   "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
00074   "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
00075   "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
00076   "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
00077   "tr4", "tr5", "tr6", "tr7"
00078 };
00079 
00080 static const char *const compare_cond_names[] =
00081 {
00082   "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
00083   ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
00084 };
00085 static const char *const compare_cond_64_names[] =
00086 {
00087   "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
00088   ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
00089 };
00090 static const char *const cmpib_cond_64_names[] =
00091 {
00092   ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
00093 };
00094 static const char *const add_cond_names[] =
00095 {
00096   "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
00097   ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
00098 };
00099 static const char *const add_cond_64_names[] =
00100 {
00101   "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
00102   ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
00103 };
00104 static const char *const wide_add_cond_names[] =
00105 {
00106   "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
00107   ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
00108 };
00109 static const char *const logical_cond_names[] =
00110 {
00111   "", ",=", ",<", ",<=", 0, 0, 0, ",od",
00112   ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
00113 static const char *const logical_cond_64_names[] =
00114 {
00115   "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
00116   ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
00117 static const char *const unit_cond_names[] =
00118 {
00119   "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
00120   ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
00121 };
00122 static const char *const unit_cond_64_names[] =
00123 {
00124   "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
00125   ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
00126 };
00127 static const char *const shift_cond_names[] =
00128 {
00129   "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
00130 };
00131 static const char *const shift_cond_64_names[] =
00132 {
00133   "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
00134 };
00135 static const char *const bb_cond_64_names[] =
00136 {
00137   ",*<", ",*>="
00138 };
00139 static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
00140 static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
00141 static const char *const short_bytes_compl_names[] =
00142 {
00143   "", ",b,m", ",e", ",e,m"
00144 };
00145 static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
00146 static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
00147 static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
00148 static const char *const float_comp_names[] =
00149 {
00150   ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
00151   ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
00152   ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
00153   ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
00154 };
00155 static const char *const signed_unsigned_names[] = {",u", ",s"};
00156 static const char *const mix_half_names[] = {",l", ",r"};
00157 static const char *const saturation_names[] = {",us", ",ss", 0, ""};
00158 static const char *const read_write_names[] = {",r", ",w"};
00159 static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
00160 
00161 /* For a bunch of different instructions form an index into a
00162    completer name table.  */
00163 #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
00164                       GET_FIELD (insn, 18, 18) << 1)
00165 
00166 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
00167                      (GET_FIELD ((insn), 19, 19) ? 8 : 0))
00168 
00169 /* Utility function to print registers.  Put these first, so gcc's function
00170    inlining can do its stuff.  */
00171 
00172 #define fputs_filtered(STR,F)      (*info->fprintf_func) (info->stream, "%s", STR)
00173 
00174 static void
00175 fput_reg (unsigned reg, disassemble_info *info)
00176 {
00177   (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
00178 }
00179 
00180 static void
00181 fput_fp_reg (unsigned reg, disassemble_info *info)
00182 {
00183   (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
00184 }
00185 
00186 static void
00187 fput_fp_reg_r (unsigned reg, disassemble_info *info)
00188 {
00189   /* Special case floating point exception registers.  */
00190   if (reg < 4)
00191     (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
00192   else
00193     (*info->fprintf_func) (info->stream, "%sR",
00194                         reg ? fp_reg_names[reg] : "fr0");
00195 }
00196 
00197 static void
00198 fput_creg (unsigned reg, disassemble_info *info)
00199 {
00200   (*info->fprintf_func) (info->stream, control_reg[reg]);
00201 }
00202 
00203 /* Print constants with sign.  */
00204 
00205 static void
00206 fput_const (unsigned num, disassemble_info *info)
00207 {
00208   if ((int) num < 0)
00209     (*info->fprintf_func) (info->stream, "-%x", - (int) num);
00210   else
00211     (*info->fprintf_func) (info->stream, "%x", num);
00212 }
00213 
00214 /* Routines to extract various sized constants out of hppa
00215    instructions.  */
00216 
00217 /* Extract a 3-bit space register number from a be, ble, mtsp or mfsp.  */
00218 static int
00219 extract_3 (unsigned word)
00220 {
00221   return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
00222 }
00223 
00224 static int
00225 extract_5_load (unsigned word)
00226 {
00227   return low_sign_extend (word >> 16 & MASK_5, 5);
00228 }
00229 
00230 /* Extract the immediate field from a st{bhw}s instruction.  */
00231 
00232 static int
00233 extract_5_store (unsigned word)
00234 {
00235   return low_sign_extend (word & MASK_5, 5);
00236 }
00237 
00238 /* Extract the immediate field from a break instruction.  */
00239 
00240 static unsigned
00241 extract_5r_store (unsigned word)
00242 {
00243   return (word & MASK_5);
00244 }
00245 
00246 /* Extract the immediate field from a {sr}sm instruction.  */
00247 
00248 static unsigned
00249 extract_5R_store (unsigned word)
00250 {
00251   return (word >> 16 & MASK_5);
00252 }
00253 
00254 /* Extract the 10 bit immediate field from a {sr}sm instruction.  */
00255 
00256 static unsigned
00257 extract_10U_store (unsigned word)
00258 {
00259   return (word >> 16 & MASK_10);
00260 }
00261 
00262 /* Extract the immediate field from a bb instruction.  */
00263 
00264 static unsigned
00265 extract_5Q_store (unsigned word)
00266 {
00267   return (word >> 21 & MASK_5);
00268 }
00269 
00270 /* Extract an 11 bit immediate field.  */
00271 
00272 static int
00273 extract_11 (unsigned word)
00274 {
00275   return low_sign_extend (word & MASK_11, 11);
00276 }
00277 
00278 /* Extract a 14 bit immediate field.  */
00279 
00280 static int
00281 extract_14 (unsigned word)
00282 {
00283   return low_sign_extend (word & MASK_14, 14);
00284 }
00285 
00286 /* Extract a 16 bit immediate field (PA2.0 wide only).  */
00287 
00288 static int
00289 extract_16 (unsigned word)
00290 {
00291   int m15, m0, m1;
00292 
00293   m0 = GET_BIT (word, 16);
00294   m1 = GET_BIT (word, 17);
00295   m15 = GET_BIT (word, 31);
00296   word = (word >> 1) & 0x1fff;
00297   word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
00298   return sign_extend (word, 16);
00299 }
00300 
00301 /* Extract a 21 bit constant.  */
00302 
00303 static int
00304 extract_21 (unsigned word)
00305 {
00306   int val;
00307 
00308   word &= MASK_21;
00309   word <<= 11;
00310   val = GET_FIELD (word, 20, 20);
00311   val <<= 11;
00312   val |= GET_FIELD (word, 9, 19);
00313   val <<= 2;
00314   val |= GET_FIELD (word, 5, 6);
00315   val <<= 5;
00316   val |= GET_FIELD (word, 0, 4);
00317   val <<= 2;
00318   val |= GET_FIELD (word, 7, 8);
00319   return sign_extend (val, 21) << 11;
00320 }
00321 
00322 /* Extract a 12 bit constant from branch instructions.  */
00323 
00324 static int
00325 extract_12 (unsigned word)
00326 {
00327   return sign_extend (GET_FIELD (word, 19, 28)
00328                     | GET_FIELD (word, 29, 29) << 10
00329                     | (word & 0x1) << 11, 12) << 2;
00330 }
00331 
00332 /* Extract a 17 bit constant from branch instructions, returning the
00333    19 bit signed value.  */
00334 
00335 static int
00336 extract_17 (unsigned word)
00337 {
00338   return sign_extend (GET_FIELD (word, 19, 28)
00339                     | GET_FIELD (word, 29, 29) << 10
00340                     | GET_FIELD (word, 11, 15) << 11
00341                     | (word & 0x1) << 16, 17) << 2;
00342 }
00343 
00344 static int
00345 extract_22 (unsigned word)
00346 {
00347   return sign_extend (GET_FIELD (word, 19, 28)
00348                     | GET_FIELD (word, 29, 29) << 10
00349                     | GET_FIELD (word, 11, 15) << 11
00350                     | GET_FIELD (word, 6, 10) << 16
00351                     | (word & 0x1) << 21, 22) << 2;
00352 }
00353 
00354 /* Print one instruction.  */
00355 
00356 int
00357 print_insn_hppa (bfd_vma memaddr, disassemble_info *info)
00358 {
00359   bfd_byte buffer[4];
00360   unsigned int insn, i;
00361 
00362   {
00363     int status =
00364       (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
00365     if (status != 0)
00366       {
00367        (*info->memory_error_func) (status, memaddr, info);
00368        return -1;
00369       }
00370   }
00371 
00372   insn = bfd_getb32 (buffer);
00373 
00374   for (i = 0; i < NUMOPCODES; ++i)
00375     {
00376       const struct pa_opcode *opcode = &pa_opcodes[i];
00377 
00378       if ((insn & opcode->mask) == opcode->match)
00379        {
00380          const char *s;
00381 #ifndef BFD64
00382          if (opcode->arch == pa20w)
00383            continue;
00384 #endif
00385          (*info->fprintf_func) (info->stream, "%s", opcode->name);
00386 
00387          if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
00388            (*info->fprintf_func) (info->stream, " ");
00389          for (s = opcode->args; *s != '\0'; ++s)
00390            {
00391              switch (*s)
00392               {
00393               case 'x':
00394                 fput_reg (GET_FIELD (insn, 11, 15), info);
00395                 break;
00396               case 'a':
00397               case 'b':
00398                 fput_reg (GET_FIELD (insn, 6, 10), info);
00399                 break;
00400               case '^':
00401                 fput_creg (GET_FIELD (insn, 6, 10), info);
00402                 break;
00403               case 't':
00404                 fput_reg (GET_FIELD (insn, 27, 31), info);
00405                 break;
00406 
00407                 /* Handle floating point registers.  */
00408               case 'f':
00409                 switch (*++s)
00410                   {
00411                   case 't':
00412                     fput_fp_reg (GET_FIELD (insn, 27, 31), info);
00413                     break;
00414                   case 'T':
00415                     if (GET_FIELD (insn, 25, 25))
00416                      fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
00417                     else
00418                      fput_fp_reg (GET_FIELD (insn, 27, 31), info);
00419                     break;
00420                   case 'a':
00421                     if (GET_FIELD (insn, 25, 25))
00422                      fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
00423                     else
00424                      fput_fp_reg (GET_FIELD (insn, 6, 10), info);
00425                     break;
00426 
00427                     /* 'fA' will not generate a space before the regsiter
00428                       name.  Normally that is fine.  Except that it
00429                       causes problems with xmpyu which has no FP format
00430                       completer.  */
00431                   case 'X':
00432                     fputs_filtered (" ", info);
00433                     /* FALLTHRU */
00434 
00435                   case 'A':
00436                     if (GET_FIELD (insn, 24, 24))
00437                      fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
00438                     else
00439                      fput_fp_reg (GET_FIELD (insn, 6, 10), info);
00440                     break;
00441                   case 'b':
00442                     if (GET_FIELD (insn, 25, 25))
00443                      fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00444                     else
00445                      fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00446                     break;
00447                   case 'B':
00448                     if (GET_FIELD (insn, 19, 19))
00449                      fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00450                     else
00451                      fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00452                     break;
00453                   case 'C':
00454                     {
00455                      int reg = GET_FIELD (insn, 21, 22);
00456                      reg |= GET_FIELD (insn, 16, 18) << 2;
00457                      if (GET_FIELD (insn, 23, 23) != 0)
00458                        fput_fp_reg_r (reg, info);
00459                      else
00460                        fput_fp_reg (reg, info);
00461                      break;
00462                     }
00463                   case 'i':
00464                     {
00465                      int reg = GET_FIELD (insn, 6, 10);
00466 
00467                      reg |= (GET_FIELD (insn, 26, 26) << 4);
00468                      fput_fp_reg (reg, info);
00469                      break;
00470                     }
00471                   case 'j':
00472                     {
00473                      int reg = GET_FIELD (insn, 11, 15);
00474 
00475                      reg |= (GET_FIELD (insn, 26, 26) << 4);
00476                      fput_fp_reg (reg, info);
00477                      break;
00478                     }
00479                   case 'k':
00480                     {
00481                      int reg = GET_FIELD (insn, 27, 31);
00482 
00483                      reg |= (GET_FIELD (insn, 26, 26) << 4);
00484                      fput_fp_reg (reg, info);
00485                      break;
00486                     }
00487                   case 'l':
00488                     {
00489                      int reg = GET_FIELD (insn, 21, 25);
00490 
00491                      reg |= (GET_FIELD (insn, 26, 26) << 4);
00492                      fput_fp_reg (reg, info);
00493                      break;
00494                     }
00495                   case 'm':
00496                     {
00497                      int reg = GET_FIELD (insn, 16, 20);
00498 
00499                      reg |= (GET_FIELD (insn, 26, 26) << 4);
00500                      fput_fp_reg (reg, info);
00501                      break;
00502                     }
00503 
00504                     /* 'fe' will not generate a space before the register
00505                       name.  Normally that is fine.  Except that it
00506                       causes problems with fstw fe,y(b) which has no FP
00507                       format completer.  */
00508                   case 'E':
00509                     fputs_filtered (" ", info);
00510                     /* FALLTHRU */
00511 
00512                   case 'e':
00513                     if (GET_FIELD (insn, 30, 30))
00514                      fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00515                     else
00516                      fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00517                     break;
00518                   case 'x':
00519                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00520                     break;
00521                   }
00522                 break;
00523 
00524               case '5':
00525                 fput_const (extract_5_load (insn), info);
00526                 break;
00527               case 's':
00528                 {
00529                   int space = GET_FIELD (insn, 16, 17);
00530                   /* Zero means implicit addressing, not use of sr0.  */
00531                   if (space != 0)
00532                     (*info->fprintf_func) (info->stream, "sr%d", space);
00533                 }
00534                 break;
00535 
00536               case 'S':
00537                 (*info->fprintf_func) (info->stream, "sr%d",
00538                                     extract_3 (insn));
00539                 break;
00540 
00541                 /* Handle completers.  */
00542               case 'c':
00543                 switch (*++s)
00544                   {
00545                   case 'x':
00546                     (*info->fprintf_func)
00547                      (info->stream, "%s",
00548                       index_compl_names[GET_COMPL (insn)]);
00549                     break;
00550                   case 'X':
00551                     (*info->fprintf_func)
00552                      (info->stream, "%s ",
00553                       index_compl_names[GET_COMPL (insn)]);
00554                     break;
00555                   case 'm':
00556                     (*info->fprintf_func)
00557                      (info->stream, "%s",
00558                       short_ldst_compl_names[GET_COMPL (insn)]);
00559                     break;
00560                   case 'M':
00561                     (*info->fprintf_func)
00562                      (info->stream, "%s ",
00563                       short_ldst_compl_names[GET_COMPL (insn)]);
00564                     break;
00565                   case 'A':
00566                     (*info->fprintf_func)
00567                      (info->stream, "%s ",
00568                       short_bytes_compl_names[GET_COMPL (insn)]);
00569                     break;
00570                   case 's':
00571                     (*info->fprintf_func)
00572                      (info->stream, "%s",
00573                       short_bytes_compl_names[GET_COMPL (insn)]);
00574                     break;
00575                   case 'c':
00576                   case 'C':
00577                     switch (GET_FIELD (insn, 20, 21))
00578                      {
00579                      case 1:
00580                        (*info->fprintf_func) (info->stream, ",bc ");
00581                        break;
00582                      case 2:
00583                        (*info->fprintf_func) (info->stream, ",sl ");
00584                        break;
00585                      default:
00586                        (*info->fprintf_func) (info->stream, " ");
00587                      }
00588                     break;
00589                   case 'd':
00590                     switch (GET_FIELD (insn, 20, 21))
00591                      {
00592                      case 1:
00593                        (*info->fprintf_func) (info->stream, ",co ");
00594                        break;
00595                      default:
00596                        (*info->fprintf_func) (info->stream, " ");
00597                      }
00598                     break;
00599                   case 'o':
00600                     (*info->fprintf_func) (info->stream, ",o");
00601                     break;
00602                   case 'g':
00603                     (*info->fprintf_func) (info->stream, ",gate");
00604                     break;
00605                   case 'p':
00606                     (*info->fprintf_func) (info->stream, ",l,push");
00607                     break;
00608                   case 'P':
00609                     (*info->fprintf_func) (info->stream, ",pop");
00610                     break;
00611                   case 'l':
00612                   case 'L':
00613                     (*info->fprintf_func) (info->stream, ",l");
00614                     break;
00615                   case 'w':
00616                     (*info->fprintf_func)
00617                      (info->stream, "%s ",
00618                       read_write_names[GET_FIELD (insn, 25, 25)]);
00619                     break;
00620                   case 'W':
00621                     (*info->fprintf_func) (info->stream, ",w ");
00622                     break;
00623                   case 'r':
00624                     if (GET_FIELD (insn, 23, 26) == 5)
00625                      (*info->fprintf_func) (info->stream, ",r");
00626                     break;
00627                   case 'Z':
00628                     if (GET_FIELD (insn, 26, 26))
00629                      (*info->fprintf_func) (info->stream, ",m ");
00630                     else
00631                      (*info->fprintf_func) (info->stream, " ");
00632                     break;
00633                   case 'i':
00634                     if (GET_FIELD (insn, 25, 25))
00635                      (*info->fprintf_func) (info->stream, ",i");
00636                     break;
00637                   case 'z':
00638                     if (!GET_FIELD (insn, 21, 21))
00639                      (*info->fprintf_func) (info->stream, ",z");
00640                     break;
00641                   case 'a':
00642                     (*info->fprintf_func)
00643                      (info->stream, "%s",
00644                       add_compl_names[GET_FIELD (insn, 20, 21)]);
00645                     break;
00646                   case 'Y':
00647                     (*info->fprintf_func)
00648                      (info->stream, ",dc%s",
00649                       add_compl_names[GET_FIELD (insn, 20, 21)]);
00650                     break;
00651                   case 'y':
00652                     (*info->fprintf_func)
00653                      (info->stream, ",c%s",
00654                       add_compl_names[GET_FIELD (insn, 20, 21)]);
00655                     break;
00656                   case 'v':
00657                     if (GET_FIELD (insn, 20, 20))
00658                      (*info->fprintf_func) (info->stream, ",tsv");
00659                     break;
00660                   case 't':
00661                     (*info->fprintf_func) (info->stream, ",tc");
00662                     if (GET_FIELD (insn, 20, 20))
00663                      (*info->fprintf_func) (info->stream, ",tsv");
00664                     break;
00665                   case 'B':
00666                     (*info->fprintf_func) (info->stream, ",db");
00667                     if (GET_FIELD (insn, 20, 20))
00668                      (*info->fprintf_func) (info->stream, ",tsv");
00669                     break;
00670                   case 'b':
00671                     (*info->fprintf_func) (info->stream, ",b");
00672                     if (GET_FIELD (insn, 20, 20))
00673                      (*info->fprintf_func) (info->stream, ",tsv");
00674                     break;
00675                   case 'T':
00676                     if (GET_FIELD (insn, 25, 25))
00677                      (*info->fprintf_func) (info->stream, ",tc");
00678                     break;
00679                   case 'S':
00680                     /* EXTRD/W has a following condition.  */
00681                     if (*(s + 1) == '?')
00682                      (*info->fprintf_func)
00683                        (info->stream, "%s",
00684                         signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
00685                     else
00686                      (*info->fprintf_func)
00687                        (info->stream, "%s ",
00688                         signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
00689                     break;
00690                   case 'h':
00691                     (*info->fprintf_func)
00692                      (info->stream, "%s",
00693                       mix_half_names[GET_FIELD (insn, 17, 17)]);
00694                     break;
00695                   case 'H':
00696                     (*info->fprintf_func)
00697                      (info->stream, "%s ",
00698                       saturation_names[GET_FIELD (insn, 24, 25)]);
00699                     break;
00700                   case '*':
00701                     (*info->fprintf_func)
00702                      (info->stream, ",%d%d%d%d ",
00703                       GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
00704                       GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
00705                     break;
00706 
00707                   case 'q':
00708                     {
00709                      int m, a;
00710 
00711                      m = GET_FIELD (insn, 28, 28);
00712                      a = GET_FIELD (insn, 29, 29);
00713 
00714                      if (m && !a)
00715                        fputs_filtered (",ma ", info);
00716                      else if (m && a)
00717                        fputs_filtered (",mb ", info);
00718                      else
00719                        fputs_filtered (" ", info);
00720                      break;
00721                     }
00722 
00723                   case 'J':
00724                     {
00725                      int opc = GET_FIELD (insn, 0, 5);
00726 
00727                      if (opc == 0x16 || opc == 0x1e)
00728                        {
00729                          if (GET_FIELD (insn, 29, 29) == 0)
00730                            fputs_filtered (",ma ", info);
00731                          else
00732                            fputs_filtered (",mb ", info);
00733                        }
00734                      else
00735                        fputs_filtered (" ", info);
00736                      break;
00737                     }
00738 
00739                   case 'e':
00740                     {
00741                      int opc = GET_FIELD (insn, 0, 5);
00742 
00743                      if (opc == 0x13 || opc == 0x1b)
00744                        {
00745                          if (GET_FIELD (insn, 18, 18) == 1)
00746                            fputs_filtered (",mb ", info);
00747                          else
00748                            fputs_filtered (",ma ", info);
00749                        }
00750                      else if (opc == 0x17 || opc == 0x1f)
00751                        {
00752                          if (GET_FIELD (insn, 31, 31) == 1)
00753                            fputs_filtered (",ma ", info);
00754                          else
00755                            fputs_filtered (",mb ", info);
00756                        }
00757                      else
00758                        fputs_filtered (" ", info);
00759 
00760                      break;
00761                     }
00762                   }
00763                 break;
00764 
00765                 /* Handle conditions.  */
00766               case '?':
00767                 {
00768                   s++;
00769                   switch (*s)
00770                     {
00771                     case 'f':
00772                      (*info->fprintf_func)
00773                        (info->stream, "%s ",
00774                         float_comp_names[GET_FIELD (insn, 27, 31)]);
00775                      break;
00776 
00777                      /* These four conditions are for the set of instructions
00778                         which distinguish true/false conditions by opcode
00779                         rather than by the 'f' bit (sigh): comb, comib,
00780                         addb, addib.  */
00781                     case 't':
00782                      fputs_filtered
00783                        (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
00784                      break;
00785                     case 'n':
00786                      fputs_filtered
00787                        (compare_cond_names[GET_FIELD (insn, 16, 18)
00788                                          + GET_FIELD (insn, 4, 4) * 8],
00789                         info);
00790                      break;
00791                     case 'N':
00792                      fputs_filtered
00793                        (compare_cond_64_names[GET_FIELD (insn, 16, 18)
00794                                            + GET_FIELD (insn, 2, 2) * 8],
00795                         info);
00796                      break;
00797                     case 'Q':
00798                      fputs_filtered
00799                        (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
00800                         info);
00801                      break;
00802                     case '@':
00803                      fputs_filtered
00804                        (add_cond_names[GET_FIELD (insn, 16, 18)
00805                                      + GET_FIELD (insn, 4, 4) * 8],
00806                         info);
00807                      break;
00808                     case 's':
00809                      (*info->fprintf_func)
00810                        (info->stream, "%s ",
00811                         compare_cond_names[GET_COND (insn)]);
00812                      break;
00813                     case 'S':
00814                      (*info->fprintf_func)
00815                        (info->stream, "%s ",
00816                         compare_cond_64_names[GET_COND (insn)]);
00817                      break;
00818                     case 'a':
00819                      (*info->fprintf_func)
00820                        (info->stream, "%s ",
00821                         add_cond_names[GET_COND (insn)]);
00822                      break;
00823                     case 'A':
00824                      (*info->fprintf_func)
00825                        (info->stream, "%s ",
00826                         add_cond_64_names[GET_COND (insn)]);
00827                      break;
00828                     case 'd':
00829                      (*info->fprintf_func)
00830                        (info->stream, "%s",
00831                         add_cond_names[GET_FIELD (insn, 16, 18)]);
00832                      break;
00833 
00834                     case 'W':
00835                      (*info->fprintf_func)
00836                        (info->stream, "%s",
00837                         wide_add_cond_names[GET_FIELD (insn, 16, 18) +
00838                                           GET_FIELD (insn, 4, 4) * 8]);
00839                      break;
00840 
00841                     case 'l':
00842                      (*info->fprintf_func)
00843                        (info->stream, "%s ",
00844                         logical_cond_names[GET_COND (insn)]);
00845                      break;
00846                     case 'L':
00847                      (*info->fprintf_func)
00848                        (info->stream, "%s ",
00849                         logical_cond_64_names[GET_COND (insn)]);
00850                      break;
00851                     case 'u':
00852                      (*info->fprintf_func)
00853                        (info->stream, "%s ",
00854                         unit_cond_names[GET_COND (insn)]);
00855                      break;
00856                     case 'U':
00857                      (*info->fprintf_func)
00858                        (info->stream, "%s ",
00859                         unit_cond_64_names[GET_COND (insn)]);
00860                      break;
00861                     case 'y':
00862                     case 'x':
00863                     case 'b':
00864                      (*info->fprintf_func)
00865                        (info->stream, "%s",
00866                         shift_cond_names[GET_FIELD (insn, 16, 18)]);
00867 
00868                      /* If the next character in args is 'n', it will handle
00869                         putting out the space.  */
00870                      if (s[1] != 'n')
00871                        (*info->fprintf_func) (info->stream, " ");
00872                      break;
00873                     case 'X':
00874                      (*info->fprintf_func)
00875                        (info->stream, "%s ",
00876                         shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
00877                      break;
00878                     case 'B':
00879                      (*info->fprintf_func)
00880                        (info->stream, "%s",
00881                         bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
00882 
00883                      /* If the next character in args is 'n', it will handle
00884                         putting out the space.  */
00885                      if (s[1] != 'n')
00886                        (*info->fprintf_func) (info->stream, " ");
00887                      break;
00888                     }
00889                   break;
00890                 }
00891 
00892               case 'V':
00893                 fput_const (extract_5_store (insn), info);
00894                 break;
00895               case 'r':
00896                 fput_const (extract_5r_store (insn), info);
00897                 break;
00898               case 'R':
00899                 fput_const (extract_5R_store (insn), info);
00900                 break;
00901               case 'U':
00902                 fput_const (extract_10U_store (insn), info);
00903                 break;
00904               case 'B':
00905               case 'Q':
00906                 fput_const (extract_5Q_store (insn), info);
00907                 break;
00908               case 'i':
00909                 fput_const (extract_11 (insn), info);
00910                 break;
00911               case 'j':
00912                 fput_const (extract_14 (insn), info);
00913                 break;
00914               case 'k':
00915                 fputs_filtered ("L%", info);
00916                 fput_const (extract_21 (insn), info);
00917                 break;
00918               case '<':
00919               case 'l':
00920                 /* 16-bit long disp., PA2.0 wide only.  */
00921                 fput_const (extract_16 (insn), info);
00922                 break;
00923               case 'n':
00924                 if (insn & 0x2)
00925                   (*info->fprintf_func) (info->stream, ",n ");
00926                 else
00927                   (*info->fprintf_func) (info->stream, " ");
00928                 break;
00929               case 'N':
00930                 if ((insn & 0x20) && s[1])
00931                   (*info->fprintf_func) (info->stream, ",n ");
00932                 else if (insn & 0x20)
00933                   (*info->fprintf_func) (info->stream, ",n");
00934                 else if (s[1])
00935                   (*info->fprintf_func) (info->stream, " ");
00936                 break;
00937               case 'w':
00938                 (*info->print_address_func)
00939                   (memaddr + 8 + extract_12 (insn), info);
00940                 break;
00941               case 'W':
00942                 /* 17 bit PC-relative branch.  */
00943                 (*info->print_address_func)
00944                   ((memaddr + 8 + extract_17 (insn)), info);
00945                 break;
00946               case 'z':
00947                 /* 17 bit displacement.  This is an offset from a register
00948                    so it gets disasssembled as just a number, not any sort
00949                    of address.  */
00950                 fput_const (extract_17 (insn), info);
00951                 break;
00952 
00953               case 'Z':
00954                 /* addil %r1 implicit output.  */
00955                 fputs_filtered ("r1", info);
00956                 break;
00957 
00958               case 'Y':
00959                 /* be,l %sr0,%r31 implicit output.  */
00960                 fputs_filtered ("sr0,r31", info);
00961                 break;
00962 
00963               case '@':
00964                 (*info->fprintf_func) (info->stream, "0");
00965                 break;
00966 
00967               case '.':
00968                 (*info->fprintf_func) (info->stream, "%d",
00969                                     GET_FIELD (insn, 24, 25));
00970                 break;
00971               case '*':
00972                 (*info->fprintf_func) (info->stream, "%d",
00973                                     GET_FIELD (insn, 22, 25));
00974                 break;
00975               case '!':
00976                 fputs_filtered ("sar", info);
00977                 break;
00978               case 'p':
00979                 (*info->fprintf_func) (info->stream, "%d",
00980                                     31 - GET_FIELD (insn, 22, 26));
00981                 break;
00982               case '~':
00983                 {
00984                   int num;
00985                   num = GET_FIELD (insn, 20, 20) << 5;
00986                   num |= GET_FIELD (insn, 22, 26);
00987                   (*info->fprintf_func) (info->stream, "%d", 63 - num);
00988                   break;
00989                 }
00990               case 'P':
00991                 (*info->fprintf_func) (info->stream, "%d",
00992                                     GET_FIELD (insn, 22, 26));
00993                 break;
00994               case 'q':
00995                 {
00996                   int num;
00997                   num = GET_FIELD (insn, 20, 20) << 5;
00998                   num |= GET_FIELD (insn, 22, 26);
00999                   (*info->fprintf_func) (info->stream, "%d", num);
01000                   break;
01001                 }
01002               case 'T':
01003                 (*info->fprintf_func) (info->stream, "%d",
01004                                     32 - GET_FIELD (insn, 27, 31));
01005                 break;
01006               case '%':
01007                 {
01008                   int num;
01009                   num = (GET_FIELD (insn, 23, 23) + 1) * 32;
01010                   num -= GET_FIELD (insn, 27, 31);
01011                   (*info->fprintf_func) (info->stream, "%d", num);
01012                   break;
01013                 }
01014               case '|':
01015                 {
01016                   int num;
01017                   num = (GET_FIELD (insn, 19, 19) + 1) * 32;
01018                   num -= GET_FIELD (insn, 27, 31);
01019                   (*info->fprintf_func) (info->stream, "%d", num);
01020                   break;
01021                 }
01022               case '$':
01023                 fput_const (GET_FIELD (insn, 20, 28), info);
01024                 break;
01025               case 'A':
01026                 fput_const (GET_FIELD (insn, 6, 18), info);
01027                 break;
01028               case 'D':
01029                 fput_const (GET_FIELD (insn, 6, 31), info);
01030                 break;
01031               case 'v':
01032                 (*info->fprintf_func) (info->stream, ",%d",
01033                                     GET_FIELD (insn, 23, 25));
01034                 break;
01035               case 'O':
01036                 fput_const ((GET_FIELD (insn, 6,20) << 5 |
01037                             GET_FIELD (insn, 27, 31)), info);
01038                 break;
01039               case 'o':
01040                 fput_const (GET_FIELD (insn, 6, 20), info);
01041                 break;
01042               case '2':
01043                 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
01044                             GET_FIELD (insn, 27, 31)), info);
01045                 break;
01046               case '1':
01047                 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
01048                             GET_FIELD (insn, 27, 31)), info);
01049                 break;
01050               case '0':
01051                 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
01052                             GET_FIELD (insn, 27, 31)), info);
01053                 break;
01054               case 'u':
01055                 (*info->fprintf_func) (info->stream, ",%d",
01056                                     GET_FIELD (insn, 23, 25));
01057                 break;
01058               case 'F':
01059                 /* If no destination completer and not before a completer
01060                    for fcmp, need a space here.  */
01061                 if (s[1] == 'G' || s[1] == '?')
01062                   fputs_filtered
01063                     (float_format_names[GET_FIELD (insn, 19, 20)], info);
01064                 else
01065                   (*info->fprintf_func)
01066                     (info->stream, "%s ",
01067                      float_format_names[GET_FIELD (insn, 19, 20)]);
01068                 break;
01069               case 'G':
01070                 (*info->fprintf_func)
01071                   (info->stream, "%s ",
01072                    float_format_names[GET_FIELD (insn, 17, 18)]);
01073                 break;
01074               case 'H':
01075                 if (GET_FIELD (insn, 26, 26) == 1)
01076                   (*info->fprintf_func) (info->stream, "%s ",
01077                                       float_format_names[0]);
01078                 else
01079                   (*info->fprintf_func) (info->stream, "%s ",
01080                                       float_format_names[1]);
01081                 break;
01082               case 'I':
01083                 /* If no destination completer and not before a completer
01084                    for fcmp, need a space here.  */
01085                 if (s[1] == '?')
01086                   fputs_filtered
01087                     (float_format_names[GET_FIELD (insn, 20, 20)], info);
01088                 else
01089                   (*info->fprintf_func)
01090                     (info->stream, "%s ",
01091                      float_format_names[GET_FIELD (insn, 20, 20)]);
01092                 break;
01093 
01094               case 'J':
01095                 fput_const (extract_14 (insn), info);
01096                 break;
01097 
01098               case '#':
01099                 {
01100                   int sign = GET_FIELD (insn, 31, 31);
01101                   int imm10 = GET_FIELD (insn, 18, 27);
01102                   int disp;
01103 
01104                   if (sign)
01105                     disp = (-1 << 10) | imm10;
01106                   else
01107                     disp = imm10;
01108 
01109                   disp <<= 3;
01110                   fput_const (disp, info);
01111                   break;
01112                 }
01113               case 'K':
01114               case 'd':
01115                 {
01116                   int sign = GET_FIELD (insn, 31, 31);
01117                   int imm11 = GET_FIELD (insn, 18, 28);
01118                   int disp;
01119 
01120                   if (sign)
01121                     disp = (-1 << 11) | imm11;
01122                   else
01123                     disp = imm11;
01124 
01125                   disp <<= 2;
01126                   fput_const (disp, info);
01127                   break;
01128                 }
01129 
01130               case '>':
01131               case 'y':
01132                 {
01133                   /* 16-bit long disp., PA2.0 wide only.  */
01134                   int disp = extract_16 (insn);
01135                   disp &= ~3;
01136                   fput_const (disp, info);
01137                   break;
01138                 }
01139 
01140               case '&':
01141                 {
01142                   /* 16-bit long disp., PA2.0 wide only.  */
01143                   int disp = extract_16 (insn);
01144                   disp &= ~7;
01145                   fput_const (disp, info);
01146                   break;
01147                 }
01148 
01149               case '_':
01150                 break; /* Dealt with by '{' */
01151 
01152               case '{':
01153                 {
01154                   int sub = GET_FIELD (insn, 14, 16);
01155                   int df = GET_FIELD (insn, 17, 18);
01156                   int sf = GET_FIELD (insn, 19, 20);
01157                   const char * const * source = float_format_names;
01158                   const char * const * dest = float_format_names;
01159                   char *t = "";
01160 
01161                   if (sub == 4)
01162                     {
01163                      fputs_filtered (",UND ", info);
01164                      break;
01165                     }
01166                   if ((sub & 3) == 3)
01167                     t = ",t";
01168                   if ((sub & 3) == 1)
01169                     source = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
01170                   if (sub & 2)
01171                     dest = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
01172 
01173                   (*info->fprintf_func) (info->stream, "%s%s%s ",
01174                                       t, source[sf], dest[df]);
01175                   break;
01176                 }
01177 
01178               case 'm':
01179                 {
01180                   int y = GET_FIELD (insn, 16, 18);
01181 
01182                   if (y != 1)
01183                     fput_const ((y ^ 1) - 1, info);
01184                 }
01185                 break;
01186 
01187               case 'h':
01188                 {
01189                   int cbit;
01190 
01191                   cbit = GET_FIELD (insn, 16, 18);
01192 
01193                   if (cbit > 0)
01194                     (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
01195                   break;
01196                 }
01197 
01198               case '=':
01199                 {
01200                   int cond = GET_FIELD (insn, 27, 31);
01201 
01202                   switch (cond)
01203                     {
01204                     case  0: fputs_filtered (" ", info); break;
01205                     case  1: fputs_filtered ("acc ", info); break;
01206                     case  2: fputs_filtered ("rej ", info); break;
01207                     case  5: fputs_filtered ("acc8 ", info); break;
01208                     case  6: fputs_filtered ("rej8 ", info); break;
01209                     case  9: fputs_filtered ("acc6 ", info); break;
01210                     case 13: fputs_filtered ("acc4 ", info); break;
01211                     case 17: fputs_filtered ("acc2 ", info); break;
01212                     default: break;
01213                     }
01214                   break;
01215                 }
01216 
01217               case 'X':
01218                 (*info->print_address_func)
01219                   (memaddr + 8 + extract_22 (insn), info);
01220                 break;
01221               case 'L':
01222                 fputs_filtered (",rp", info);
01223                 break;
01224               default:
01225                 (*info->fprintf_func) (info->stream, "%c", *s);
01226                 break;
01227               }
01228            }
01229          return sizeof (insn);
01230        }
01231     }
01232   (*info->fprintf_func) (info->stream, "#%8x", insn);
01233   return sizeof (insn);
01234 }