* "objcopy -O binary" warning tweak, suggested by dmoseley
[binutils-gdb.git] / opcodes / hppa-dis.c
blobf71221c75f1b9c8bdff28fa28d228c86c28938e4
1 /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2 Copyright 1989, 1990, 1992, 1993 Free Software Foundation, Inc.
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
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.
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.
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. */
21 /* Define this name if you want to restrict the
22 disassembler to host-native formats. */
24 /* #define LOCAL_ONLY 1 */
26 #include <ansidecl.h>
27 #include "sysdep.h"
28 #include "dis-asm.h"
29 #include "libhppa.h"
30 #include "opcode/hppa.h"
32 #ifdef LOCAL_ONLY
33 /* Needed for HP-specific architecture version numbers. */
34 #include <unistd.h>
35 #endif
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"};
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"};
54 /* (No longer) Format '-': Sign-extension completers */
55 static const char *const sign_extension_names[] = { ",u", ",s" };
57 /* Format '/': Deposit completers */
58 static const char *const deposit_names[] = { ",z", "" };
60 /* Format '}': Floating conversion types */
61 static const char *const conversion_names[] =
62 { "ff", "xf", "fx", "fxt", "", "uxf", "fxu", "fxut" };
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" };
70 typedef unsigned int CORE_ADDR;
72 /* Get at various relevent fields of an instruction word. */
74 #define MASK_5 0x1f
75 #define MASK_11 0x7ff
76 #define MASK_14 0x3fff
77 #define MASK_21 0x1fffff
79 /* These macros get bit fields using HP's numbering (MSB = 0) */
81 /* Now defined in "libhppa.h"
82 #define GET_FIELD(X, FROM, TO) \
83 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
85 #define GET_BIT( X, WHICH ) \
86 GET_FIELD( X, WHICH, WHICH )
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] =
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"
102 static const char compare_cond_names[][5] = {
103 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
104 ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
105 ",>>", ",nsv", ",ev"
108 static const char compare_cond_names_double[][6] = {
109 "*", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv",
110 ",*od", ",*tr", ",*<>", ",*>=", ",*>", ",*>>=",
111 ",*>>", ",*nsv", ",*ev"
114 static const char add_cond_names[][5] = {
115 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
116 ",od", ",tr", ",<>", ",>=", ",>", ",uv",
117 ",vnz", ",nsv", ",ev"
120 static const char add_cond_names_double[][6] = {
121 "*", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv",
122 ",*od", ",*tr", ",*<>", ",*>=", ",*>", ",*uv",
123 ",*vnz", ",*nsv", ",*ev"
126 static const char *const logical_cond_names[] = {
127 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
128 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"
131 static const char *const logical_cond_names_double[] = {
132 "*", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
133 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"
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"
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"
143 static const char shift_cond_names[][4] = {
144 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
147 static const char shift_cond_names_double[][5] = {
148 "*", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
151 /* Format 'c' */
152 static const char index_compl_names[][4] = {"", ",m", ",s", ",sm"};
154 /* Format 'C' */
155 static const char short_ldst_compl_names[][4] = {"", ",ma", ",o", ",mb"};
157 /* Format 'Y' */
158 static const char *const short_bytes_compl_names[] = { "", ",b,m", ",e", ",e,m" };
160 /* Format '$' */
161 static const char *const branch_push_pop_names[] = { "", ",pop", ",l", ",l,push" };
163 /* Format '=' */
164 static const char *const saturation_names[] = { ",us", ",ss", "", "" };
166 /* Format '3' */
167 static const char *const shift_names[] = { "", "", ",u", ",s" };
169 /* Format 'e' */
170 static const char *const mix_names[] = { ",l", "", ",r", "" };
172 static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
174 static const char float_comp_names[][8] =
176 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
177 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
178 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
179 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
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)
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))
193 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
194 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
196 #define GET_PUSH_POP(insn) ((GET_BIT ((insn), 18) << 1) | GET_BIT((insn), 31))
198 /* Two-part register extract */
199 #define MERGED_REG(insn) ((GET_FIELD((insn), 16, 18)) << 2 | GET_FIELD((insn), 21, 22))
201 /* Utility function to print registers. Put these first, so gcc's function
202 inlining can do its stuff. */
204 #define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
206 static void
207 fput_reg (reg, info)
208 unsigned reg;
209 disassemble_info *info;
211 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
214 static void
215 fput_fp_reg (reg, info)
216 unsigned reg;
217 disassemble_info *info;
219 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
222 static void
223 fput_fp_reg_r (reg, info)
224 unsigned reg;
225 disassemble_info *info;
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");
235 static void
236 fput_creg (reg, info)
237 unsigned reg;
238 disassemble_info *info;
240 (*info->fprintf_func) (info->stream, control_reg[reg]);
243 /* print constants in hex with sign */
245 static void
246 fput_hex_const (num, info)
247 unsigned num;
248 disassemble_info *info;
250 /* Mark negative numbers as negative; only mark
251 numbers as hex if necessary. */
252 if ((int)num < 0)
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);
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);
265 /* print constants in decimal with sign */
267 static void
268 fput_decimal_const (num, info)
269 unsigned num;
270 disassemble_info *info;
272 if ((int)num < 0)
273 (*info->fprintf_func) (info->stream, "-%d", -(int)num);
274 else
275 (*info->fprintf_func) (info->stream, "%d", num);
278 /* Routines to extract various sized constants out of hppa
279 instructions. */
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;
287 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
290 static int
291 extract_5_load (word)
292 unsigned word;
294 return low_sign_extend (word >> 16 & MASK_5, 5);
297 /* extract the immediate field from a st{bhw}s instruction */
298 static int
299 extract_5_store (word)
300 unsigned word;
302 return low_sign_extend (word & MASK_5, 5);
305 /* extract the immediate field from a break instruction */
306 static unsigned
307 extract_5r_store (word)
308 unsigned word;
310 return (word & MASK_5);
313 /* extract the immediate field from a {sr}sm instruction */
314 static unsigned
315 extract_5R_store (word)
316 unsigned word;
318 return (word >> 16 & MASK_5);
321 /* extract the immediate field from a bb instruction */
322 static unsigned
323 extract_5Q_store (word)
324 unsigned word;
326 return (word >> 21 & MASK_5);
329 /* extract an 11 bit immediate field */
330 static int
331 extract_11 (word)
332 unsigned word;
334 return low_sign_extend (word & MASK_11, 11);
337 /* extract a 14 bit immediate field */
338 static int
339 extract_14 (word)
340 unsigned word;
342 return low_sign_extend (word & MASK_14, 14);
345 /* extract a 21 bit constant */
347 static int
348 extract_21 (word)
349 unsigned word;
351 int val;
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;
367 /* extract a 12 bit constant from branch instructions */
369 static int
370 extract_12 (word)
371 unsigned word;
373 return sign_extend (GET_FIELD (word, 19, 28) |
374 GET_FIELD (word, 29, 29) << 10 |
375 (word & 0x1) << 11, 12) << 2;
378 /* extract a 17 bit constant from branch instructions, returning the
379 19 bit signed value. */
381 static int
382 extract_17 (word)
383 unsigned word;
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;
391 /* Print one instruction. */
393 print_insn_hppa (memaddr, info)
394 bfd_vma memaddr;
395 disassemble_info *info;
397 bfd_byte buffer[4];
398 unsigned int insn, i;
400 #ifdef LOCAL_ONLY
401 static int got_version_id = 0;
402 static enum pa_arch pa_version;
403 #endif
405 /* Get the instruction to disassemble.
408 int status =
409 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
410 if (status != 0)
412 (*info->memory_error_func) (status, memaddr, info);
413 return -1;
416 insn = bfd_getb32 (buffer);
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:
425 CPU_PA_RISC1_0 0x20B
426 CPU_PA_RISC1_1 0x210
427 CPU_PA_RISC1_2 0x211
428 CPU_PA_RISC2_0 0x214
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)
434 int version_id;
436 got_version_id = 1;
437 version_id = sysconf (_SC_CPU_VERSION);
438 switch (version_id)
440 case CPU_PA_RISC1_0 :
441 case CPU_PA_RISC1_1 :
442 case CPU_PA_RISC1_2 :
443 pa_version = pa10;
444 break;
446 case CPU_PA_RISC2_0 :
447 pa_version = pa20;
448 break;
450 default:
451 /* Now what? */
452 break;
455 #endif
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.
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)
466 const struct pa_opcode *opcode = &pa_opcodes[i];
467 if ((insn & opcode->mask) == opcode->match)
469 register const char *s;
470 int added_space = 0;
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
481 fputs_filtered (opcode->name, info);
483 for (s = opcode->args; *s != '\0'; ++s)
485 if (!added_space
486 && 0 == strchr(completer_chars, *s))
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;
495 /* '*s' describes either an extraction and a format,
496 or is a literal string to dump to the disassembly. */
497 switch (*s)
499 case 'x':
500 fput_reg (GET_FIELD (insn, 11, 15), info);
501 break;
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;
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;
517 case 'b':
518 fput_reg (GET_FIELD (insn, 6, 10), info);
519 break;
521 case '^':
522 fput_creg (GET_FIELD (insn, 6, 10), info);
523 break;
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;
532 case 't':
533 fput_reg (GET_FIELD (insn, 27, 31), info);
534 break;
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;
543 case 'y':
544 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
545 break;
547 case 'B':
548 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
549 break;
551 case '4':
553 int reg = GET_FIELD (insn, 6, 10);
555 reg |= (GET_FIELD (insn, 26, 26) << 4);
556 fput_fp_reg (reg, info);
557 break;
560 case '6':
562 int reg = GET_FIELD (insn, 11, 15);
564 reg |= (GET_FIELD (insn, 26, 26) << 4);
565 fput_fp_reg (reg, info);
566 break;
569 case '7':
571 int reg = GET_FIELD (insn, 27, 31);
573 reg |= (GET_FIELD (insn, 26, 26) << 4);
574 fput_fp_reg (reg, info);
575 break;
578 case '8':
580 int reg = GET_FIELD (insn, 16, 20);
582 reg |= (GET_FIELD (insn, 26, 26) << 4);
583 fput_fp_reg (reg, info);
584 break;
587 case '9':
589 int reg = GET_FIELD (insn, 21, 25);
591 reg |= (GET_FIELD (insn, 26, 26) << 4);
592 fput_fp_reg (reg, info);
593 break;
596 case '5':
597 fput_hex_const (extract_5_load (insn), info);
598 break;
600 case 's':
601 (*info->fprintf_func) (info->stream,
602 "sr%d", GET_FIELD (insn, 16, 17));
603 break;
605 case 'S':
606 /* Used when 'assemble_3' is specified.
608 (*info->fprintf_func) (info->stream, "sr%d",
609 extract_3 (insn));
610 break;
612 case 'c':
613 fputs_filtered (index_compl_names[GET_COMPL (insn)], info);
614 break;
616 case 'C':
617 fputs_filtered (short_ldst_compl_names[GET_COMPL_O (insn)], info);
618 break;
620 case 'm':
621 fputs_filtered (short_ldst_compl_names[
622 (GET_BIT(insn,29) << 1 | GET_BIT(insn,28)) ],
623 info);
624 break;
626 case 'Y':
627 fputs_filtered (short_bytes_compl_names[GET_COMPL (insn)], info);
628 break;
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;
638 case '?':
639 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
640 + GET_FIELD (insn, 4, 4) * 8], info);
641 break;
643 case '@':
644 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
645 + GET_FIELD (insn, 4, 4) * 8], info);
646 break;
648 case 'a':
649 fputs_filtered (compare_cond_names[GET_COND (insn)], info);
650 break;
652 case 'd':
653 fputs_filtered (add_cond_names[GET_COND (insn)], info);
654 break;
656 case '!':
657 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)], info);
658 break;
660 case '&':
661 fputs_filtered (logical_cond_names[GET_COND (insn)], info);
662 break;
664 case 'U':
665 fputs_filtered (unit_cond_names[GET_COND (insn)], info);
666 break;
668 case '|':
669 case '>':
670 case '~':
671 fputs_filtered (shift_cond_names[GET_FIELD (insn, 16, 18)], info);
672 break;
674 case 'V':
675 fput_hex_const (extract_5_store (insn), info);
676 break;
678 case 'r':
679 fput_hex_const (extract_5r_store (insn), info);
680 break;
682 case 'R':
683 fput_hex_const (extract_5R_store (insn), info);
684 break;
686 case 'Q':
687 fput_hex_const (extract_5Q_store (insn), info);
688 break;
690 case 'i':
691 fput_hex_const (extract_11 (insn), info);
692 break;
694 case 'j':
695 fput_hex_const (extract_14 (insn), info);
696 break;
698 case 'k':
699 fput_hex_const (extract_21 (insn), info);
700 break;
702 case 'n':
703 if (insn & 0x2)
704 fputs_filtered (",n", info);
705 break;
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;
714 case 'w':
715 (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
716 info);
717 break;
719 case 'W':
720 /* 17 bit PC-relative branch. */
721 (*info->print_address_func) ((memaddr + 8
722 + extract_17 (insn)),
723 info);
724 break;
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;
733 case 'p':
734 if( pa20 != opcode->arch ) {
735 fput_decimal_const (31 - GET_FIELD (insn, 22, 26), info);
737 else {
738 fput_decimal_const (63 - CATENATE (GET_BIT (insn, 20), 1,
739 GET_FIELD (insn, 22, 26), 5),
740 info);
742 break;
744 case 'P':
745 fput_decimal_const (GET_FIELD (insn, 22, 26), info);
746 break;
748 case 'T':
749 fput_decimal_const (32 - GET_FIELD (insn, 27, 31), info);
750 break;
752 case 'A':
753 fput_hex_const (GET_FIELD (insn, 6, 18), info);
754 break;
756 case 'Z':
757 if (GET_FIELD (insn, 26, 26))
758 fputs_filtered (",m", info);
759 break;
761 case 'D':
762 fput_hex_const (GET_FIELD (insn, 6, 31), info);
763 break;
765 case 'f':
766 fput_decimal_const (GET_FIELD (insn, 23, 25), info);
767 break;
769 case 'O':
770 fput_hex_const ((GET_FIELD (insn, 6,20) << 5 |
771 GET_FIELD (insn, 27, 31)), info);
772 break;
774 case 'o':
775 fput_hex_const (GET_FIELD (insn, 6, 20), info);
776 break;
778 case '2':
779 fput_hex_const ((GET_FIELD (insn, 6, 22) << 5 |
780 GET_FIELD (insn, 27, 31)), info);
781 break;
783 case '1':
784 fput_hex_const ((GET_FIELD (insn, 11, 20) << 5 |
785 GET_FIELD (insn, 27, 31)), info);
786 break;
788 case '0':
789 fput_hex_const ((GET_FIELD (insn, 16, 20) << 5 |
790 GET_FIELD (insn, 27, 31)), info);
791 break;
793 case 'u':
794 fput_decimal_const (GET_FIELD (insn, 23, 25), info);
795 break;
797 case 'F':
798 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
799 info);
800 break;
802 case 'G':
803 fputs_filtered (float_format_names[GET_FIELD (insn, 17, 18)],
804 info);
805 break;
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;
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;
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;
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;
835 case 'M':
836 fputs_filtered (float_comp_names[GET_FIELD (insn, 27, 31)],
837 info);
838 break;
840 case 'L': {
841 long temp;
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;
851 case 'l': {
852 long temp;
854 temp = assemble_16a (s,
855 GET_FIELD (insn, 18, 28),
856 GET_BIT (insn, 31));
857 fput_hex_const (temp, info);
858 break;
861 case 'q':
863 /* TEMP HACK - FIXME - edie */
864 fput_hex_const (sign_extend (GET_FIELD (insn, 20, 30), 0), info);
865 break;
867 case '#':
868 fput_decimal_const (GET_FIELD (insn, 20, 28), info);
869 break;
871 case '$':
872 fputs_filtered (branch_push_pop_names[GET_PUSH_POP(insn)], info);
873 break;
875 case '.':
876 fput_creg( 11, info ); /* %cr11, printed by gdb as "sar" */
877 break;
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;
889 case '/':
890 fputs_filtered (deposit_names[GET_BIT(insn,21)], info);
891 break;
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;
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;
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;
913 case '=':
914 fputs_filtered (saturation_names[GET_FIELD(insn,24,25)], info);
915 break;
917 case ';':
918 /* Always positive */
919 fput_decimal_const (GET_FIELD (insn, 24, 25), info);
920 break;
922 case ':':
923 /* Always positive */
924 fput_decimal_const (GET_FIELD (insn, 22, 25), info);
925 break;
927 case '3':
928 fputs_filtered (shift_names[GET_FIELD(insn,20,21)], info);
929 break;
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;
939 case 'e':
940 fputs_filtered (mix_names[GET_FIELD(insn,17,18)], info);
941 break;
943 case '}':
944 fputs_filtered (conversion_names[GET_FIELD(insn,14,16)], info);
945 break;
947 case 'h':
948 fput_hex_const (GET_FIELD (insn, 6, 15), info);
949 break;
951 case '_':
952 fput_decimal_const ((GET_FIELD (insn, 16, 18) - 1), info);
953 break;
955 case '+': {
956 int temp = GET_FIELD (insn, 16, 18) ^ 1;
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;
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;
976 default:
977 (*info->fprintf_func) (info->stream, "%c", *s);
978 break;
980 } /* For each operand */
982 return sizeof (insn);
983 } /* If matched */
984 } /* For each opcode */
986 (*info->fprintf_func) (info->stream, "#%8x", insn);
987 return sizeof(insn);