12159047fSniklas /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2*c074d1c9Sdrahn Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003
3b55d4692Sfgsch Free Software Foundation, Inc.
42159047fSniklas
52159047fSniklas Contributed by the Center for Software Science at the
62159047fSniklas University of Utah (pa-gdb-bugs@cs.utah.edu).
72159047fSniklas
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
212159047fSniklas
222159047fSniklas #include "sysdep.h"
232159047fSniklas #include "dis-asm.h"
242159047fSniklas #include "libhppa.h"
252159047fSniklas #include "opcode/hppa.h"
262159047fSniklas
272159047fSniklas /* Integer register names, indexed by the numbers which appear in the
282159047fSniklas opcodes. */
292159047fSniklas static const char *const reg_names[] =
302159047fSniklas {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
312159047fSniklas "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
322159047fSniklas "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
332159047fSniklas "sp", "r31"};
342159047fSniklas
352159047fSniklas /* Floating point register names, indexed by the numbers which appear in the
362159047fSniklas opcodes. */
372159047fSniklas static const char *const fp_reg_names[] =
382159047fSniklas {"fpsr", "fpe2", "fpe4", "fpe6",
392159047fSniklas "fr4", "fr5", "fr6", "fr7", "fr8",
402159047fSniklas "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
412159047fSniklas "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
422159047fSniklas "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
432159047fSniklas
442159047fSniklas typedef unsigned int CORE_ADDR;
452159047fSniklas
462159047fSniklas /* Get at various relevent fields of an instruction word. */
472159047fSniklas
482159047fSniklas #define MASK_5 0x1f
49f7cc78ecSespie #define MASK_10 0x3ff
502159047fSniklas #define MASK_11 0x7ff
512159047fSniklas #define MASK_14 0x3fff
52b55d4692Sfgsch #define MASK_16 0xffff
532159047fSniklas #define MASK_21 0x1fffff
542159047fSniklas
55b55d4692Sfgsch /* These macros get bit fields using HP's numbering (MSB = 0) */
562159047fSniklas
572159047fSniklas #define GET_FIELD(X, FROM, TO) \
582159047fSniklas ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
592159047fSniklas
60b55d4692Sfgsch #define GET_BIT(X, WHICH) \
61b55d4692Sfgsch GET_FIELD (X, WHICH, WHICH)
62b55d4692Sfgsch
632159047fSniklas /* Some of these have been converted to 2-d arrays because they
642159047fSniklas consume less storage this way. If the maintenance becomes a
652159047fSniklas problem, convert them back to const 1-d pointer arrays. */
66f7cc78ecSespie static const char *const control_reg[] = {
672159047fSniklas "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
682159047fSniklas "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
692159047fSniklas "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
702159047fSniklas "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
712159047fSniklas "tr4", "tr5", "tr6", "tr7"
722159047fSniklas };
732159047fSniklas
74f7cc78ecSespie static const char *const compare_cond_names[] = {
75f7cc78ecSespie "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
76f7cc78ecSespie ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
772159047fSniklas };
78f7cc78ecSespie static const char *const compare_cond_64_names[] = {
79f7cc78ecSespie "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
80f7cc78ecSespie ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
81f7cc78ecSespie };
82f7cc78ecSespie static const char *const cmpib_cond_64_names[] = {
83f7cc78ecSespie ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
84f7cc78ecSespie };
85f7cc78ecSespie static const char *const add_cond_names[] = {
86f7cc78ecSespie "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
87f7cc78ecSespie ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
88f7cc78ecSespie };
89f7cc78ecSespie static const char *const add_cond_64_names[] = {
90f7cc78ecSespie "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
91f7cc78ecSespie ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
92f7cc78ecSespie };
93f7cc78ecSespie static const char *const wide_add_cond_names[] = {
94f7cc78ecSespie "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
95f7cc78ecSespie ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
962159047fSniklas };
972159047fSniklas static const char *const logical_cond_names[] = {
982159047fSniklas "", ",=", ",<", ",<=", 0, 0, 0, ",od",
992159047fSniklas ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
100f7cc78ecSespie static const char *const logical_cond_64_names[] = {
101f7cc78ecSespie "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
102f7cc78ecSespie ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
1032159047fSniklas static const char *const unit_cond_names[] = {
104f7cc78ecSespie "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
105f7cc78ecSespie ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
1062159047fSniklas };
107f7cc78ecSespie static const char *const unit_cond_64_names[] = {
108f7cc78ecSespie "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
109f7cc78ecSespie ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
110f7cc78ecSespie };
111f7cc78ecSespie static const char *const shift_cond_names[] = {
1122159047fSniklas "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
1132159047fSniklas };
114f7cc78ecSespie static const char *const shift_cond_64_names[] = {
115f7cc78ecSespie "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
116f7cc78ecSespie };
117f7cc78ecSespie static const char *const bb_cond_64_names[] = {
118f7cc78ecSespie ",*<", ",*>="
119f7cc78ecSespie };
120f7cc78ecSespie static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
121f7cc78ecSespie static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
1222159047fSniklas static const char *const short_bytes_compl_names[] = {
1232159047fSniklas "", ",b,m", ",e", ",e,m"
1242159047fSniklas };
1252159047fSniklas static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
126*c074d1c9Sdrahn static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
127*c074d1c9Sdrahn static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
128f7cc78ecSespie static const char *const float_comp_names[] =
1292159047fSniklas {
1302159047fSniklas ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
1312159047fSniklas ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
1322159047fSniklas ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
1332159047fSniklas ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
1342159047fSniklas };
135f7cc78ecSespie static const char *const signed_unsigned_names[] = {",u", ",s"};
136f7cc78ecSespie static const char *const mix_half_names[] = {",l", ",r"};
137f7cc78ecSespie static const char *const saturation_names[] = {",us", ",ss", 0, ""};
138f7cc78ecSespie static const char *const read_write_names[] = {",r", ",w"};
139f7cc78ecSespie static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
1402159047fSniklas
1412159047fSniklas /* For a bunch of different instructions form an index into a
1422159047fSniklas completer name table. */
1432159047fSniklas #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
1442159047fSniklas GET_FIELD (insn, 18, 18) << 1)
1452159047fSniklas
1462159047fSniklas #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
1472159047fSniklas (GET_FIELD ((insn), 19, 19) ? 8 : 0))
1482159047fSniklas
149b55d4692Sfgsch static void fput_reg PARAMS ((unsigned int, disassemble_info *));
150b55d4692Sfgsch static void fput_fp_reg PARAMS ((unsigned int, disassemble_info *));
151b55d4692Sfgsch static void fput_fp_reg_r PARAMS ((unsigned int, disassemble_info *));
152b55d4692Sfgsch static void fput_creg PARAMS ((unsigned int, disassemble_info *));
153b55d4692Sfgsch static void fput_const PARAMS ((unsigned int, disassemble_info *));
154b55d4692Sfgsch static int extract_3 PARAMS ((unsigned int));
155b55d4692Sfgsch static int extract_5_load PARAMS ((unsigned int));
156b55d4692Sfgsch static int extract_5_store PARAMS ((unsigned int));
157b55d4692Sfgsch static unsigned extract_5r_store PARAMS ((unsigned int));
158b55d4692Sfgsch static unsigned extract_5R_store PARAMS ((unsigned int));
159b55d4692Sfgsch static unsigned extract_10U_store PARAMS ((unsigned int));
160b55d4692Sfgsch static unsigned extract_5Q_store PARAMS ((unsigned int));
161b55d4692Sfgsch static int extract_11 PARAMS ((unsigned int));
162b55d4692Sfgsch static int extract_14 PARAMS ((unsigned int));
163b55d4692Sfgsch static int extract_16 PARAMS ((unsigned int));
164b55d4692Sfgsch static int extract_21 PARAMS ((unsigned int));
165b55d4692Sfgsch static int extract_12 PARAMS ((unsigned int));
166b55d4692Sfgsch static int extract_17 PARAMS ((unsigned int));
167b55d4692Sfgsch static int extract_22 PARAMS ((unsigned int));
168b55d4692Sfgsch
1692159047fSniklas /* Utility function to print registers. Put these first, so gcc's function
1702159047fSniklas inlining can do its stuff. */
1712159047fSniklas
1722159047fSniklas #define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
1732159047fSniklas
1742159047fSniklas static void
fput_reg(reg,info)1752159047fSniklas fput_reg (reg, info)
1762159047fSniklas unsigned reg;
1772159047fSniklas disassemble_info *info;
1782159047fSniklas {
1792159047fSniklas (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
1802159047fSniklas }
1812159047fSniklas
1822159047fSniklas static void
fput_fp_reg(reg,info)1832159047fSniklas fput_fp_reg (reg, info)
1842159047fSniklas unsigned reg;
1852159047fSniklas disassemble_info *info;
1862159047fSniklas {
1872159047fSniklas (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
1882159047fSniklas }
1892159047fSniklas
1902159047fSniklas static void
fput_fp_reg_r(reg,info)1912159047fSniklas fput_fp_reg_r (reg, info)
1922159047fSniklas unsigned reg;
1932159047fSniklas disassemble_info *info;
1942159047fSniklas {
1952159047fSniklas /* Special case floating point exception registers. */
1962159047fSniklas if (reg < 4)
1972159047fSniklas (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
1982159047fSniklas else
199*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, "%sR",
200*c074d1c9Sdrahn reg ? fp_reg_names[reg] : "fr0");
2012159047fSniklas }
2022159047fSniklas
2032159047fSniklas static void
fput_creg(reg,info)2042159047fSniklas fput_creg (reg, info)
2052159047fSniklas unsigned reg;
2062159047fSniklas disassemble_info *info;
2072159047fSniklas {
2082159047fSniklas (*info->fprintf_func) (info->stream, control_reg[reg]);
2092159047fSniklas }
2102159047fSniklas
211b55d4692Sfgsch /* Print constants with sign. */
2122159047fSniklas
2132159047fSniklas static void
fput_const(num,info)2142159047fSniklas fput_const (num, info)
2152159047fSniklas unsigned num;
2162159047fSniklas disassemble_info *info;
2172159047fSniklas {
2182159047fSniklas if ((int)num < 0)
2192159047fSniklas (*info->fprintf_func) (info->stream, "-%x", -(int)num);
2202159047fSniklas else
2212159047fSniklas (*info->fprintf_func) (info->stream, "%x", num);
2222159047fSniklas }
2232159047fSniklas
2242159047fSniklas /* Routines to extract various sized constants out of hppa
2252159047fSniklas instructions. */
2262159047fSniklas
227b55d4692Sfgsch /* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */
2282159047fSniklas static int
extract_3(word)2292159047fSniklas extract_3 (word)
2302159047fSniklas unsigned word;
2312159047fSniklas {
2322159047fSniklas return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
2332159047fSniklas }
2342159047fSniklas
2352159047fSniklas static int
extract_5_load(word)2362159047fSniklas extract_5_load (word)
2372159047fSniklas unsigned word;
2382159047fSniklas {
2392159047fSniklas return low_sign_extend (word >> 16 & MASK_5, 5);
2402159047fSniklas }
2412159047fSniklas
242b55d4692Sfgsch /* Extract the immediate field from a st{bhw}s instruction. */
2432159047fSniklas static int
extract_5_store(word)2442159047fSniklas extract_5_store (word)
2452159047fSniklas unsigned word;
2462159047fSniklas {
2472159047fSniklas return low_sign_extend (word & MASK_5, 5);
2482159047fSniklas }
2492159047fSniklas
250b55d4692Sfgsch /* Extract the immediate field from a break instruction. */
2512159047fSniklas static unsigned
extract_5r_store(word)2522159047fSniklas extract_5r_store (word)
2532159047fSniklas unsigned word;
2542159047fSniklas {
2552159047fSniklas return (word & MASK_5);
2562159047fSniklas }
2572159047fSniklas
258b55d4692Sfgsch /* Extract the immediate field from a {sr}sm instruction. */
2592159047fSniklas static unsigned
extract_5R_store(word)2602159047fSniklas extract_5R_store (word)
2612159047fSniklas unsigned word;
2622159047fSniklas {
2632159047fSniklas return (word >> 16 & MASK_5);
2642159047fSniklas }
2652159047fSniklas
266b55d4692Sfgsch /* Extract the 10 bit immediate field from a {sr}sm instruction. */
267f7cc78ecSespie static unsigned
extract_10U_store(word)268f7cc78ecSespie extract_10U_store (word)
269f7cc78ecSespie unsigned word;
270f7cc78ecSespie {
271f7cc78ecSespie return (word >> 16 & MASK_10);
272f7cc78ecSespie }
273f7cc78ecSespie
274b55d4692Sfgsch /* Extract the immediate field from a bb instruction. */
2752159047fSniklas static unsigned
extract_5Q_store(word)2762159047fSniklas extract_5Q_store (word)
2772159047fSniklas unsigned word;
2782159047fSniklas {
2792159047fSniklas return (word >> 21 & MASK_5);
2802159047fSniklas }
2812159047fSniklas
282b55d4692Sfgsch /* Extract an 11 bit immediate field. */
2832159047fSniklas static int
extract_11(word)2842159047fSniklas extract_11 (word)
2852159047fSniklas unsigned word;
2862159047fSniklas {
2872159047fSniklas return low_sign_extend (word & MASK_11, 11);
2882159047fSniklas }
2892159047fSniklas
290b55d4692Sfgsch /* Extract a 14 bit immediate field. */
2912159047fSniklas static int
extract_14(word)2922159047fSniklas extract_14 (word)
2932159047fSniklas unsigned word;
2942159047fSniklas {
2952159047fSniklas return low_sign_extend (word & MASK_14, 14);
2962159047fSniklas }
2972159047fSniklas
298b55d4692Sfgsch /* Extract a 16 bit immediate field (PA2.0 wide only). */
299b55d4692Sfgsch static int
extract_16(word)300b55d4692Sfgsch extract_16 (word)
301b55d4692Sfgsch unsigned word;
302b55d4692Sfgsch {
303b55d4692Sfgsch int m15, m0, m1;
304b55d4692Sfgsch m0 = GET_BIT (word, 16);
305b55d4692Sfgsch m1 = GET_BIT (word, 17);
306b55d4692Sfgsch m15 = GET_BIT (word, 31);
307b55d4692Sfgsch word = (word >> 1) & 0x1fff;
308b55d4692Sfgsch word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
309b55d4692Sfgsch return sign_extend (word, 16);
310b55d4692Sfgsch }
311b55d4692Sfgsch
312b55d4692Sfgsch /* Extract a 21 bit constant. */
3132159047fSniklas
3142159047fSniklas static int
extract_21(word)3152159047fSniklas extract_21 (word)
3162159047fSniklas unsigned word;
3172159047fSniklas {
3182159047fSniklas int val;
3192159047fSniklas
3202159047fSniklas word &= MASK_21;
3212159047fSniklas word <<= 11;
3222159047fSniklas val = GET_FIELD (word, 20, 20);
3232159047fSniklas val <<= 11;
3242159047fSniklas val |= GET_FIELD (word, 9, 19);
3252159047fSniklas val <<= 2;
3262159047fSniklas val |= GET_FIELD (word, 5, 6);
3272159047fSniklas val <<= 5;
3282159047fSniklas val |= GET_FIELD (word, 0, 4);
3292159047fSniklas val <<= 2;
3302159047fSniklas val |= GET_FIELD (word, 7, 8);
3312159047fSniklas return sign_extend (val, 21) << 11;
3322159047fSniklas }
3332159047fSniklas
334b55d4692Sfgsch /* Extract a 12 bit constant from branch instructions. */
3352159047fSniklas
3362159047fSniklas static int
extract_12(word)3372159047fSniklas extract_12 (word)
3382159047fSniklas unsigned word;
3392159047fSniklas {
3402159047fSniklas return sign_extend (GET_FIELD (word, 19, 28) |
3412159047fSniklas GET_FIELD (word, 29, 29) << 10 |
3422159047fSniklas (word & 0x1) << 11, 12) << 2;
3432159047fSniklas }
3442159047fSniklas
345b55d4692Sfgsch /* Extract a 17 bit constant from branch instructions, returning the
3462159047fSniklas 19 bit signed value. */
3472159047fSniklas
3482159047fSniklas static int
extract_17(word)3492159047fSniklas extract_17 (word)
3502159047fSniklas unsigned word;
3512159047fSniklas {
3522159047fSniklas return sign_extend (GET_FIELD (word, 19, 28) |
3532159047fSniklas GET_FIELD (word, 29, 29) << 10 |
3542159047fSniklas GET_FIELD (word, 11, 15) << 11 |
3552159047fSniklas (word & 0x1) << 16, 17) << 2;
3562159047fSniklas }
3572159047fSniklas
358f7cc78ecSespie static int
extract_22(word)359f7cc78ecSespie extract_22 (word)
360f7cc78ecSespie unsigned word;
361f7cc78ecSespie {
362f7cc78ecSespie return sign_extend (GET_FIELD (word, 19, 28) |
363f7cc78ecSespie GET_FIELD (word, 29, 29) << 10 |
364f7cc78ecSespie GET_FIELD (word, 11, 15) << 11 |
365f7cc78ecSespie GET_FIELD (word, 6, 10) << 16 |
366f7cc78ecSespie (word & 0x1) << 21, 22) << 2;
367f7cc78ecSespie }
368f7cc78ecSespie
3692159047fSniklas /* Print one instruction. */
3702159047fSniklas int
print_insn_hppa(memaddr,info)3712159047fSniklas print_insn_hppa (memaddr, info)
3722159047fSniklas bfd_vma memaddr;
3732159047fSniklas disassemble_info *info;
3742159047fSniklas {
3752159047fSniklas bfd_byte buffer[4];
3762159047fSniklas unsigned int insn, i;
3772159047fSniklas
3782159047fSniklas {
3792159047fSniklas int status =
3802159047fSniklas (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
3812159047fSniklas if (status != 0)
3822159047fSniklas {
3832159047fSniklas (*info->memory_error_func) (status, memaddr, info);
3842159047fSniklas return -1;
3852159047fSniklas }
3862159047fSniklas }
3872159047fSniklas
3882159047fSniklas insn = bfd_getb32 (buffer);
3892159047fSniklas
3902159047fSniklas for (i = 0; i < NUMOPCODES; ++i)
3912159047fSniklas {
3922159047fSniklas const struct pa_opcode *opcode = &pa_opcodes[i];
3932159047fSniklas if ((insn & opcode->mask) == opcode->match)
3942159047fSniklas {
3952159047fSniklas register const char *s;
396b55d4692Sfgsch #ifndef BFD64
397b55d4692Sfgsch if (opcode->arch == pa20w)
398b55d4692Sfgsch continue;
399b55d4692Sfgsch #endif
4002159047fSniklas (*info->fprintf_func) (info->stream, "%s", opcode->name);
4012159047fSniklas
402*c074d1c9Sdrahn if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
4032159047fSniklas (*info->fprintf_func) (info->stream, " ");
4042159047fSniklas for (s = opcode->args; *s != '\0'; ++s)
4052159047fSniklas {
4062159047fSniklas switch (*s)
4072159047fSniklas {
4082159047fSniklas case 'x':
4092159047fSniklas fput_reg (GET_FIELD (insn, 11, 15), info);
4102159047fSniklas break;
411f7cc78ecSespie case 'a':
4122159047fSniklas case 'b':
4132159047fSniklas fput_reg (GET_FIELD (insn, 6, 10), info);
4142159047fSniklas break;
4152159047fSniklas case '^':
4162159047fSniklas fput_creg (GET_FIELD (insn, 6, 10), info);
4172159047fSniklas break;
4182159047fSniklas case 't':
4192159047fSniklas fput_reg (GET_FIELD (insn, 27, 31), info);
4202159047fSniklas break;
421f7cc78ecSespie
422f7cc78ecSespie /* Handle floating point registers. */
423f7cc78ecSespie case 'f':
424f7cc78ecSespie switch (*++s)
425f7cc78ecSespie {
426f7cc78ecSespie case 't':
427f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 27, 31), info);
428f7cc78ecSespie break;
429f7cc78ecSespie case 'T':
4302159047fSniklas if (GET_FIELD (insn, 25, 25))
4312159047fSniklas fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
4322159047fSniklas else
4332159047fSniklas fput_fp_reg (GET_FIELD (insn, 27, 31), info);
4342159047fSniklas break;
435f7cc78ecSespie case 'a':
436f7cc78ecSespie if (GET_FIELD (insn, 25, 25))
437f7cc78ecSespie fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
438f7cc78ecSespie else
439f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 6, 10), info);
4402159047fSniklas break;
441f7cc78ecSespie
442f7cc78ecSespie /* 'fA' will not generate a space before the regsiter
443f7cc78ecSespie name. Normally that is fine. Except that it
444f7cc78ecSespie causes problems with xmpyu which has no FP format
445f7cc78ecSespie completer. */
446f7cc78ecSespie case 'X':
447f7cc78ecSespie fputs_filtered (" ", info);
448f7cc78ecSespie /* FALLTHRU */
449f7cc78ecSespie
450f7cc78ecSespie case 'A':
451f7cc78ecSespie if (GET_FIELD (insn, 24, 24))
452f7cc78ecSespie fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
453f7cc78ecSespie else
454f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 6, 10), info);
455f7cc78ecSespie break;
456f7cc78ecSespie case 'b':
457f7cc78ecSespie if (GET_FIELD (insn, 25, 25))
458f7cc78ecSespie fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
459f7cc78ecSespie else
460f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 11, 15), info);
461f7cc78ecSespie break;
462f7cc78ecSespie case 'B':
463f7cc78ecSespie if (GET_FIELD (insn, 19, 19))
464f7cc78ecSespie fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
465f7cc78ecSespie else
466f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 11, 15), info);
467f7cc78ecSespie break;
468f7cc78ecSespie case 'C':
469f7cc78ecSespie {
470f7cc78ecSespie int reg = GET_FIELD (insn, 21, 22);
471f7cc78ecSespie reg |= GET_FIELD (insn, 16, 18) << 2;
472f7cc78ecSespie if (GET_FIELD (insn, 23, 23) != 0)
473f7cc78ecSespie fput_fp_reg_r (reg, info);
474f7cc78ecSespie else
475f7cc78ecSespie fput_fp_reg (reg, info);
476f7cc78ecSespie break;
477f7cc78ecSespie }
478f7cc78ecSespie case 'i':
4792159047fSniklas {
4802159047fSniklas int reg = GET_FIELD (insn, 6, 10);
4812159047fSniklas
4822159047fSniklas reg |= (GET_FIELD (insn, 26, 26) << 4);
4832159047fSniklas fput_fp_reg (reg, info);
4842159047fSniklas break;
4852159047fSniklas }
486f7cc78ecSespie case 'j':
4872159047fSniklas {
4882159047fSniklas int reg = GET_FIELD (insn, 11, 15);
4892159047fSniklas
4902159047fSniklas reg |= (GET_FIELD (insn, 26, 26) << 4);
4912159047fSniklas fput_fp_reg (reg, info);
4922159047fSniklas break;
4932159047fSniklas }
494f7cc78ecSespie case 'k':
4952159047fSniklas {
4962159047fSniklas int reg = GET_FIELD (insn, 27, 31);
4972159047fSniklas
4982159047fSniklas reg |= (GET_FIELD (insn, 26, 26) << 4);
4992159047fSniklas fput_fp_reg (reg, info);
5002159047fSniklas break;
5012159047fSniklas }
502f7cc78ecSespie case 'l':
5032159047fSniklas {
5042159047fSniklas int reg = GET_FIELD (insn, 21, 25);
5052159047fSniklas
5062159047fSniklas reg |= (GET_FIELD (insn, 26, 26) << 4);
5072159047fSniklas fput_fp_reg (reg, info);
5082159047fSniklas break;
5092159047fSniklas }
510f7cc78ecSespie case 'm':
511f7cc78ecSespie {
512f7cc78ecSespie int reg = GET_FIELD (insn, 16, 20);
513f7cc78ecSespie
514f7cc78ecSespie reg |= (GET_FIELD (insn, 26, 26) << 4);
515f7cc78ecSespie fput_fp_reg (reg, info);
516f7cc78ecSespie break;
517f7cc78ecSespie }
518b55d4692Sfgsch
519b55d4692Sfgsch /* 'fe' will not generate a space before the register
520b55d4692Sfgsch name. Normally that is fine. Except that it
521b55d4692Sfgsch causes problems with fstw fe,y(b) which has no FP
522b55d4692Sfgsch format completer. */
523b55d4692Sfgsch case 'E':
524b55d4692Sfgsch fputs_filtered (" ", info);
525b55d4692Sfgsch /* FALLTHRU */
526b55d4692Sfgsch
527f7cc78ecSespie case 'e':
528b55d4692Sfgsch if (GET_FIELD (insn, 30, 30))
529f7cc78ecSespie fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
530f7cc78ecSespie else
531f7cc78ecSespie fput_fp_reg (GET_FIELD (insn, 11, 15), info);
532f7cc78ecSespie break;
533b55d4692Sfgsch case 'x':
534b55d4692Sfgsch fput_fp_reg (GET_FIELD (insn, 11, 15), info);
535b55d4692Sfgsch break;
536f7cc78ecSespie }
537f7cc78ecSespie break;
538f7cc78ecSespie
5392159047fSniklas case '5':
5402159047fSniklas fput_const (extract_5_load (insn), info);
5412159047fSniklas break;
5422159047fSniklas case 's':
543*c074d1c9Sdrahn {
544*c074d1c9Sdrahn int space = GET_FIELD (insn, 16, 17);
545*c074d1c9Sdrahn /* Zero means implicit addressing, not use of sr0. */
546*c074d1c9Sdrahn if (space != 0)
547*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, "sr%d", space);
548*c074d1c9Sdrahn }
5492159047fSniklas break;
550f7cc78ecSespie
5512159047fSniklas case 'S':
552*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, "sr%d",
553*c074d1c9Sdrahn extract_3 (insn));
5542159047fSniklas break;
555f7cc78ecSespie
556f7cc78ecSespie /* Handle completers. */
5572159047fSniklas case 'c':
558f7cc78ecSespie switch (*++s)
559f7cc78ecSespie {
560f7cc78ecSespie case 'x':
561*c074d1c9Sdrahn (*info->fprintf_func)
562*c074d1c9Sdrahn (info->stream, "%s",
563*c074d1c9Sdrahn index_compl_names[GET_COMPL (insn)]);
564*c074d1c9Sdrahn break;
565*c074d1c9Sdrahn case 'X':
566*c074d1c9Sdrahn (*info->fprintf_func)
567*c074d1c9Sdrahn (info->stream, "%s ",
5682159047fSniklas index_compl_names[GET_COMPL (insn)]);
5692159047fSniklas break;
570f7cc78ecSespie case 'm':
571*c074d1c9Sdrahn (*info->fprintf_func)
572*c074d1c9Sdrahn (info->stream, "%s",
5732159047fSniklas short_ldst_compl_names[GET_COMPL (insn)]);
5742159047fSniklas break;
575*c074d1c9Sdrahn case 'M':
576*c074d1c9Sdrahn (*info->fprintf_func)
577*c074d1c9Sdrahn (info->stream, "%s ",
578*c074d1c9Sdrahn short_ldst_compl_names[GET_COMPL (insn)]);
579*c074d1c9Sdrahn break;
580*c074d1c9Sdrahn case 'A':
581*c074d1c9Sdrahn (*info->fprintf_func)
582*c074d1c9Sdrahn (info->stream, "%s ",
583*c074d1c9Sdrahn short_bytes_compl_names[GET_COMPL (insn)]);
584*c074d1c9Sdrahn break;
585f7cc78ecSespie case 's':
586*c074d1c9Sdrahn (*info->fprintf_func)
587*c074d1c9Sdrahn (info->stream, "%s",
5882159047fSniklas short_bytes_compl_names[GET_COMPL (insn)]);
5892159047fSniklas break;
590f7cc78ecSespie case 'c':
591f7cc78ecSespie case 'C':
592f7cc78ecSespie switch (GET_FIELD (insn, 20, 21))
593f7cc78ecSespie {
594f7cc78ecSespie case 1:
595f7cc78ecSespie (*info->fprintf_func) (info->stream, ",bc ");
596f7cc78ecSespie break;
597f7cc78ecSespie case 2:
598f7cc78ecSespie (*info->fprintf_func) (info->stream, ",sl ");
599f7cc78ecSespie break;
600f7cc78ecSespie default:
601f7cc78ecSespie (*info->fprintf_func) (info->stream, " ");
602f7cc78ecSespie }
603f7cc78ecSespie break;
604f7cc78ecSespie case 'd':
605f7cc78ecSespie switch (GET_FIELD (insn, 20, 21))
606f7cc78ecSespie {
607f7cc78ecSespie case 1:
608f7cc78ecSespie (*info->fprintf_func) (info->stream, ",co ");
609f7cc78ecSespie break;
610f7cc78ecSespie default:
611f7cc78ecSespie (*info->fprintf_func) (info->stream, " ");
612f7cc78ecSespie }
613f7cc78ecSespie break;
614f7cc78ecSespie case 'o':
615f7cc78ecSespie (*info->fprintf_func) (info->stream, ",o");
616f7cc78ecSespie break;
617f7cc78ecSespie case 'g':
618f7cc78ecSespie (*info->fprintf_func) (info->stream, ",gate");
619f7cc78ecSespie break;
620f7cc78ecSespie case 'p':
621f7cc78ecSespie (*info->fprintf_func) (info->stream, ",l,push");
622f7cc78ecSespie break;
623f7cc78ecSespie case 'P':
624f7cc78ecSespie (*info->fprintf_func) (info->stream, ",pop");
625f7cc78ecSespie break;
626f7cc78ecSespie case 'l':
627f7cc78ecSespie case 'L':
628f7cc78ecSespie (*info->fprintf_func) (info->stream, ",l");
629f7cc78ecSespie break;
630f7cc78ecSespie case 'w':
631*c074d1c9Sdrahn (*info->fprintf_func)
632*c074d1c9Sdrahn (info->stream, "%s ",
633f7cc78ecSespie read_write_names[GET_FIELD (insn, 25, 25)]);
634f7cc78ecSespie break;
635f7cc78ecSespie case 'W':
636f7cc78ecSespie (*info->fprintf_func) (info->stream, ",w");
637f7cc78ecSespie break;
638f7cc78ecSespie case 'r':
639f7cc78ecSespie if (GET_FIELD (insn, 23, 26) == 5)
640f7cc78ecSespie (*info->fprintf_func) (info->stream, ",r");
641f7cc78ecSespie break;
642f7cc78ecSespie case 'Z':
643f7cc78ecSespie if (GET_FIELD (insn, 26, 26))
644f7cc78ecSespie (*info->fprintf_func) (info->stream, ",m ");
645f7cc78ecSespie else
646f7cc78ecSespie (*info->fprintf_func) (info->stream, " ");
647f7cc78ecSespie break;
648f7cc78ecSespie case 'i':
649f7cc78ecSespie if (GET_FIELD (insn, 25, 25))
650f7cc78ecSespie (*info->fprintf_func) (info->stream, ",i");
651f7cc78ecSespie break;
652f7cc78ecSespie case 'z':
653f7cc78ecSespie if (!GET_FIELD (insn, 21, 21))
654f7cc78ecSespie (*info->fprintf_func) (info->stream, ",z");
655f7cc78ecSespie break;
656f7cc78ecSespie case 'a':
657f7cc78ecSespie (*info->fprintf_func)
658*c074d1c9Sdrahn (info->stream, "%s",
659*c074d1c9Sdrahn add_compl_names[GET_FIELD (insn, 20, 21)]);
660f7cc78ecSespie break;
661f7cc78ecSespie case 'Y':
662f7cc78ecSespie (*info->fprintf_func)
663*c074d1c9Sdrahn (info->stream, ",dc%s",
664*c074d1c9Sdrahn add_compl_names[GET_FIELD (insn, 20, 21)]);
665f7cc78ecSespie break;
666f7cc78ecSespie case 'y':
667f7cc78ecSespie (*info->fprintf_func)
668*c074d1c9Sdrahn (info->stream, ",c%s",
669*c074d1c9Sdrahn add_compl_names[GET_FIELD (insn, 20, 21)]);
670f7cc78ecSespie break;
671f7cc78ecSespie case 'v':
672f7cc78ecSespie if (GET_FIELD (insn, 20, 20))
673f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tsv");
674f7cc78ecSespie break;
675f7cc78ecSespie case 't':
676f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tc");
677f7cc78ecSespie if (GET_FIELD (insn, 20, 20))
678f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tsv");
679f7cc78ecSespie break;
680f7cc78ecSespie case 'B':
681f7cc78ecSespie (*info->fprintf_func) (info->stream, ",db");
682f7cc78ecSespie if (GET_FIELD (insn, 20, 20))
683f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tsv");
684f7cc78ecSespie break;
685f7cc78ecSespie case 'b':
686f7cc78ecSespie (*info->fprintf_func) (info->stream, ",b");
687f7cc78ecSespie if (GET_FIELD (insn, 20, 20))
688f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tsv");
689f7cc78ecSespie break;
690f7cc78ecSespie case 'T':
691f7cc78ecSespie if (GET_FIELD (insn, 25, 25))
692f7cc78ecSespie (*info->fprintf_func) (info->stream, ",tc");
693f7cc78ecSespie break;
694f7cc78ecSespie case 'S':
695f7cc78ecSespie /* EXTRD/W has a following condition. */
696f7cc78ecSespie if (*(s + 1) == '?')
697f7cc78ecSespie (*info->fprintf_func)
698*c074d1c9Sdrahn (info->stream, "%s",
699*c074d1c9Sdrahn signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
700f7cc78ecSespie else
701f7cc78ecSespie (*info->fprintf_func)
702*c074d1c9Sdrahn (info->stream, "%s ",
703*c074d1c9Sdrahn signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
704f7cc78ecSespie break;
705f7cc78ecSespie case 'h':
706f7cc78ecSespie (*info->fprintf_func)
707*c074d1c9Sdrahn (info->stream, "%s",
708*c074d1c9Sdrahn mix_half_names[GET_FIELD (insn, 17, 17)]);
709f7cc78ecSespie break;
710f7cc78ecSespie case 'H':
711f7cc78ecSespie (*info->fprintf_func)
712*c074d1c9Sdrahn (info->stream, "%s ",
713*c074d1c9Sdrahn saturation_names[GET_FIELD (insn, 24, 25)]);
714f7cc78ecSespie break;
715f7cc78ecSespie case '*':
716f7cc78ecSespie (*info->fprintf_func)
717f7cc78ecSespie (info->stream, ",%d%d%d%d ",
718f7cc78ecSespie GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
719f7cc78ecSespie GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
720f7cc78ecSespie break;
721f7cc78ecSespie
722f7cc78ecSespie case 'q':
723f7cc78ecSespie {
724f7cc78ecSespie int m, a;
725f7cc78ecSespie
726f7cc78ecSespie m = GET_FIELD (insn, 28, 28);
727f7cc78ecSespie a = GET_FIELD (insn, 29, 29);
728f7cc78ecSespie
729f7cc78ecSespie if (m && !a)
730f7cc78ecSespie fputs_filtered (",ma ", info);
731f7cc78ecSespie else if (m && a)
732f7cc78ecSespie fputs_filtered (",mb ", info);
733f7cc78ecSespie else
734f7cc78ecSespie fputs_filtered (" ", info);
735f7cc78ecSespie break;
736f7cc78ecSespie }
737f7cc78ecSespie
738f7cc78ecSespie case 'J':
739f7cc78ecSespie {
740b55d4692Sfgsch int opc = GET_FIELD (insn, 0, 5);
741f7cc78ecSespie
742b55d4692Sfgsch if (opc == 0x16 || opc == 0x1e)
743f7cc78ecSespie {
744f7cc78ecSespie if (GET_FIELD (insn, 29, 29) == 0)
745f7cc78ecSespie fputs_filtered (",ma ", info);
746f7cc78ecSespie else
747f7cc78ecSespie fputs_filtered (",mb ", info);
748f7cc78ecSespie }
749f7cc78ecSespie else
750f7cc78ecSespie fputs_filtered (" ", info);
751f7cc78ecSespie break;
752f7cc78ecSespie }
753f7cc78ecSespie
754f7cc78ecSespie case 'e':
755f7cc78ecSespie {
756b55d4692Sfgsch int opc = GET_FIELD (insn, 0, 5);
757f7cc78ecSespie
758b55d4692Sfgsch if (opc == 0x13 || opc == 0x1b)
759f7cc78ecSespie {
760f7cc78ecSespie if (GET_FIELD (insn, 18, 18) == 1)
761f7cc78ecSespie fputs_filtered (",mb ", info);
762f7cc78ecSespie else
763f7cc78ecSespie fputs_filtered (",ma ", info);
764f7cc78ecSespie }
765b55d4692Sfgsch else if (opc == 0x17 || opc == 0x1f)
766f7cc78ecSespie {
767f7cc78ecSespie if (GET_FIELD (insn, 31, 31) == 1)
768f7cc78ecSespie fputs_filtered (",ma ", info);
769f7cc78ecSespie else
770f7cc78ecSespie fputs_filtered (",mb ", info);
771f7cc78ecSespie }
772f7cc78ecSespie else
773f7cc78ecSespie fputs_filtered (" ", info);
774f7cc78ecSespie
775f7cc78ecSespie break;
776f7cc78ecSespie }
777f7cc78ecSespie }
778f7cc78ecSespie break;
779f7cc78ecSespie
780f7cc78ecSespie /* Handle conditions. */
781f7cc78ecSespie case '?':
782f7cc78ecSespie {
783f7cc78ecSespie s++;
784f7cc78ecSespie switch (*s)
785f7cc78ecSespie {
786f7cc78ecSespie case 'f':
787*c074d1c9Sdrahn (*info->fprintf_func)
788*c074d1c9Sdrahn (info->stream, "%s ",
789*c074d1c9Sdrahn float_comp_names[GET_FIELD (insn, 27, 31)]);
790f7cc78ecSespie break;
791f7cc78ecSespie
7922159047fSniklas /* these four conditions are for the set of instructions
793f7cc78ecSespie which distinguish true/false conditions by opcode
794f7cc78ecSespie rather than by the 'f' bit (sigh): comb, comib,
795f7cc78ecSespie addb, addib */
796f7cc78ecSespie case 't':
797*c074d1c9Sdrahn fputs_filtered
798*c074d1c9Sdrahn (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
7992159047fSniklas break;
800f7cc78ecSespie case 'n':
801*c074d1c9Sdrahn fputs_filtered
802*c074d1c9Sdrahn (compare_cond_names[GET_FIELD (insn, 16, 18)
803*c074d1c9Sdrahn + GET_FIELD (insn, 4, 4) * 8],
804*c074d1c9Sdrahn info);
8052159047fSniklas break;
806f7cc78ecSespie case 'N':
807*c074d1c9Sdrahn fputs_filtered
808*c074d1c9Sdrahn (compare_cond_64_names[GET_FIELD (insn, 16, 18)
809*c074d1c9Sdrahn + GET_FIELD (insn, 2, 2) * 8],
810*c074d1c9Sdrahn info);
811f7cc78ecSespie break;
812f7cc78ecSespie case 'Q':
813*c074d1c9Sdrahn fputs_filtered
814*c074d1c9Sdrahn (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
815f7cc78ecSespie info);
816f7cc78ecSespie break;
8172159047fSniklas case '@':
818*c074d1c9Sdrahn fputs_filtered
819*c074d1c9Sdrahn (add_cond_names[GET_FIELD (insn, 16, 18)
820*c074d1c9Sdrahn + GET_FIELD (insn, 4, 4) * 8],
821*c074d1c9Sdrahn info);
8222159047fSniklas break;
823f7cc78ecSespie case 's':
824*c074d1c9Sdrahn (*info->fprintf_func)
825*c074d1c9Sdrahn (info->stream, "%s ",
8262159047fSniklas compare_cond_names[GET_COND (insn)]);
8272159047fSniklas break;
828f7cc78ecSespie case 'S':
829*c074d1c9Sdrahn (*info->fprintf_func)
830*c074d1c9Sdrahn (info->stream, "%s ",
831f7cc78ecSespie compare_cond_64_names[GET_COND (insn)]);
832f7cc78ecSespie break;
833f7cc78ecSespie case 'a':
834*c074d1c9Sdrahn (*info->fprintf_func)
835*c074d1c9Sdrahn (info->stream, "%s ",
8362159047fSniklas add_cond_names[GET_COND (insn)]);
8372159047fSniklas break;
838f7cc78ecSespie case 'A':
839*c074d1c9Sdrahn (*info->fprintf_func)
840*c074d1c9Sdrahn (info->stream, "%s ",
841f7cc78ecSespie add_cond_64_names[GET_COND (insn)]);
842f7cc78ecSespie break;
843f7cc78ecSespie case 'd':
844*c074d1c9Sdrahn (*info->fprintf_func)
845*c074d1c9Sdrahn (info->stream, "%s",
8462159047fSniklas add_cond_names[GET_FIELD (insn, 16, 18)]);
8472159047fSniklas break;
8482159047fSniklas
849f7cc78ecSespie case 'W':
850f7cc78ecSespie (*info->fprintf_func)
851f7cc78ecSespie (info->stream, "%s",
852f7cc78ecSespie wide_add_cond_names[GET_FIELD (insn, 16, 18) +
853f7cc78ecSespie GET_FIELD (insn, 4, 4) * 8]);
854f7cc78ecSespie break;
855f7cc78ecSespie
856f7cc78ecSespie case 'l':
857*c074d1c9Sdrahn (*info->fprintf_func)
858*c074d1c9Sdrahn (info->stream, "%s ",
8592159047fSniklas logical_cond_names[GET_COND (insn)]);
8602159047fSniklas break;
861f7cc78ecSespie case 'L':
862*c074d1c9Sdrahn (*info->fprintf_func)
863*c074d1c9Sdrahn (info->stream, "%s ",
864f7cc78ecSespie logical_cond_64_names[GET_COND (insn)]);
865f7cc78ecSespie break;
866f7cc78ecSespie case 'u':
867*c074d1c9Sdrahn (*info->fprintf_func)
868*c074d1c9Sdrahn (info->stream, "%s ",
8692159047fSniklas unit_cond_names[GET_COND (insn)]);
8702159047fSniklas break;
871f7cc78ecSespie case 'U':
872*c074d1c9Sdrahn (*info->fprintf_func)
873*c074d1c9Sdrahn (info->stream, "%s ",
874f7cc78ecSespie unit_cond_64_names[GET_COND (insn)]);
875f7cc78ecSespie break;
876f7cc78ecSespie case 'y':
877f7cc78ecSespie case 'x':
878f7cc78ecSespie case 'b':
8792159047fSniklas (*info->fprintf_func)
8802159047fSniklas (info->stream, "%s",
8812159047fSniklas shift_cond_names[GET_FIELD (insn, 16, 18)]);
8822159047fSniklas
8832159047fSniklas /* If the next character in args is 'n', it will handle
8842159047fSniklas putting out the space. */
8852159047fSniklas if (s[1] != 'n')
8862159047fSniklas (*info->fprintf_func) (info->stream, " ");
8872159047fSniklas break;
888f7cc78ecSespie case 'X':
889*c074d1c9Sdrahn (*info->fprintf_func)
890*c074d1c9Sdrahn (info->stream, "%s ",
891f7cc78ecSespie shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
892f7cc78ecSespie break;
893f7cc78ecSespie case 'B':
894f7cc78ecSespie (*info->fprintf_func)
895f7cc78ecSespie (info->stream, "%s",
896f7cc78ecSespie bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
897f7cc78ecSespie
898f7cc78ecSespie /* If the next character in args is 'n', it will handle
899f7cc78ecSespie putting out the space. */
900f7cc78ecSespie if (s[1] != 'n')
901f7cc78ecSespie (*info->fprintf_func) (info->stream, " ");
902f7cc78ecSespie break;
903f7cc78ecSespie }
904f7cc78ecSespie break;
905f7cc78ecSespie }
906f7cc78ecSespie
9072159047fSniklas case 'V':
9082159047fSniklas fput_const (extract_5_store (insn), info);
9092159047fSniklas break;
9102159047fSniklas case 'r':
9112159047fSniklas fput_const (extract_5r_store (insn), info);
9122159047fSniklas break;
9132159047fSniklas case 'R':
9142159047fSniklas fput_const (extract_5R_store (insn), info);
9152159047fSniklas break;
916f7cc78ecSespie case 'U':
917f7cc78ecSespie fput_const (extract_10U_store (insn), info);
918f7cc78ecSespie break;
919f7cc78ecSespie case 'B':
9202159047fSniklas case 'Q':
9212159047fSniklas fput_const (extract_5Q_store (insn), info);
9222159047fSniklas break;
9232159047fSniklas case 'i':
9242159047fSniklas fput_const (extract_11 (insn), info);
9252159047fSniklas break;
9262159047fSniklas case 'j':
9272159047fSniklas fput_const (extract_14 (insn), info);
9282159047fSniklas break;
9292159047fSniklas case 'k':
9302159047fSniklas fput_const (extract_21 (insn), info);
9312159047fSniklas break;
932b55d4692Sfgsch case '<':
933b55d4692Sfgsch case 'l':
934b55d4692Sfgsch /* 16-bit long disp., PA2.0 wide only. */
935b55d4692Sfgsch fput_const (extract_16 (insn), info);
936b55d4692Sfgsch break;
9372159047fSniklas case 'n':
9382159047fSniklas if (insn & 0x2)
9392159047fSniklas (*info->fprintf_func) (info->stream, ",n ");
9402159047fSniklas else
9412159047fSniklas (*info->fprintf_func) (info->stream, " ");
9422159047fSniklas break;
9432159047fSniklas case 'N':
9442159047fSniklas if ((insn & 0x20) && s[1])
9452159047fSniklas (*info->fprintf_func) (info->stream, ",n ");
9462159047fSniklas else if (insn & 0x20)
9472159047fSniklas (*info->fprintf_func) (info->stream, ",n");
9482159047fSniklas else if (s[1])
9492159047fSniklas (*info->fprintf_func) (info->stream, " ");
9502159047fSniklas break;
9512159047fSniklas case 'w':
952*c074d1c9Sdrahn (*info->print_address_func)
953*c074d1c9Sdrahn (memaddr + 8 + extract_12 (insn), info);
9542159047fSniklas break;
9552159047fSniklas case 'W':
9562159047fSniklas /* 17 bit PC-relative branch. */
957*c074d1c9Sdrahn (*info->print_address_func)
958*c074d1c9Sdrahn ((memaddr + 8 + extract_17 (insn)), info);
9592159047fSniklas break;
9602159047fSniklas case 'z':
9612159047fSniklas /* 17 bit displacement. This is an offset from a register
9622159047fSniklas so it gets disasssembled as just a number, not any sort
9632159047fSniklas of address. */
9642159047fSniklas fput_const (extract_17 (insn), info);
9652159047fSniklas break;
966f7cc78ecSespie
967f7cc78ecSespie case 'Z':
968f7cc78ecSespie /* addil %r1 implicit output. */
969f7cc78ecSespie (*info->fprintf_func) (info->stream, "%%r1");
970f7cc78ecSespie break;
971f7cc78ecSespie
972f7cc78ecSespie case 'Y':
973f7cc78ecSespie /* be,l %sr0,%r31 implicit output. */
974f7cc78ecSespie (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
975f7cc78ecSespie break;
976f7cc78ecSespie
977f7cc78ecSespie case '@':
978f7cc78ecSespie (*info->fprintf_func) (info->stream, "0");
979f7cc78ecSespie break;
980f7cc78ecSespie
981f7cc78ecSespie case '.':
982f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d",
983f7cc78ecSespie GET_FIELD (insn, 24, 25));
984f7cc78ecSespie break;
985f7cc78ecSespie case '*':
986f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d",
987f7cc78ecSespie GET_FIELD (insn, 22, 25));
988f7cc78ecSespie break;
989f7cc78ecSespie case '!':
990f7cc78ecSespie (*info->fprintf_func) (info->stream, "%%sar");
991f7cc78ecSespie break;
9922159047fSniklas case 'p':
9932159047fSniklas (*info->fprintf_func) (info->stream, "%d",
9942159047fSniklas 31 - GET_FIELD (insn, 22, 26));
9952159047fSniklas break;
996f7cc78ecSespie case '~':
997f7cc78ecSespie {
998f7cc78ecSespie int num;
999f7cc78ecSespie num = GET_FIELD (insn, 20, 20) << 5;
1000f7cc78ecSespie num |= GET_FIELD (insn, 22, 26);
1001f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d", 63 - num);
1002f7cc78ecSespie break;
1003f7cc78ecSespie }
10042159047fSniklas case 'P':
10052159047fSniklas (*info->fprintf_func) (info->stream, "%d",
10062159047fSniklas GET_FIELD (insn, 22, 26));
10072159047fSniklas break;
1008f7cc78ecSespie case 'q':
1009f7cc78ecSespie {
1010f7cc78ecSespie int num;
1011f7cc78ecSespie num = GET_FIELD (insn, 20, 20) << 5;
1012f7cc78ecSespie num |= GET_FIELD (insn, 22, 26);
1013f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d", num);
1014f7cc78ecSespie break;
1015f7cc78ecSespie }
10162159047fSniklas case 'T':
10172159047fSniklas (*info->fprintf_func) (info->stream, "%d",
10182159047fSniklas 32 - GET_FIELD (insn, 27, 31));
10192159047fSniklas break;
1020f7cc78ecSespie case '%':
1021f7cc78ecSespie {
1022f7cc78ecSespie int num;
1023f7cc78ecSespie num = (GET_FIELD (insn, 23, 23) + 1) * 32;
1024f7cc78ecSespie num -= GET_FIELD (insn, 27, 31);
1025f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d", num);
1026f7cc78ecSespie break;
1027f7cc78ecSespie }
1028f7cc78ecSespie case '|':
1029f7cc78ecSespie {
1030f7cc78ecSespie int num;
1031f7cc78ecSespie num = (GET_FIELD (insn, 19, 19) + 1) * 32;
1032f7cc78ecSespie num -= GET_FIELD (insn, 27, 31);
1033f7cc78ecSespie (*info->fprintf_func) (info->stream, "%d", num);
1034f7cc78ecSespie break;
1035f7cc78ecSespie }
1036f7cc78ecSespie case '$':
1037f7cc78ecSespie fput_const (GET_FIELD (insn, 20, 28), info);
1038f7cc78ecSespie break;
10392159047fSniklas case 'A':
10402159047fSniklas fput_const (GET_FIELD (insn, 6, 18), info);
10412159047fSniklas break;
10422159047fSniklas case 'D':
10432159047fSniklas fput_const (GET_FIELD (insn, 6, 31), info);
10442159047fSniklas break;
1045f7cc78ecSespie case 'v':
1046*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, ",%d",
1047*c074d1c9Sdrahn GET_FIELD (insn, 23, 25));
10482159047fSniklas break;
10492159047fSniklas case 'O':
10502159047fSniklas fput_const ((GET_FIELD (insn, 6,20) << 5 |
10512159047fSniklas GET_FIELD (insn, 27, 31)), info);
10522159047fSniklas break;
10532159047fSniklas case 'o':
10542159047fSniklas fput_const (GET_FIELD (insn, 6, 20), info);
10552159047fSniklas break;
10562159047fSniklas case '2':
10572159047fSniklas fput_const ((GET_FIELD (insn, 6, 22) << 5 |
10582159047fSniklas GET_FIELD (insn, 27, 31)), info);
10592159047fSniklas break;
10602159047fSniklas case '1':
10612159047fSniklas fput_const ((GET_FIELD (insn, 11, 20) << 5 |
10622159047fSniklas GET_FIELD (insn, 27, 31)), info);
10632159047fSniklas break;
10642159047fSniklas case '0':
10652159047fSniklas fput_const ((GET_FIELD (insn, 16, 20) << 5 |
10662159047fSniklas GET_FIELD (insn, 27, 31)), info);
10672159047fSniklas break;
10682159047fSniklas case 'u':
1069*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, ",%d",
1070*c074d1c9Sdrahn GET_FIELD (insn, 23, 25));
10712159047fSniklas break;
10722159047fSniklas case 'F':
10732159047fSniklas /* if no destination completer and not before a completer
10742159047fSniklas for fcmp, need a space here */
1075f7cc78ecSespie if (s[1] == 'G' || s[1] == '?')
1076*c074d1c9Sdrahn fputs_filtered
1077*c074d1c9Sdrahn (float_format_names[GET_FIELD (insn, 19, 20)], info);
10782159047fSniklas else
1079*c074d1c9Sdrahn (*info->fprintf_func)
1080*c074d1c9Sdrahn (info->stream, "%s ",
1081*c074d1c9Sdrahn float_format_names[GET_FIELD (insn, 19, 20)]);
10822159047fSniklas break;
10832159047fSniklas case 'G':
1084*c074d1c9Sdrahn (*info->fprintf_func)
1085*c074d1c9Sdrahn (info->stream, "%s ",
1086*c074d1c9Sdrahn float_format_names[GET_FIELD (insn, 17, 18)]);
10872159047fSniklas break;
10882159047fSniklas case 'H':
10892159047fSniklas if (GET_FIELD (insn, 26, 26) == 1)
10902159047fSniklas (*info->fprintf_func) (info->stream, "%s ",
10912159047fSniklas float_format_names[0]);
10922159047fSniklas else
10932159047fSniklas (*info->fprintf_func) (info->stream, "%s ",
10942159047fSniklas float_format_names[1]);
10952159047fSniklas break;
10962159047fSniklas case 'I':
10972159047fSniklas /* if no destination completer and not before a completer
10982159047fSniklas for fcmp, need a space here */
1099f7cc78ecSespie if (s[1] == '?')
1100*c074d1c9Sdrahn fputs_filtered
1101*c074d1c9Sdrahn (float_format_names[GET_FIELD (insn, 20, 20)], info);
11022159047fSniklas else
1103*c074d1c9Sdrahn (*info->fprintf_func)
1104*c074d1c9Sdrahn (info->stream, "%s ",
1105*c074d1c9Sdrahn float_format_names[GET_FIELD (insn, 20, 20)]);
11062159047fSniklas break;
11072159047fSniklas
1108f7cc78ecSespie case 'J':
1109f7cc78ecSespie fput_const (extract_14 (insn), info);
11102159047fSniklas break;
1111f7cc78ecSespie
1112f7cc78ecSespie case '#':
1113f7cc78ecSespie {
1114f7cc78ecSespie int sign = GET_FIELD (insn, 31, 31);
1115f7cc78ecSespie int imm10 = GET_FIELD (insn, 18, 27);
1116f7cc78ecSespie int disp;
1117f7cc78ecSespie
1118f7cc78ecSespie if (sign)
1119f7cc78ecSespie disp = (-1 << 10) | imm10;
11202159047fSniklas else
1121f7cc78ecSespie disp = imm10;
1122f7cc78ecSespie
1123f7cc78ecSespie disp <<= 3;
1124f7cc78ecSespie fput_const (disp, info);
11252159047fSniklas break;
1126f7cc78ecSespie }
1127f7cc78ecSespie case 'K':
1128f7cc78ecSespie case 'd':
1129f7cc78ecSespie {
1130f7cc78ecSespie int sign = GET_FIELD (insn, 31, 31);
1131f7cc78ecSespie int imm11 = GET_FIELD (insn, 18, 28);
1132f7cc78ecSespie int disp;
1133f7cc78ecSespie
1134f7cc78ecSespie if (sign)
1135f7cc78ecSespie disp = (-1 << 11) | imm11;
1136f7cc78ecSespie else
1137f7cc78ecSespie disp = imm11;
1138f7cc78ecSespie
1139f7cc78ecSespie disp <<= 2;
1140f7cc78ecSespie fput_const (disp, info);
1141f7cc78ecSespie break;
1142f7cc78ecSespie }
1143f7cc78ecSespie
1144b55d4692Sfgsch case '>':
1145b55d4692Sfgsch case 'y':
1146b55d4692Sfgsch {
1147b55d4692Sfgsch /* 16-bit long disp., PA2.0 wide only. */
1148b55d4692Sfgsch int disp = extract_16 (insn);
1149b55d4692Sfgsch disp &= ~3;
1150b55d4692Sfgsch fput_const (disp, info);
1151b55d4692Sfgsch break;
1152b55d4692Sfgsch }
1153b55d4692Sfgsch
1154b55d4692Sfgsch case '&':
1155b55d4692Sfgsch {
1156b55d4692Sfgsch /* 16-bit long disp., PA2.0 wide only. */
1157b55d4692Sfgsch int disp = extract_16 (insn);
1158b55d4692Sfgsch disp &= ~7;
1159b55d4692Sfgsch fput_const (disp, info);
1160b55d4692Sfgsch break;
1161b55d4692Sfgsch }
1162b55d4692Sfgsch
1163f7cc78ecSespie case '_':
1164*c074d1c9Sdrahn break; /* Dealt with by '{' */
1165*c074d1c9Sdrahn
1166f7cc78ecSespie case '{':
1167*c074d1c9Sdrahn {
1168*c074d1c9Sdrahn int sub = GET_FIELD (insn, 14, 16);
1169*c074d1c9Sdrahn int df = GET_FIELD (insn, 17, 18);
1170*c074d1c9Sdrahn int sf = GET_FIELD (insn, 19, 20);
1171*c074d1c9Sdrahn const char * const * source = float_format_names;
1172*c074d1c9Sdrahn const char * const * dest = float_format_names;
1173*c074d1c9Sdrahn char *t = "";
1174*c074d1c9Sdrahn if (sub == 4)
1175*c074d1c9Sdrahn {
1176*c074d1c9Sdrahn fputs_filtered (",UND ", info);
1177f7cc78ecSespie break;
1178*c074d1c9Sdrahn }
1179*c074d1c9Sdrahn if ((sub & 3) == 3)
1180*c074d1c9Sdrahn t = ",t";
1181*c074d1c9Sdrahn if ((sub & 3) == 1)
1182*c074d1c9Sdrahn source = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
1183*c074d1c9Sdrahn if (sub & 2)
1184*c074d1c9Sdrahn dest = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
1185*c074d1c9Sdrahn
1186*c074d1c9Sdrahn (*info->fprintf_func) (info->stream, "%s%s%s ",
1187*c074d1c9Sdrahn t, source[sf], dest[df]);
1188*c074d1c9Sdrahn break;
1189*c074d1c9Sdrahn }
1190f7cc78ecSespie
1191f7cc78ecSespie case 'm':
1192f7cc78ecSespie {
1193f7cc78ecSespie int y = GET_FIELD (insn, 16, 18);
1194f7cc78ecSespie
1195f7cc78ecSespie if (y != 1)
1196f7cc78ecSespie fput_const ((y ^ 1) - 1, info);
1197f7cc78ecSespie }
1198f7cc78ecSespie break;
1199f7cc78ecSespie
1200f7cc78ecSespie case 'h':
1201f7cc78ecSespie {
1202f7cc78ecSespie int cbit;
1203f7cc78ecSespie
1204f7cc78ecSespie cbit = GET_FIELD (insn, 16, 18);
1205f7cc78ecSespie
1206f7cc78ecSespie if (cbit > 0)
1207f7cc78ecSespie (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1208f7cc78ecSespie break;
1209f7cc78ecSespie }
1210f7cc78ecSespie
1211f7cc78ecSespie case '=':
1212f7cc78ecSespie {
1213f7cc78ecSespie int cond = GET_FIELD (insn, 27, 31);
1214f7cc78ecSespie
1215f7cc78ecSespie if (cond == 0)
1216f7cc78ecSespie fputs_filtered (" ", info);
1217f7cc78ecSespie else if (cond == 1)
1218f7cc78ecSespie fputs_filtered ("acc ", info);
1219f7cc78ecSespie else if (cond == 2)
1220f7cc78ecSespie fputs_filtered ("rej ", info);
1221f7cc78ecSespie else if (cond == 5)
1222f7cc78ecSespie fputs_filtered ("acc8 ", info);
1223f7cc78ecSespie else if (cond == 6)
1224f7cc78ecSespie fputs_filtered ("rej8 ", info);
1225f7cc78ecSespie else if (cond == 9)
1226f7cc78ecSespie fputs_filtered ("acc6 ", info);
1227f7cc78ecSespie else if (cond == 13)
1228f7cc78ecSespie fputs_filtered ("acc4 ", info);
1229f7cc78ecSespie else if (cond == 17)
1230f7cc78ecSespie fputs_filtered ("acc2 ", info);
1231f7cc78ecSespie break;
1232f7cc78ecSespie }
1233f7cc78ecSespie
1234f7cc78ecSespie case 'X':
1235*c074d1c9Sdrahn (*info->print_address_func)
1236*c074d1c9Sdrahn (memaddr + 8 + extract_22 (insn), info);
1237f7cc78ecSespie break;
1238f7cc78ecSespie case 'L':
1239f7cc78ecSespie fputs_filtered (",%r2", info);
12402159047fSniklas break;
12412159047fSniklas default:
12422159047fSniklas (*info->fprintf_func) (info->stream, "%c", *s);
12432159047fSniklas break;
12442159047fSniklas }
12452159047fSniklas }
12462159047fSniklas return sizeof(insn);
12472159047fSniklas }
12482159047fSniklas }
12492159047fSniklas (*info->fprintf_func) (info->stream, "#%8x", insn);
12502159047fSniklas return sizeof(insn);
12512159047fSniklas }
1252