fix comments and some indentation.
[platform/upstream/binutils.git] / opcodes / hppa-dis.c
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* Define this name if you want to restrict the
22    disassembler to host-native formats. */
23
24 /* #define LOCAL_ONLY 1 */ 
25
26 #include <ansidecl.h>
27 #include "sysdep.h"
28 #include "dis-asm.h"
29 #include "libhppa.h"
30 #include "opcode/hppa.h"
31
32 #ifdef LOCAL_ONLY
33 /* Needed for HP-specific architecture version numbers. */
34 #include <unistd.h>
35 #endif
36
37 /* Integer register names, indexed by the numbers which appear in the
38    opcodes.  */
39 static const char *const reg_names[] = 
40  {"flags",
41           "r1",  "rp",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8", "r9",
42   "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
43   "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
44   "sp",  "r31"};
45
46 /* Floating point register names, indexed by the numbers which appear in the
47    opcodes.  */
48 static const char *const fp_reg_names[] = 
49  {"fpsr",  "fpe2", "fpe4", "fpe6", "fr4",  "fr5",  "fr6",  "fr7",  "fr8", "fr9",
50   "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", "fr16", "fr17", "fr18", "fr19",
51   "fr20", "fr21", "fr22", "fr23", "fr24", "fr25", "fr26", "fr27", "fr28", "fr29",
52   "fr30", "fr31"};
53
54 /* (No longer) Format '-': Sign-extension completers */
55 static const char *const sign_extension_names[] = { ",u", ",s" };
56
57 /* Format '/': Deposit completers */
58 static const char *const deposit_names[] = { ",z", "" };
59
60 /* Format '}': Floating conversion types */
61 static const char *const conversion_names[] =
62                { "ff", "xf", "fx", "fxt", "", "uxf", "fxu", "fxut" };
63
64 /* Format <none yet>: Kinds of floating point test */
65 static const char *const float_test_names[] =
66                { "", ",acc",  ",rej", "", "", ",acc8", ",rej8", "",
67                  "", ",acc6", "",     "", "", ",acc4", "",      "",
68                  "", ",acc2" };
69
70 typedef unsigned int CORE_ADDR;
71
72 /* Get at various relevent fields of an instruction word. */
73
74 #define MASK_5 0x1f
75 #define MASK_11 0x7ff
76 #define MASK_14 0x3fff
77 #define MASK_21 0x1fffff
78
79 /* These macros get bit fields using HP's numbering (MSB = 0) */
80
81 /* Now defined in "libhppa.h"
82  #define GET_FIELD(X, FROM, TO) \
83   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
84   
85  #define GET_BIT( X, WHICH ) \
86   GET_FIELD( X, WHICH, WHICH )
87 */
88
89 /* Some of these have been converted to 2-d arrays because they
90    consume less storage this way.  If the maintenance becomes a
91    problem, convert them back to const 1-d pointer arrays. */
92 static const char control_reg[][6] =
93 {
94   "rctr",
95   "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
96   "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
97   "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
98   "ior", "ipsw", "eirr",
99   "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7"
100 };
101
102 static const char compare_cond_names[][5] = {
103   "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
104   ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
105   ",>>", ",nsv", ",ev"
106 };
107
108 static const char compare_cond_names_double[][6] = {
109   "*", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv",
110   ",*od", ",*tr", ",*<>", ",*>=", ",*>", ",*>>=",
111   ",*>>", ",*nsv", ",*ev"
112 };
113
114 static const char add_cond_names[][5] = {
115   "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
116   ",od", ",tr", ",<>", ",>=", ",>", ",uv",
117   ",vnz", ",nsv", ",ev"
118 };
119
120 static const char add_cond_names_double[][6] = {
121   "*", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv",
122   ",*od", ",*tr", ",*<>", ",*>=", ",*>", ",*uv",
123   ",*vnz", ",*nsv", ",*ev"
124 };
125
126 static const char *const logical_cond_names[] = {
127   "", ",=", ",<", ",<=", 0, 0, 0, ",od",
128   ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"
129 };
130
131 static const char *const logical_cond_names_double[] = {
132   "*", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
133   ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"
134 };
135 static const char *const unit_cond_names[] = {
136   "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
137   ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
138 };
139 static const char *const unit_cond_names_double[] = {
140   "*", 0, ",*sbz", ",*shz", ",*sdc", 0, ",*sbc", ",*shc",
141   ",*tr", 0, ",*nbz", ",*nhz", ",*ndc", 0, ",*nbc", ",*nhc"
142 };
143 static const char shift_cond_names[][4] = {
144   "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
145 };
146
147 static const char shift_cond_names_double[][5] = {
148   "*", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
149 };
150
151 /* Format 'c' */
152 static const char index_compl_names[][4] = {"", ",m", ",s", ",sm"};
153
154 /* Format 'C' */
155 static const char short_ldst_compl_names[][4] = {"", ",ma", ",o", ",mb"};
156
157 /* Format 'Y' */
158 static const char *const short_bytes_compl_names[] = { "", ",b,m", ",e", ",e,m" };
159
160 /* Format '$' */
161 static const char *const branch_push_pop_names[] = { "", ",pop", ",l", ",l,push" };
162
163 /* Format '=' */
164 static const char *const saturation_names[] = { ",us", ",ss", "", "" };
165
166 /* Format '3' */
167 static const char *const shift_names[] = { "", "", ",u", ",s" };
168
169 /* Format 'e' */
170 static const char *const mix_names[] = { ",l", "", ",r", "" };
171
172 static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
173
174 static const char float_comp_names[][8] =
175 {
176   ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
177   ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
178   ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
179   ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
180 };
181
182 /* For a bunch of different instructions form an index into a 
183    completer name table. */
184 #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
185                          GET_FIELD (insn, 18, 18) << 1)
186
187 /* Like GET_COMPL, but if the last five bits are 0 and the M bit is
188  * set, return "2" for ",o" */
189 #define GET_COMPL_O(insn) ( (GET_COMPL(insn) == 1) \
190                              ? ((GET_FIELD (insn, 27, 31 ) == 0) ? 2 : 1 )\
191                              : GET_COMPL(insn))
192
193 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
194                         (GET_FIELD ((insn), 19, 19) ? 8 : 0))
195
196 #define GET_PUSH_POP(insn) ((GET_BIT ((insn), 18) << 1) | GET_BIT((insn), 31))
197
198 /* Two-part register extract */
199 #define MERGED_REG(insn) ((GET_FIELD((insn), 16, 18)) << 2 | GET_FIELD((insn), 21, 22))
200
201 /* Utility function to print registers.  Put these first, so gcc's function
202    inlining can do its stuff.  */
203
204 #define fputs_filtered(STR,F)   (*info->fprintf_func) (info->stream, "%s", STR)
205
206 static void
207 fput_reg (reg, info)
208      unsigned reg;
209      disassemble_info *info;
210 {
211   (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
212 }
213
214 static void
215 fput_fp_reg (reg, info)
216      unsigned reg;
217      disassemble_info *info;
218 {
219   (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
220 }
221
222 static void
223 fput_fp_reg_r (reg, info)
224      unsigned reg;
225      disassemble_info *info;
226 {
227   /* Special case floating point exception registers.  */
228   if (reg < 4)
229     (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
230   else
231     (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg] 
232                                                     : "fr0");
233 }
234
235 static void
236 fput_creg (reg, info)
237      unsigned reg;
238      disassemble_info *info;
239 {
240   (*info->fprintf_func) (info->stream, control_reg[reg]);
241 }
242
243 /* print constants in hex with sign */
244
245 static void
246 fput_hex_const (num, info)
247      unsigned num;
248      disassemble_info *info;
249 {
250   /* Mark negative numbers as negative; only mark
251      numbers as hex if necessary. */
252   if ((int)num < 0)
253     {
254       if ((int)num > -10)
255         (*info->fprintf_func) (info->stream, "-%d", -(int)num );
256       else
257         (*info->fprintf_func) (info->stream, "-0x%x", -(int)num);
258     }
259   else if ((int)num < 10)
260     (*info->fprintf_func) (info->stream, "%d", num );
261   else
262     (*info->fprintf_func) (info->stream, "0x%x", num);
263 }
264
265 /* print constants in decimal with sign */
266
267 static void
268 fput_decimal_const (num, info)
269      unsigned num;
270      disassemble_info *info;
271 {
272   if ((int)num < 0)
273     (*info->fprintf_func) (info->stream, "-%d", -(int)num);
274   else
275     (*info->fprintf_func) (info->stream, "%d", num);
276 }
277
278 /* Routines to extract various sized constants out of hppa
279    instructions. */
280
281 /* extract a 3-bit space register number from a be, ble,
282    mtsp, pitlb or mfsp */
283 static int
284 extract_3 (word)
285      unsigned word;
286 {
287   return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
288 }
289
290 static int
291 extract_5_load (word)
292      unsigned word;
293 {
294   return low_sign_extend (word >> 16 & MASK_5, 5);
295 }
296
297 /* extract the immediate field from a st{bhw}s instruction */
298 static int
299 extract_5_store (word)
300      unsigned word;
301 {
302   return low_sign_extend (word & MASK_5, 5);
303 }
304
305 /* extract the immediate field from a break instruction */
306 static unsigned
307 extract_5r_store (word)
308      unsigned word;
309 {
310   return (word & MASK_5);
311 }
312
313 /* extract the immediate field from a {sr}sm instruction */
314 static unsigned
315 extract_5R_store (word)
316      unsigned word;
317 {
318   return (word >> 16 & MASK_5);
319 }
320
321 /* extract the immediate field from a bb instruction */
322 static unsigned
323 extract_5Q_store (word)
324      unsigned word;
325 {
326   return (word >> 21 & MASK_5);
327 }
328
329 /* extract an 11 bit immediate field */
330 static int
331 extract_11 (word)
332      unsigned word;
333 {
334   return low_sign_extend (word & MASK_11, 11);
335 }
336
337 /* extract a 14 bit immediate field */
338 static int
339 extract_14 (word)
340      unsigned word;
341 {
342   return low_sign_extend (word & MASK_14, 14);
343 }
344
345 /* extract a 21 bit constant */
346
347 static int
348 extract_21 (word)
349      unsigned word;
350 {
351   int val;
352
353   word &= MASK_21;
354   word <<= 11;
355   val = GET_FIELD (word, 20, 20);
356   val <<= 11;
357   val |= GET_FIELD (word, 9, 19);
358   val <<= 2;
359   val |= GET_FIELD (word, 5, 6);
360   val <<= 5;
361   val |= GET_FIELD (word, 0, 4);
362   val <<= 2;
363   val |= GET_FIELD (word, 7, 8);
364   return sign_extend (val, 21) << 11;
365 }
366
367 /* extract a 12 bit constant from branch instructions */
368
369 static int
370 extract_12 (word)
371      unsigned word;
372 {
373   return sign_extend (GET_FIELD (word, 19, 28) |
374                       GET_FIELD (word, 29, 29) << 10 |
375                       (word & 0x1) << 11, 12) << 2;
376 }
377
378 /* extract a 17 bit constant from branch instructions, returning the
379    19 bit signed value. */
380
381 static int
382 extract_17 (word)
383      unsigned word;
384 {
385   return sign_extend (GET_FIELD (word, 19, 28) |
386                       GET_FIELD (word, 29, 29) << 10 |
387                       GET_FIELD (word, 11, 15) << 11 |
388                       (word & 0x1) << 16, 17) << 2;
389 }
390
391 /* Print one instruction.  */
392 int
393 print_insn_hppa (memaddr, info)
394      bfd_vma memaddr;
395      disassemble_info *info;
396 {
397   bfd_byte buffer[4];
398   unsigned int insn, i;
399
400 #ifdef LOCAL_ONLY
401   static   int got_version_id = 0;
402   static   enum pa_arch pa_version;
403 #endif
404
405   /* Get the instruction to disassemble.
406    */
407   {
408     int status =
409       (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
410     if (status != 0)
411       {
412         (*info->memory_error_func) (status, memaddr, info);
413         return -1;
414       }
415   }
416   insn = bfd_getb32 (buffer);
417
418 #ifdef LOCAL_ONLY
419   /* Get the architecture version of this machine, and assume
420      it's the same as our target (this won't work for remote
421      or core debugging, nor for looking at PA2.0 binaries from
422      a 1.x machine, which is not only legal but part of our
423      test system!).  Values are:
424
425        CPU_PA_RISC1_0  0x20B
426        CPU_PA_RISC1_1  0x210
427        CPU_PA_RISC1_2  0x211
428        CPU_PA_RISC2_0  0x214
429     
430      What we really want is a way to query the bfd for the
431      architecture the binary was compiled/assembled for. */
432   if(!got_version_id)
433     {
434       int version_id;
435       
436       got_version_id = 1;
437       version_id = sysconf (_SC_CPU_VERSION);
438       switch (version_id)
439         {
440         case CPU_PA_RISC1_0 :
441         case CPU_PA_RISC1_1 :
442         case CPU_PA_RISC1_2 :
443           pa_version = pa10;
444           break;
445
446         case CPU_PA_RISC2_0 :
447           pa_version = pa20;
448           break;
449
450         default:
451           /* Now what? */
452           break;
453         }
454     }
455 #endif
456
457   /* This linear search through the opcode table is potentially
458      a bottleneck.  If it becomes one, we can use the six-bit actual
459      opcode as an index into a table of pointers to smaller tables.
460
461      A better organization might use the fact that there are only
462      about 40 distinct formats for instructions, rather than looking
463      at the hundred-plus kinds of operands. */
464   for (i = 0; i < NUMOPCODES; ++i)
465     {
466       const struct pa_opcode *opcode = &pa_opcodes[i];
467       if ((insn & opcode->mask) == opcode->match)
468         {
469           register const char *s;
470           int added_space = 0;
471
472 #ifdef LOCAL_ONLY
473           if (opcode->arch == pa20
474               && pa_version == pa10)
475               /* Target file has new architecture, host is old.
476                  This can't be a correct match, can it?
477                  NOTE: the other way is ok. */
478             continue;
479 #endif
480               
481           fputs_filtered (opcode->name, info);
482
483           for (s = opcode->args; *s != '\0'; ++s)
484             {
485               if (!added_space
486                   && 0 == strchr(completer_chars, *s))
487                 {
488                   /* This is the first non-completer.
489                      Print a space here, after all completers,
490                      before any regular operands. */
491                   fputs_filtered (" ", info);
492                   added_space = 1;
493                 }
494  
495               /* '*s' describes either an extraction and a format,
496                  or is a literal string to dump to the disassembly. */
497               switch (*s)
498                 {
499                 case 'x':
500                   fput_reg (GET_FIELD (insn, 11, 15), info);
501                   break;
502
503                 case 'X':
504                   if (GET_FIELD (insn, 25, 25))
505                     fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
506                   else
507                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
508                   break;
509
510                 case 'g':
511                   if (GET_FIELD (insn, 30, 30))
512                     fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
513                   else
514                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
515                   break;
516
517                 case 'b':
518                   fput_reg (GET_FIELD (insn, 6, 10), info);
519                   break;
520
521                 case '^':
522                   fput_creg (GET_FIELD (insn, 6, 10), info);
523                   break;
524
525                 case 'E':
526                   if (GET_FIELD (insn, 25, 25))
527                     fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
528                   else
529                     fput_fp_reg (GET_FIELD (insn, 6, 10), info);
530                   break;
531
532                 case 't':
533                   fput_reg (GET_FIELD (insn, 27, 31), info);
534                   break;
535
536                 case 'v':
537                   if (GET_FIELD (insn, 25, 25))
538                     fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
539                   else
540                     fput_fp_reg (GET_FIELD (insn, 27, 31), info);
541                   break;
542
543                 case 'y':
544                   fput_fp_reg (GET_FIELD (insn, 27, 31), info);
545                   break;
546
547                 case 'B':
548                   fput_fp_reg (GET_FIELD (insn, 11, 15), info);
549                   break;
550
551                 case '4':
552                   {
553                     int reg = GET_FIELD (insn, 6, 10);
554
555                     reg |= (GET_FIELD (insn, 26, 26) << 4);
556                     fput_fp_reg (reg, info);
557                     break;
558                   }
559
560                 case '6':
561                   {
562                     int reg = GET_FIELD (insn, 11, 15);
563
564                     reg |= (GET_FIELD (insn, 26, 26) << 4);
565                     fput_fp_reg (reg, info);
566                     break;
567                   }
568
569                 case '7':
570                   {
571                     int reg = GET_FIELD (insn, 27, 31);
572
573                     reg |= (GET_FIELD (insn, 26, 26) << 4);
574                     fput_fp_reg (reg, info);
575                     break;
576                   }
577
578                 case '8':
579                   {
580                     int reg = GET_FIELD (insn, 16, 20);
581
582                     reg |= (GET_FIELD (insn, 26, 26) << 4);
583                     fput_fp_reg (reg, info);
584                     break;
585                   }
586
587                 case '9':
588                   {
589                     int reg = GET_FIELD (insn, 21, 25);
590
591                     reg |= (GET_FIELD (insn, 26, 26) << 4);
592                     fput_fp_reg (reg, info);
593                     break;
594                   }
595
596                 case '5':
597                   fput_hex_const (extract_5_load (insn), info);
598                   break;
599
600                 case 's':
601                   (*info->fprintf_func) (info->stream,
602                                          "sr%d", GET_FIELD (insn, 16, 17));
603                   break;
604
605                 case 'S':
606                   /* Used when 'assemble_3' is specified.
607                    */
608                   (*info->fprintf_func) (info->stream, "sr%d",
609                                          extract_3 (insn));
610                   break;
611
612                 case 'c':
613                   fputs_filtered (index_compl_names[GET_COMPL (insn)], info);
614                   break;
615
616                 case 'C':
617                   fputs_filtered (short_ldst_compl_names[GET_COMPL_O (insn)], info);
618                   break;
619
620                 case 'm':
621                   fputs_filtered (short_ldst_compl_names[
622                                          (GET_BIT(insn,29) << 1 | GET_BIT(insn,28)) ],
623                                   info);
624                   break;
625
626                 case 'Y':
627                   fputs_filtered (short_bytes_compl_names[GET_COMPL (insn)], info);
628                   break;
629
630                 /* these four conditions are for the set of instructions
631                    which distinguish true/false conditions by opcode rather
632                    than by the 'f' bit (sigh): comb, comib, addb, addib */
633                 case '<':
634                   fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
635                                   info);
636                   break;
637
638                 case '?':
639                   fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
640                                   + GET_FIELD (insn, 4, 4) * 8], info);
641                   break;
642
643                 case '@':
644                   fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
645                                   + GET_FIELD (insn, 4, 4) * 8], info);
646                   break;
647
648                 case 'a':
649                   fputs_filtered (compare_cond_names[GET_COND (insn)], info);
650                   break;
651
652                 case 'd':
653                   fputs_filtered (add_cond_names[GET_COND (insn)], info);
654                   break;
655                   
656                 case '!':
657                   fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)], info);
658                   break;
659
660                 case '&':
661                   fputs_filtered (logical_cond_names[GET_COND (insn)], info);
662                   break;
663                   
664                 case 'U':
665                   fputs_filtered (unit_cond_names[GET_COND (insn)], info);
666                   break;
667                   
668                 case '|':
669                 case '>':
670                 case '~':
671                   fputs_filtered (shift_cond_names[GET_FIELD (insn, 16, 18)], info);
672                   break;
673
674                 case 'V':
675                   fput_hex_const (extract_5_store (insn), info);
676                   break;
677
678                 case 'r':
679                   fput_hex_const (extract_5r_store (insn), info);
680                   break;
681
682                 case 'R':
683                   fput_hex_const (extract_5R_store (insn), info);
684                   break;
685
686                 case 'Q':
687                   fput_hex_const (extract_5Q_store (insn), info);
688                   break;
689
690                 case 'i':
691                   fput_hex_const (extract_11 (insn), info);
692                   break;
693
694                 case 'j':
695                   fput_hex_const (extract_14 (insn), info);
696                   break;
697
698                 case 'k':
699                   fput_hex_const (extract_21 (insn), info);
700                   break;
701
702                 case 'n':
703                   if (insn & 0x2)
704                     fputs_filtered (",n", info);
705                   break;
706
707                 case 'N':
708                   if ((insn & 0x20) && s[1])
709                     fputs_filtered (",n", info);
710                   else if (insn & 0x20)
711                     fputs_filtered (",n", info);
712                   break;
713
714                 case 'w':
715                   (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
716                                                info);
717                   break;
718
719                 case 'W':
720                   /* 17 bit PC-relative branch. */
721                   (*info->print_address_func) ((memaddr + 8 
722                                                 + extract_17 (insn)),
723                                                info);
724                   break;
725
726                 case 'z':
727                   /* 17 bit displacement.  This is an offset from a register
728                      so it gets disasssembled as just a number, not any sort
729                      of address. */
730                   fput_hex_const (extract_17 (insn), info);
731                   break;
732
733                 case 'p':
734                   if( pa20 != opcode->arch ) {
735                     fput_decimal_const (31 - GET_FIELD (insn, 22, 26), info);
736                   }
737                   else {
738                     fput_decimal_const (63 - CATENATE (GET_BIT (insn, 20), 1,
739                                                        GET_FIELD (insn, 22, 26), 5),
740                                         info);
741                   }
742                   break;
743
744                 case 'P':
745                   fput_decimal_const (GET_FIELD (insn, 22, 26), info);
746                   break;
747
748                 case 'T':
749                   fput_decimal_const (32 - GET_FIELD (insn, 27, 31), info);
750                   break;
751
752                 case 'A':
753                   fput_hex_const (GET_FIELD (insn, 6, 18), info);
754                   break;
755
756                 case 'Z':
757                   if (GET_FIELD (insn, 26, 26))
758                     fputs_filtered (",m", info);
759                   break;
760
761                 case 'D':
762                   fput_hex_const (GET_FIELD (insn, 6, 31), info);
763                   break;
764
765                 case 'f':
766                   fput_decimal_const (GET_FIELD (insn, 23, 25), info);
767                   break;
768
769                 case 'O':
770                   fput_hex_const ((GET_FIELD (insn, 6,20) << 5 |
771                                GET_FIELD (insn, 27, 31)), info);
772                   break;
773
774                 case 'o':
775                   fput_hex_const (GET_FIELD (insn, 6, 20), info);
776                   break;
777
778                 case '2':
779                   fput_hex_const ((GET_FIELD (insn, 6, 22) << 5 |
780                                GET_FIELD (insn, 27, 31)), info);
781                   break;
782
783                 case '1':
784                   fput_hex_const ((GET_FIELD (insn, 11, 20) << 5 |
785                                GET_FIELD (insn, 27, 31)), info);
786                   break;
787
788                 case '0':
789                   fput_hex_const ((GET_FIELD (insn, 16, 20) << 5 |
790                                GET_FIELD (insn, 27, 31)), info);
791                   break;
792
793                 case 'u':
794                   fput_decimal_const (GET_FIELD (insn, 23, 25), info);
795                   break;
796
797                 case 'F':
798                   fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
799                                     info);
800                   break;
801
802                 case 'G':
803                   fputs_filtered (float_format_names[GET_FIELD (insn, 17, 18)], 
804                                   info);
805                   break;
806
807                 case 'H':
808                   if (GET_FIELD (insn, 26, 26) == 1)
809                     fputs_filtered (float_format_names[0], info);
810                   else
811                     fputs_filtered (float_format_names[1], info);
812                   break;
813
814                 case 'I':
815                   /* if no destination completer and not before a completer
816                      for fcmp, need a space here */
817                     fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
818                                     info);
819                   break;
820
821                 case 'J':
822                   if (GET_FIELD (insn, 24, 24))
823                     fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
824                   else
825                     fput_fp_reg (GET_FIELD (insn, 6, 10), info);
826                   break;
827
828                 case 'K':
829                   if (GET_FIELD (insn, 19, 19))
830                     fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
831                   else
832                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
833                   break;
834
835                 case 'M':
836                   fputs_filtered (float_comp_names[GET_FIELD (insn, 27, 31)], 
837                                   info);
838                   break;
839
840                 case 'L': {
841                   long temp;
842
843                   temp = GET_FIELD (insn, 18, 27) << 1;
844                   temp = assemble_16a (GET_FIELD (insn, 16, 17),
845                                        temp,
846                                        GET_BIT (insn, 31));
847                   fput_hex_const (temp, info);
848                   break;
849                   }
850
851                 case 'l': {
852                   long temp;
853
854                   temp = assemble_16a (s,
855                                        GET_FIELD (insn, 18, 28),
856                                        GET_BIT (insn, 31));
857                   fput_hex_const (temp, info);
858                   break;
859                   }
860
861                 case 'q':
862
863 /* TEMP HACK - FIXME - edie */
864                   fput_hex_const (sign_extend (GET_FIELD (insn, 20, 30), 0), info);
865                   break;
866
867                 case '#':
868                   fput_decimal_const (GET_FIELD (insn, 20, 28), info);
869                   break;
870
871                 case '$':
872                   fputs_filtered (branch_push_pop_names[GET_PUSH_POP(insn)], info);
873                   break;
874
875                 case '.':
876                   fput_creg( 11, info );      /* %cr11, printed by gdb as "sar" */
877                   break;
878
879                 case '-':
880                   /* 22 bit PC-relative branch.  */
881                   (*info->print_address_func) (memaddr + 8 +
882                                                (assemble_22 (GET_FIELD (insn,  6, 10),
883                                                              GET_FIELD (insn, 11, 15),
884                                                              GET_FIELD (insn, 19, 29),
885                                                              GET_FIELD (insn, 31, 31)) << 2), 
886                                                info);
887                   break;
888
889                 case '/':
890                   fputs_filtered (deposit_names[GET_BIT(insn,21)], info);
891                   break;
892
893                 case '*':
894 /* TEMP HACK - FIXME - edie */
895                   fput_decimal_const (sign_extend (assemble_6 (GET_BIT (insn, 23), 
896                                                                GET_FIELD (insn, 27, 31)), 0), 
897                                       info);
898                   break;
899
900                 case '[':
901 /* TEMP HACK - FIXME - edie */
902                   fput_decimal_const (sign_extend (CATENATE (GET_BIT (insn, 20), 1,
903                                                              GET_FIELD (insn, 22, 26), 5), 
904                                                    0), 
905                                       info);
906                   break;
907                   
908                 case ']':
909 /* TEMP HACK - FIXME - edie */
910                   fput_decimal_const (sign_extend (assemble_6 (GET_BIT (insn, 19), GET_FIELD (insn, 27, 31)), 0), info);
911                   break;
912
913                 case '=':
914                   fputs_filtered (saturation_names[GET_FIELD(insn,24,25)], info);
915                   break;
916
917                 case ';':
918                   /* Always positive */
919                   fput_decimal_const (GET_FIELD (insn, 24, 25), info);
920                   break;
921
922                 case ':':
923                   /* Always positive */
924                   fput_decimal_const (GET_FIELD (insn, 22, 25), info);
925                   break;
926                   
927                 case '3':
928                   fputs_filtered (shift_names[GET_FIELD(insn,20,21)], info);
929                   break;
930
931                 case '%':
932                   fputs_filtered (",", info);
933                   fput_decimal_const (GET_FIELD (insn, 17, 18), info );
934                   fput_decimal_const (GET_FIELD (insn, 20, 21), info );
935                   fput_decimal_const (GET_FIELD (insn, 22, 23), info );
936                   fput_decimal_const (GET_FIELD (insn, 24, 25), info );
937                   break;
938
939                 case 'e':
940                   fputs_filtered (mix_names[GET_FIELD(insn,17,18)], info);
941                   break;
942
943                 case '}':
944                   fputs_filtered (conversion_names[GET_FIELD(insn,14,16)], info);
945                   break;
946
947                 case 'h':
948                   fput_hex_const (GET_FIELD (insn, 6, 15), info);
949                   break;
950
951                 case '_':
952                   fput_decimal_const ((GET_FIELD (insn, 16, 18) - 1), info);
953                   break;
954
955                 case '+': {
956                   int temp = GET_FIELD (insn, 16, 18) ^ 1;
957                   
958                   if (temp == 0)
959                     /* shouldn't happen, as spec says that if
960                        this field is "1", then it's a different
961                        format. */
962                     fput_decimal_const (7, info);
963                   else
964                     fput_decimal_const (temp - 1, info);
965                   break;
966                 }
967
968                 case '{':
969                   /* Funky two-part six-bit register specifier */
970                   if (GET_BIT (insn, 23))
971                     fput_fp_reg_r (MERGED_REG (insn), info);
972                   else
973                     fput_fp_reg (MERGED_REG (insn), info);
974                   break;
975
976                 default:
977                   (*info->fprintf_func) (info->stream, "%c", *s);
978                   break;
979                 }
980             }   /* For each operand */
981             
982           return sizeof (insn);
983         }   /* If matched  */
984     }   /* For each opcode */
985
986   (*info->fprintf_func) (info->stream, "#%8x", insn);
987   return sizeof(insn);
988 }
989