home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / opcodes / hppa-dis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  16.7 KB  |  627 lines

  1. /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
  2.    Copyright 1989, 1990, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    Contributed by the Center for Software Science at the
  5.    University of Utah (pa-gdb-bugs@cs.utah.edu).
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "dis-asm.h"
  22. #include "sysdep.h"
  23. #include "opcode/hppa.h"
  24.  
  25. /* Initializer for an array of names of registers.
  26.    There should be NUM_REGS strings in this initializer.  */
  27.  
  28. #define REGISTER_NAMES  \
  29.  {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",        \
  30.   "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", \
  31.   "r20", "r21", "r22", "arg3", "arg2", "arg1", "arg0", "dp", "ret0", "ret1", \
  32.   "sp", "r31", "sar", "pcoqh", "pcsqh", "pcoqt", "pcsqt", \
  33.   "eiem", "iir", "isr", "ior", "ipsw", "goto", "sr4", "sr0", "sr1", "sr2", \
  34.   "sr3", "sr5", "sr6", "sr7", "cr0", "cr8", "cr9", "ccr", "cr12", "cr13", \
  35.   "cr24", "cr25", "cr26", "mpsfu_high", "mpsfu_low", "mpsfu_ovflo", "pad", \
  36.   "fpsr", "fpe1", "fpe2", "fpe3", "fpe4", "fpe5", "fpe6", "fpe7", \
  37.   "fp4", "fp5", "fp6", "fp7", "fp8", \
  38.   "fp9", "fp10", "fp11", "fp12", "fp13", "fp14", "fp15", \
  39.   "fp16", "fp17", "fp18", "fp19", "fp20", "fp21", "fp22", "fp23", \
  40.   "fp24", "fp25", "fp26", "fp27", "fp28", "fp29", "fp30", "fp31"}
  41.  
  42. static const char *const reg_names[] = REGISTER_NAMES;
  43.  
  44. typedef unsigned int CORE_ADDR;
  45.  
  46. /* Get at various relevent fields of an instruction word. */
  47.  
  48. #define MASK_5 0x1f
  49. #define MASK_11 0x7ff
  50. #define MASK_14 0x3fff
  51. #define MASK_21 0x1fffff
  52.  
  53. /* This macro gets bit fields using HP's numbering (MSB = 0) */
  54.  
  55. #define GET_FIELD(X, FROM, TO) \
  56.   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
  57.  
  58. /* Some of these have been converted to 2-d arrays because they
  59.    consume less storage this way.  If the maintenance becomes a
  60.    problem, convert them back to const 1-d pointer arrays.  */
  61. static const char control_reg[][6] = {
  62.   "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
  63.   "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
  64.   "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
  65.   "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
  66.   "tr4", "tr5", "tr6", "tr7"
  67. };
  68.  
  69. static const char compare_cond_names[][5] = {
  70.   "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
  71.   ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
  72.   ",>>", ",nsv", ",ev"
  73. };
  74. static const char add_cond_names[][5] = {
  75.   "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
  76.   ",od", ",tr", ",<>", ",>=", ",>", ",uv",
  77.   ",vnz", ",nsv", ",ev"
  78. };
  79. static const char *const logical_cond_names[] = {
  80.   "", ",=", ",<", ",<=", 0, 0, 0, ",od",
  81.   ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
  82. static const char *const unit_cond_names[] = {
  83.   "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
  84.   ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
  85. };
  86. static const char shift_cond_names[][4] = {
  87.   "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
  88. };
  89. static const char index_compl_names[][4] = {"", ",m", ",s", ",sm"};
  90. static const char short_ldst_compl_names[][4] = {"", ",ma", "", ",mb"};
  91. static const char *const short_bytes_compl_names[] = {
  92.   "", ",b,m", ",e", ",e,m"
  93. };
  94. static const char *const float_format_names[] = {",sgl", ",dbl", ",quad"};
  95. static const char float_comp_names[][8] =
  96. {
  97.   ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
  98.   ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
  99.   ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
  100.   ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
  101. };
  102.  
  103. /* For a bunch of different instructions form an index into a 
  104.    completer name table. */
  105. #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
  106.              GET_FIELD (insn, 18, 18) << 1)
  107.  
  108. #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
  109.             (GET_FIELD ((insn), 19, 19) ? 8 : 0))
  110.  
  111. /* Utility function to print registers.  Put these first, so gcc's function
  112.    inlining can do its stuff.  */
  113.  
  114. #define fputs_filtered(STR,F)    (*info->fprintf_func) (info->stream, "%s", STR)
  115.  
  116. static void
  117. fput_reg (reg, info)
  118.      unsigned reg;
  119.      disassemble_info *info;
  120. {
  121.   (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
  122. }
  123.  
  124. static void
  125. fput_reg_r (reg, info)
  126.      unsigned reg;
  127.      disassemble_info *info;
  128. {
  129.   (*info->fprintf_func) (info->stream, "%sR", reg ? reg_names[reg] : "r0");
  130. }
  131.  
  132. static void
  133. fput_creg (reg, info)
  134.      unsigned reg;
  135.      disassemble_info *info;
  136. {
  137.   (*info->fprintf_func) (info->stream, control_reg[reg]);
  138. }
  139.  
  140. /* print constants with sign */
  141.  
  142. static void
  143. fput_const (num, info)
  144.      unsigned num;
  145.      disassemble_info *info;
  146. {
  147.   if ((int)num < 0)
  148.     (*info->fprintf_func) (info->stream, "-%x", -(int)num);
  149.   else
  150.     (*info->fprintf_func) (info->stream, "%x", num);
  151. }
  152.  
  153. /* Routines to extract various sized constants out of hppa
  154.    instructions. */
  155.  
  156. /* This assumes that no garbage lies outside of the lower bits of
  157.    value. */
  158.  
  159. static int
  160. sign_extend (val, bits)
  161.      unsigned val, bits;
  162. {
  163.   return (int)(val >> (bits - 1) ? (-1 << bits) | val : val);
  164. }
  165.  
  166. /* For many immediate values the sign bit is the low bit! */
  167.  
  168. static int
  169. low_sign_extend (val, bits)
  170.      unsigned val, bits;
  171. {
  172.   return (int)((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
  173. }
  174. /* extract the immediate field from a ld{bhw}s instruction */
  175.  
  176. #if 0 /* not used */
  177. static unsigned
  178. get_field (val, from, to)
  179.      unsigned val, from, to;
  180. {
  181.   val = val >> (31 - to);
  182.   return val & ((1 << (32 - from)) - 1);
  183. }
  184.  
  185. static unsigned
  186. set_field (val, from, to, new_val)
  187.      unsigned *val, from, to, new_val;
  188. {
  189.   unsigned mask = ~((1 << (to - from + 1)) << (31 - from));
  190.   return *val = (*val & mask) | (new_val << (31 - from));
  191. }
  192. #endif
  193.  
  194. /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
  195. static int
  196. extract_3 (word)
  197.      unsigned word;
  198. {
  199.   return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
  200. }
  201.  
  202. static int
  203. extract_5_load (word)
  204.      unsigned word;
  205. {
  206.   return low_sign_extend (word >> 16 & MASK_5, 5);
  207. }
  208.  
  209. /* extract the immediate field from a st{bhw}s instruction */
  210. static int
  211. extract_5_store (word)
  212.      unsigned word;
  213. {
  214.   return low_sign_extend (word & MASK_5, 5);
  215. }
  216.  
  217. /* extract the immediate field from a break instruction */
  218. static unsigned
  219. extract_5r_store (word)
  220.      unsigned word;
  221. {
  222.   return (word & MASK_5);
  223. }
  224.  
  225. /* extract the immediate field from a {sr}sm instruction */
  226. static unsigned
  227. extract_5R_store (word)
  228.      unsigned word;
  229. {
  230.   return (word >> 16 & MASK_5);
  231. }
  232.  
  233. /* extract the immediate field from a bb instruction */
  234. static unsigned
  235. extract_5Q_store (word)
  236.      unsigned word;
  237. {
  238.   return (word >> 21 & MASK_5);
  239. }
  240.  
  241. /* extract an 11 bit immediate field */
  242. static int
  243. extract_11 (word)
  244.      unsigned word;
  245. {
  246.   return low_sign_extend (word & MASK_11, 11);
  247. }
  248.  
  249. /* extract a 14 bit immediate field */
  250. static int
  251. extract_14 (word)
  252.      unsigned word;
  253. {
  254.   return low_sign_extend (word & MASK_14, 14);
  255. }
  256.  
  257. #if 0
  258. /* deposit a 14 bit constant in a word */
  259. static unsigned
  260. deposit_14 (opnd, word)
  261.      int opnd;
  262.      unsigned word;
  263. {
  264.   unsigned sign = (opnd < 0 ? 1 : 0);
  265.  
  266.   return word | ((unsigned)opnd << 1 & MASK_14)  | sign;
  267. }
  268. #endif
  269.  
  270. /* extract a 21 bit constant */
  271.  
  272. static int
  273. extract_21 (word)
  274.      unsigned word;
  275. {
  276.   int val;
  277.  
  278.   word &= MASK_21;
  279.   word <<= 11;
  280.   val = GET_FIELD (word, 20, 20);
  281.   val <<= 11;
  282.   val |= GET_FIELD (word, 9, 19);
  283.   val <<= 2;
  284.   val |= GET_FIELD (word, 5, 6);
  285.   val <<= 5;
  286.   val |= GET_FIELD (word, 0, 4);
  287.   val <<= 2;
  288.   val |= GET_FIELD (word, 7, 8);
  289.   return sign_extend (val, 21) << 11;
  290. }
  291.  
  292. #if 0
  293. /* deposit a 21 bit constant in a word. Although 21 bit constants are
  294.    usually the top 21 bits of a 32 bit constant, we assume that only
  295.    the low 21 bits of opnd are relevant */
  296.  
  297. static unsigned
  298. deposit_21 (opnd, word)
  299.      unsigned opnd, word;
  300. {
  301.   unsigned val = 0;
  302.  
  303.   val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
  304.   val <<= 2;
  305.   val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
  306.   val <<= 2;
  307.   val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
  308.   val <<= 11;
  309.   val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
  310.   val <<= 1;
  311.   val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
  312.   return word | val;
  313. }
  314. #endif
  315.  
  316. /* extract a 12 bit constant from branch instructions */
  317.  
  318. static int
  319. extract_12 (word)
  320.      unsigned word;
  321. {
  322.   return sign_extend (GET_FIELD (word, 19, 28) |
  323.                       GET_FIELD (word, 29, 29) << 10 |
  324.                       (word & 0x1) << 11, 12) << 2;
  325. }
  326.  
  327. /* extract a 17 bit constant from branch instructions, returning the
  328.    19 bit signed value. */
  329.  
  330. static int
  331. extract_17 (word)
  332.      unsigned word;
  333. {
  334.   return sign_extend (GET_FIELD (word, 19, 28) |
  335.                       GET_FIELD (word, 29, 29) << 10 |
  336.                       GET_FIELD (word, 11, 15) << 11 |
  337.                       (word & 0x1) << 16, 17) << 2;
  338. }
  339.  
  340. /* Print one instruction.  */
  341. int
  342. print_insn_hppa (memaddr, info)
  343.      bfd_vma memaddr;
  344.      disassemble_info *info;
  345. {
  346.   unsigned int insn, i, op;
  347.   FILE *stream = info->stream;
  348.  
  349.   {
  350.     int status =
  351.       (*info->read_memory_func) (memaddr, (bfd_byte*) &insn, sizeof (insn),
  352.                  info);
  353.     if (status != 0)
  354.       {
  355.     (*info->memory_error_func) (status, memaddr, info);
  356.     return -1;
  357.       }
  358.   }
  359.  
  360.   for (i = 0; i < NUMOPCODES; ++i)
  361.     {
  362.       const struct pa_opcode *opcode = &pa_opcodes[i];
  363.       if ((insn & opcode->mask) == opcode->match)
  364.     {
  365.       register const char *s;
  366.       
  367.       (*info->fprintf_func) (info->stream, "%s", opcode->name);
  368.  
  369.       if (!strchr ("cCY<?!@-+&U>~nZFM", opcode->args[0]))
  370.         (*info->fprintf_func) (info->stream, " ");
  371.       for (s = opcode->args; *s != '\0'; ++s)
  372.         {
  373.           switch (*s)
  374.         {
  375.         case 'x':
  376.           fput_reg (GET_FIELD (insn, 11, 15), stream);
  377.           break;
  378.         case 'X':
  379.                   if (GET_FIELD (insn, 25, 25))
  380.               fput_reg_r (GET_FIELD (insn, 11, 15), stream);
  381.           else
  382.               fput_reg (GET_FIELD (insn, 11, 15), stream);
  383.           break;
  384.         case 'b':
  385.           fput_reg (GET_FIELD (insn, 6, 10), stream);
  386.           break;
  387.         case '^':
  388.           fput_creg (GET_FIELD (insn, 6, 10), stream);
  389.           break;
  390.         case 'E':
  391.                   if (GET_FIELD (insn, 25, 25))
  392.               fput_reg_r (GET_FIELD (insn, 6, 10), stream);
  393.           else
  394.               fput_reg (GET_FIELD (insn, 6, 10), stream);
  395.           break;
  396.         case 't':
  397.           fput_reg (GET_FIELD (insn, 27, 31), stream);
  398.           break;
  399.         case 'v':
  400.                   if (GET_FIELD (insn, 25, 25))
  401.               fput_reg_r (GET_FIELD (insn, 27, 31), stream);
  402.           else
  403.               fput_reg (GET_FIELD (insn, 27, 31), stream);
  404.           break;
  405.         case '4':
  406.           fput_creg (GET_FIELD (insn, 6, 10), stream);
  407.           break;
  408.         case '6':
  409.           fput_reg (GET_FIELD (insn, 11, 15), stream);
  410.           break;
  411.         case '7':
  412.           fput_reg (GET_FIELD (insn, 27, 31), stream);
  413.           break;
  414.         case '8':
  415.           fput_reg (GET_FIELD (insn, 16, 20), stream);
  416.           break;
  417.         case '9':
  418.           fput_reg (GET_FIELD (insn, 21, 25), stream);
  419.           break;
  420.         case '5':
  421.           fput_const (extract_5_load (insn), stream);
  422.           break;
  423.           /* case 's': */
  424.         case 'S':
  425.           (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
  426.           break;
  427.         case 'c':
  428.           (*info->fprintf_func) (info->stream, "%s ",
  429.                     index_compl_names[GET_COMPL (insn)]);
  430.           break;
  431.         case 'C':
  432.           (*info->fprintf_func) (info->stream, "%s ",
  433.                     short_ldst_compl_names[GET_COMPL (insn)]);
  434.           break;
  435.         case 'Y':
  436.           (*info->fprintf_func) (info->stream, "%s ",
  437.                     short_bytes_compl_names[GET_COMPL (insn)]);
  438.           break;
  439.         /* these four conditions are for the set of instructions
  440.            which distinguish true/false conditions by opcode rather
  441.            than by the 'f' bit (sigh): comb, comib, addb, addib */
  442.         case '<':
  443.           fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
  444.                   stream);
  445.           break;
  446.         case '?':
  447.           fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18) + 8],
  448.                   stream);
  449.           break;
  450.         case '!':
  451.           fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)],
  452.                   stream);
  453.           break;
  454.         case '@':
  455.           fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18) + 8],
  456.                   stream);
  457.           break;
  458.         case '-':
  459.           (*info->fprintf_func) (info->stream, "%s ",
  460.                     compare_cond_names[GET_COND (insn)]);
  461.           break;
  462.         case '+':
  463.           (*info->fprintf_func) (info->stream, "%s ",
  464.                     add_cond_names[GET_FIELD (insn, 16, 18)]);
  465.           break;
  466.  
  467.         case '&':
  468.           (*info->fprintf_func) (info->stream, "%s ",
  469.                     logical_cond_names[GET_COND (insn)]);
  470.           break;
  471.         case 'U':
  472.           (*info->fprintf_func) (info->stream, "%s ",
  473.                     unit_cond_names[GET_COND (insn)]);
  474.           break;
  475.         case '>':
  476.         case '~':
  477.           (*info->fprintf_func) (info->stream, "%s ",
  478.                     shift_cond_names[GET_FIELD (insn, 16, 18)]);
  479.           break;
  480.         case 'V':
  481.           fput_const (extract_5_store (insn), stream);
  482.           break;
  483.         case 'r':
  484.           fput_const (extract_5r_store (insn), stream);
  485.           break;
  486.         case 'R':
  487.           fput_const (extract_5R_store (insn), stream);
  488.           break;
  489.         case 'Q':
  490.           fput_const (extract_5Q_store (insn), stream);
  491.           break;
  492.         case 'i':
  493.           fput_const (extract_11 (insn), stream);
  494.           break;
  495.         case 'j':
  496.           fput_const (extract_14 (insn), stream);
  497.           break;
  498.         case 'k':
  499.           fput_const (extract_21 (insn), stream);
  500.           break;
  501.         case 'n':
  502.           if (insn & 0x2)
  503.             (*info->fprintf_func) (info->stream, ",n ");
  504.           else
  505.             (*info->fprintf_func) (info->stream, " ");
  506.           break;
  507.         case 'w':
  508.           (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
  509.                            info);
  510.           break;
  511.         case 'W':
  512.           /* don't interpret an address if it's an external branch
  513.              instruction. */
  514.           op = GET_FIELD (insn, 0, 5);
  515.           if (op != 0x38 /* be */ && op != 0x39 /* ble */)
  516.             (*info->print_address_func) ((memaddr + 8
  517.                           + extract_17 (insn)),
  518.                          info);
  519.           else
  520.             fput_const (extract_17 (insn), stream);
  521.           break;
  522.         case 'B':
  523.           {
  524.             int space = GET_FIELD (insn, 16, 17);
  525.             if (space)
  526.               (*info->fprintf_func) (info->stream, "sr%d,", space);
  527.             fput_reg (GET_FIELD (insn, 6, 10), stream);
  528.             break;
  529.           }
  530.         case 'p':
  531.           (*info->fprintf_func) (info->stream, "%d",
  532.                     31 - GET_FIELD (insn, 22, 26));
  533.           break;
  534.         case 'P':
  535.           (*info->fprintf_func) (info->stream, "%d",
  536.                     GET_FIELD (insn, 22, 26));
  537.           break;
  538.         case 'T':
  539.           (*info->fprintf_func) (info->stream, "%d",
  540.                     32 - GET_FIELD (insn, 27, 31));
  541.           break;
  542.         case 'A':
  543.           fput_const (GET_FIELD (insn, 6, 18), stream);
  544.           break;
  545.         case 'Z':
  546.           if (GET_FIELD (insn, 26, 26))
  547.             (*info->fprintf_func) (info->stream, ",m ");
  548.           else
  549.             (*info->fprintf_func) (info->stream, " ");
  550.           break;
  551.         case 'D':
  552.           fput_const (GET_FIELD (insn, 6, 31), stream);
  553.           break;
  554.         case 'f':
  555.           (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
  556.           break;
  557.         case 'O':
  558.           fput_const ((GET_FIELD (insn, 6,20) << 5 |
  559.                    GET_FIELD (insn, 27, 31)), stream);
  560.           break;
  561.         case 'o':
  562.           fput_const (GET_FIELD (insn, 6, 20), stream);
  563.           break;
  564.         case '2':
  565.           fput_const ((GET_FIELD (insn, 6, 22) << 5 |
  566.                    GET_FIELD (insn, 27, 31)), stream);
  567.           break;
  568.         case '1':
  569.           fput_const ((GET_FIELD (insn, 11, 20) << 5 |
  570.                    GET_FIELD (insn, 27, 31)), stream);
  571.           break;
  572.         case '0':
  573.           fput_const ((GET_FIELD (insn, 16, 20) << 5 |
  574.                    GET_FIELD (insn, 27, 31)), stream);
  575.           break;
  576.         case 'u':
  577.           (*info->fprintf_func) (info->stream, "%d", GET_FIELD (insn, 23, 25));
  578.           break;
  579.         case 'F':
  580.           /* if no destination completer, need a space here */
  581.           if (GET_FIELD (insn, 21, 22) == 1)
  582.             fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
  583.                     stream);
  584.           else
  585.             (*info->fprintf_func) (info->stream, "%s ",
  586.                       float_format_names[GET_FIELD
  587.                              (insn, 19, 20)]);
  588.           break;
  589.         case 'G':
  590.           (*info->fprintf_func) (info->stream, "%s ",
  591.                     float_format_names[GET_FIELD (insn,
  592.                                   17, 18)]);
  593.           break;
  594.         case 'H':
  595.             fputs_filtered (float_format_names[GET_FIELD 
  596.                                                       (insn, 26, 26)], stream);
  597.           break;
  598.         case 'M':
  599.           fputs_filtered (float_comp_names[GET_FIELD (insn, 27, 31)],
  600.                   stream);
  601.           break;
  602.         case '}':
  603.           (*info->fprintf_func) (info->stream, "fp%d", GET_FIELD (insn, 6, 10));
  604.           break;
  605.         case '|':
  606.           (*info->fprintf_func) (info->stream, "fp%d", GET_FIELD (insn, 11, 15));
  607.           break;
  608.         case '{':
  609.           if (GET_FIELD (insn, 23, 25) == 0)
  610.             (*info->fprintf_func) (info->stream, "fp%d",
  611.                       GET_FIELD (insn, 27, 31));
  612.           else
  613.             (*info->fprintf_func) (info->stream, "cp%d",
  614.                       GET_FIELD (insn, 27, 31));
  615.           break;
  616.         default:
  617.           (*info->fprintf_func) (info->stream, "%c", *s);
  618.           break;
  619.         }
  620.         }
  621.       return sizeof(insn);
  622.     }
  623.     }
  624.   (*info->fprintf_func) (info->stream, "#%8x", insn);
  625.   return sizeof(insn);
  626. }
  627.