]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/hppa-dis.c
* hppa.h (call, ret): Move to end of table.
[thirdparty/binutils-gdb.git] / opcodes / hppa-dis.c
CommitLineData
252b5132 1/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
060d22b0 2 Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
6e09abd4 3 Free Software Foundation, Inc.
252b5132
RH
4
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
252b5132
RH
22#include "sysdep.h"
23#include "dis-asm.h"
24#include "libhppa.h"
25#include "opcode/hppa.h"
26
27/* Integer register names, indexed by the numbers which appear in the
28 opcodes. */
29static const char *const reg_names[] =
30 {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
31 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
32 "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
33 "sp", "r31"};
34
35/* Floating point register names, indexed by the numbers which appear in the
36 opcodes. */
37static const char *const fp_reg_names[] =
38 {"fpsr", "fpe2", "fpe4", "fpe6",
39 "fr4", "fr5", "fr6", "fr7", "fr8",
40 "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
41 "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
42 "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
43
44typedef unsigned int CORE_ADDR;
45
91b1cc5d 46/* Get at various relevent fields of an instruction word. */
252b5132
RH
47
48#define MASK_5 0x1f
3b67cf2b 49#define MASK_10 0x3ff
252b5132
RH
50#define MASK_11 0x7ff
51#define MASK_14 0x3fff
91b1cc5d 52#define MASK_16 0xffff
252b5132
RH
53#define MASK_21 0x1fffff
54
6e09abd4 55/* These macros get bit fields using HP's numbering (MSB = 0) */
252b5132
RH
56
57#define GET_FIELD(X, FROM, TO) \
58 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
59
6e09abd4
AM
60#define GET_BIT(X, WHICH) \
61 GET_FIELD (X, WHICH, WHICH)
62
252b5132
RH
63/* Some of these have been converted to 2-d arrays because they
64 consume less storage this way. If the maintenance becomes a
65 problem, convert them back to const 1-d pointer arrays. */
58d0c905 66static const char *const control_reg[] = {
252b5132
RH
67 "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
68 "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
69 "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
70 "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
71 "tr4", "tr5", "tr6", "tr7"
72};
73
58d0c905 74static const char *const compare_cond_names[] = {
b333b6c6
JL
75 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
76 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
77};
58d0c905 78static const char *const compare_cond_64_names[] = {
b333b6c6
JL
79 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
80 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
81};
58d0c905 82static const char *const cmpib_cond_64_names[] = {
b333b6c6 83 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
252b5132 84};
58d0c905 85static const char *const add_cond_names[] = {
b333b6c6
JL
86 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
87 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
88};
58d0c905 89static const char *const add_cond_64_names[] = {
d1e9bd1f 90 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
b333b6c6
JL
91 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
92};
58d0c905 93static const char *const wide_add_cond_names[] = {
b333b6c6
JL
94 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
95 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
252b5132
RH
96};
97static const char *const logical_cond_names[] = {
98 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
99 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
b333b6c6 100static const char *const logical_cond_64_names[] = {
d1e9bd1f 101 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
b333b6c6 102 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
252b5132 103static const char *const unit_cond_names[] = {
61e8273b
JL
104 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
105 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
252b5132 106};
b333b6c6 107static const char *const unit_cond_64_names[] = {
d1e9bd1f 108 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
b333b6c6
JL
109 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
110};
58d0c905 111static const char *const shift_cond_names[] = {
252b5132
RH
112 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
113};
58d0c905 114static const char *const shift_cond_64_names[] = {
d1e9bd1f 115 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
b333b6c6 116};
58d0c905 117static const char *const bb_cond_64_names[] = {
b333b6c6
JL
118 ",*<", ",*>="
119};
58d0c905
JL
120static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
121static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
252b5132
RH
122static const char *const short_bytes_compl_names[] = {
123 "", ",b,m", ",e", ",e,m"
124};
125static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
58d0c905 126static const char *const float_comp_names[] =
252b5132
RH
127{
128 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
129 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
130 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
131 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
132};
58d0c905
JL
133static const char *const signed_unsigned_names[] = {",u", ",s"};
134static const char *const mix_half_names[] = {",l", ",r"};
135static const char *const saturation_names[] = {",us", ",ss", 0, ""};
136static const char *const read_write_names[] = {",r", ",w"};
137static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
252b5132
RH
138
139/* For a bunch of different instructions form an index into a
91b1cc5d 140 completer name table. */
252b5132
RH
141#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
142 GET_FIELD (insn, 18, 18) << 1)
143
144#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
145 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
146
6e09abd4
AM
147static void fput_reg PARAMS ((unsigned int, disassemble_info *));
148static void fput_fp_reg PARAMS ((unsigned int, disassemble_info *));
149static void fput_fp_reg_r PARAMS ((unsigned int, disassemble_info *));
150static void fput_creg PARAMS ((unsigned int, disassemble_info *));
151static void fput_const PARAMS ((unsigned int, disassemble_info *));
152static int extract_3 PARAMS ((unsigned int));
153static int extract_5_load PARAMS ((unsigned int));
154static int extract_5_store PARAMS ((unsigned int));
155static unsigned extract_5r_store PARAMS ((unsigned int));
156static unsigned extract_5R_store PARAMS ((unsigned int));
157static unsigned extract_10U_store PARAMS ((unsigned int));
158static unsigned extract_5Q_store PARAMS ((unsigned int));
159static int extract_11 PARAMS ((unsigned int));
160static int extract_14 PARAMS ((unsigned int));
161static int extract_16 PARAMS ((unsigned int));
162static int extract_21 PARAMS ((unsigned int));
163static int extract_12 PARAMS ((unsigned int));
164static int extract_17 PARAMS ((unsigned int));
165static int extract_22 PARAMS ((unsigned int));
166
252b5132
RH
167/* Utility function to print registers. Put these first, so gcc's function
168 inlining can do its stuff. */
169
170#define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
171
172static void
173fput_reg (reg, info)
174 unsigned reg;
175 disassemble_info *info;
176{
177 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
178}
179
180static void
181fput_fp_reg (reg, info)
182 unsigned reg;
183 disassemble_info *info;
184{
185 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
186}
187
188static void
189fput_fp_reg_r (reg, info)
190 unsigned reg;
191 disassemble_info *info;
192{
193 /* Special case floating point exception registers. */
194 if (reg < 4)
195 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
196 else
197 (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg]
198 : "fr0");
199}
200
201static void
202fput_creg (reg, info)
203 unsigned reg;
204 disassemble_info *info;
205{
206 (*info->fprintf_func) (info->stream, control_reg[reg]);
207}
208
91b1cc5d 209/* Print constants with sign. */
252b5132
RH
210
211static void
212fput_const (num, info)
213 unsigned num;
214 disassemble_info *info;
215{
216 if ((int)num < 0)
217 (*info->fprintf_func) (info->stream, "-%x", -(int)num);
218 else
219 (*info->fprintf_func) (info->stream, "%x", num);
220}
221
222/* Routines to extract various sized constants out of hppa
91b1cc5d 223 instructions. */
252b5132 224
91b1cc5d 225/* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */
252b5132
RH
226static int
227extract_3 (word)
228 unsigned word;
229{
230 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
231}
232
233static int
234extract_5_load (word)
235 unsigned word;
236{
237 return low_sign_extend (word >> 16 & MASK_5, 5);
238}
239
91b1cc5d 240/* Extract the immediate field from a st{bhw}s instruction. */
252b5132
RH
241static int
242extract_5_store (word)
243 unsigned word;
244{
245 return low_sign_extend (word & MASK_5, 5);
246}
247
91b1cc5d 248/* Extract the immediate field from a break instruction. */
252b5132
RH
249static unsigned
250extract_5r_store (word)
251 unsigned word;
252{
253 return (word & MASK_5);
254}
255
91b1cc5d 256/* Extract the immediate field from a {sr}sm instruction. */
252b5132
RH
257static unsigned
258extract_5R_store (word)
259 unsigned word;
260{
261 return (word >> 16 & MASK_5);
262}
263
91b1cc5d 264/* Extract the 10 bit immediate field from a {sr}sm instruction. */
3b67cf2b
JL
265static unsigned
266extract_10U_store (word)
267 unsigned word;
268{
269 return (word >> 16 & MASK_10);
270}
271
91b1cc5d 272/* Extract the immediate field from a bb instruction. */
252b5132
RH
273static unsigned
274extract_5Q_store (word)
275 unsigned word;
276{
277 return (word >> 21 & MASK_5);
278}
279
91b1cc5d 280/* Extract an 11 bit immediate field. */
252b5132
RH
281static int
282extract_11 (word)
283 unsigned word;
284{
285 return low_sign_extend (word & MASK_11, 11);
286}
287
91b1cc5d 288/* Extract a 14 bit immediate field. */
252b5132
RH
289static int
290extract_14 (word)
291 unsigned word;
292{
293 return low_sign_extend (word & MASK_14, 14);
294}
295
91b1cc5d
JL
296/* Extract a 16 bit immediate field (PA2.0 wide only). */
297static int
298extract_16 (word)
299 unsigned word;
300{
301 int m15, m0, m1;
302 m0 = GET_BIT (word, 16);
303 m1 = GET_BIT (word, 17);
304 m15 = GET_BIT (word, 31);
305 word = (word >> 1) & 0x1fff;
306 word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
307 return sign_extend (word, 16);
308}
309
310/* Extract a 21 bit constant. */
252b5132
RH
311
312static int
313extract_21 (word)
314 unsigned word;
315{
316 int val;
317
318 word &= MASK_21;
319 word <<= 11;
320 val = GET_FIELD (word, 20, 20);
321 val <<= 11;
322 val |= GET_FIELD (word, 9, 19);
323 val <<= 2;
324 val |= GET_FIELD (word, 5, 6);
325 val <<= 5;
326 val |= GET_FIELD (word, 0, 4);
327 val <<= 2;
328 val |= GET_FIELD (word, 7, 8);
329 return sign_extend (val, 21) << 11;
330}
331
91b1cc5d 332/* Extract a 12 bit constant from branch instructions. */
252b5132
RH
333
334static int
335extract_12 (word)
336 unsigned word;
337{
338 return sign_extend (GET_FIELD (word, 19, 28) |
339 GET_FIELD (word, 29, 29) << 10 |
340 (word & 0x1) << 11, 12) << 2;
341}
342
91b1cc5d
JL
343/* Extract a 17 bit constant from branch instructions, returning the
344 19 bit signed value. */
252b5132
RH
345
346static int
347extract_17 (word)
348 unsigned word;
349{
350 return sign_extend (GET_FIELD (word, 19, 28) |
351 GET_FIELD (word, 29, 29) << 10 |
352 GET_FIELD (word, 11, 15) << 11 |
353 (word & 0x1) << 16, 17) << 2;
354}
355
b3fe7ee2
JL
356static int
357extract_22 (word)
358 unsigned word;
359{
360 return sign_extend (GET_FIELD (word, 19, 28) |
361 GET_FIELD (word, 29, 29) << 10 |
362 GET_FIELD (word, 11, 15) << 11 |
363 GET_FIELD (word, 6, 10) << 16 |
364 (word & 0x1) << 21, 22) << 2;
365}
366
252b5132
RH
367/* Print one instruction. */
368int
369print_insn_hppa (memaddr, info)
370 bfd_vma memaddr;
371 disassemble_info *info;
372{
373 bfd_byte buffer[4];
374 unsigned int insn, i;
375
376 {
377 int status =
378 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
379 if (status != 0)
380 {
381 (*info->memory_error_func) (status, memaddr, info);
382 return -1;
383 }
384 }
385
386 insn = bfd_getb32 (buffer);
387
388 for (i = 0; i < NUMOPCODES; ++i)
389 {
390 const struct pa_opcode *opcode = &pa_opcodes[i];
391 if ((insn & opcode->mask) == opcode->match)
392 {
393 register const char *s;
91b1cc5d
JL
394#ifndef BFD64
395 if (opcode->arch == pa20w)
396 continue;
397#endif
252b5132
RH
398 (*info->fprintf_func) (info->stream, "%s", opcode->name);
399
46e36b17 400 if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0]))
252b5132
RH
401 (*info->fprintf_func) (info->stream, " ");
402 for (s = opcode->args; *s != '\0'; ++s)
403 {
404 switch (*s)
405 {
406 case 'x':
407 fput_reg (GET_FIELD (insn, 11, 15), info);
408 break;
1eee34f5 409 case 'a':
252b5132
RH
410 case 'b':
411 fput_reg (GET_FIELD (insn, 6, 10), info);
412 break;
413 case '^':
414 fput_creg (GET_FIELD (insn, 6, 10), info);
415 break;
252b5132
RH
416 case 't':
417 fput_reg (GET_FIELD (insn, 27, 31), info);
418 break;
a349b151
JL
419
420 /* Handle floating point registers. */
421 case 'f':
422 switch (*++s)
423 {
424 case 't':
252b5132 425 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
a349b151
JL
426 break;
427 case 'T':
428 if (GET_FIELD (insn, 25, 25))
429 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
430 else
431 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
432 break;
433 case 'a':
434 if (GET_FIELD (insn, 25, 25))
435 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
436 else
437 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
438 break;
debc018d
JL
439
440 /* 'fA' will not generate a space before the regsiter
441 name. Normally that is fine. Except that it
442 causes problems with xmpyu which has no FP format
443 completer. */
444 case 'X':
445 fputs_filtered (" ", info);
446
447 /* FALLTHRU */
448
a349b151
JL
449 case 'A':
450 if (GET_FIELD (insn, 24, 24))
451 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
452 else
453 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
454
455 break;
456 case 'b':
457 if (GET_FIELD (insn, 25, 25))
458 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
459 else
460 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
461 break;
462 case 'B':
463 if (GET_FIELD (insn, 19, 19))
464 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
465 else
466 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
467 break;
468 case 'C':
469 {
470 int reg = GET_FIELD (insn, 21, 22);
471 reg |= GET_FIELD (insn, 16, 18) << 2;
472 if (GET_FIELD (insn, 23, 23) != 0)
473 fput_fp_reg_r (reg, info);
474 else
475 fput_fp_reg (reg, info);
476 break;
477 }
478 case 'i':
479 {
480 int reg = GET_FIELD (insn, 6, 10);
252b5132 481
a349b151
JL
482 reg |= (GET_FIELD (insn, 26, 26) << 4);
483 fput_fp_reg (reg, info);
484 break;
485 }
486 case 'j':
487 {
488 int reg = GET_FIELD (insn, 11, 15);
252b5132 489
a349b151
JL
490 reg |= (GET_FIELD (insn, 26, 26) << 4);
491 fput_fp_reg (reg, info);
492 break;
493 }
494 case 'k':
495 {
496 int reg = GET_FIELD (insn, 27, 31);
252b5132 497
a349b151
JL
498 reg |= (GET_FIELD (insn, 26, 26) << 4);
499 fput_fp_reg (reg, info);
500 break;
501 }
502 case 'l':
503 {
504 int reg = GET_FIELD (insn, 21, 25);
252b5132 505
a349b151
JL
506 reg |= (GET_FIELD (insn, 26, 26) << 4);
507 fput_fp_reg (reg, info);
508 break;
509 }
510 case 'm':
511 {
512 int reg = GET_FIELD (insn, 16, 20);
513
514 reg |= (GET_FIELD (insn, 26, 26) << 4);
515 fput_fp_reg (reg, info);
516 break;
517 }
91b1cc5d
JL
518
519 /* 'fe' will not generate a space before the register
520 name. Normally that is fine. Except that it
521 causes problems with fstw fe,y(b) which has no FP
522 format completer. */
523 case 'E':
524 fputs_filtered (" ", info);
525
526 /* FALLTHRU */
527
f322c2c2 528 case 'e':
91b1cc5d 529 if (GET_FIELD (insn, 30, 30))
f322c2c2
JL
530 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
531 else
532 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
533 break;
91b1cc5d
JL
534 case 'x':
535 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
536 break;
a349b151 537 }
2f87f883 538 break;
252b5132 539
252b5132
RH
540 case '5':
541 fput_const (extract_5_load (insn), info);
542 break;
543 case 's':
544 (*info->fprintf_func) (info->stream,
545 "sr%d", GET_FIELD (insn, 16, 17));
546 break;
b333b6c6 547
252b5132
RH
548 case 'S':
549 (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
550 break;
3281117a
JL
551
552 /* Handle completers. */
252b5132 553 case 'c':
3281117a
JL
554 switch (*++s)
555 {
556 case 'x':
557 (*info->fprintf_func) (info->stream, "%s ",
558 index_compl_names[GET_COMPL (insn)]);
559 break;
560 case 'm':
561 (*info->fprintf_func) (info->stream, "%s ",
562 short_ldst_compl_names[GET_COMPL (insn)]);
563 break;
564 case 's':
565 (*info->fprintf_func) (info->stream, "%s ",
566 short_bytes_compl_names[GET_COMPL (insn)]);
567 break;
1c170bd8
JL
568 case 'c':
569 case 'C':
570 switch (GET_FIELD (insn, 20, 21))
571 {
572 case 1:
573 (*info->fprintf_func) (info->stream, ",bc ");
574 break;
575 case 2:
576 (*info->fprintf_func) (info->stream, ",sl ");
577 break;
578 default:
579 (*info->fprintf_func) (info->stream, " ");
580 }
581 break;
582 case 'd':
583 switch (GET_FIELD (insn, 20, 21))
584 {
585 case 1:
586 (*info->fprintf_func) (info->stream, ",co ");
587 break;
588 default:
589 (*info->fprintf_func) (info->stream, " ");
590 }
591 break;
592 case 'o':
593 (*info->fprintf_func) (info->stream, ",o");
594 break;
1fb72ed1
JL
595 case 'g':
596 (*info->fprintf_func) (info->stream, ",gate");
1c170bd8 597 break;
1fb72ed1
JL
598 case 'p':
599 (*info->fprintf_func) (info->stream, ",l,push");
600 break;
601 case 'P':
602 (*info->fprintf_func) (info->stream, ",pop");
603 break;
604 case 'l':
3b67cf2b
JL
605 case 'L':
606 (*info->fprintf_func) (info->stream, ",l");
607 break;
608 case 'w':
609 (*info->fprintf_func) (info->stream, "%s ",
610 read_write_names[GET_FIELD (insn, 25, 25)]);
611 break;
612 case 'W':
613 (*info->fprintf_func) (info->stream, ",w");
614 break;
615 case 'r':
616 if (GET_FIELD (insn, 23, 26) == 5)
617 (*info->fprintf_func) (info->stream, ",r");
618 break;
3281117a
JL
619 case 'Z':
620 if (GET_FIELD (insn, 26, 26))
621 (*info->fprintf_func) (info->stream, ",m ");
622 else
623 (*info->fprintf_func) (info->stream, " ");
624 break;
3b67cf2b
JL
625 case 'i':
626 if (GET_FIELD (insn, 25, 25))
627 (*info->fprintf_func) (info->stream, ",i");
628 break;
af10de82
JL
629 case 'z':
630 if (!GET_FIELD (insn, 21, 21))
631 (*info->fprintf_func) (info->stream, ",z");
632 break;
3b67cf2b
JL
633 case 'a':
634 (*info->fprintf_func)
635 (info->stream, "%s", add_compl_names[GET_FIELD
636 (insn, 20, 21)]);
637 break;
638 case 'Y':
639 (*info->fprintf_func)
640 (info->stream, ",dc%s", add_compl_names[GET_FIELD
641 (insn, 20, 21)]);
642 break;
643 case 'y':
644 (*info->fprintf_func)
645 (info->stream, ",c%s", add_compl_names[GET_FIELD
646 (insn, 20, 21)]);
647 break;
648 case 'v':
649 if (GET_FIELD (insn, 20, 20))
650 (*info->fprintf_func) (info->stream, ",tsv");
651 break;
652 case 't':
653 (*info->fprintf_func) (info->stream, ",tc");
654 if (GET_FIELD (insn, 20, 20))
655 (*info->fprintf_func) (info->stream, ",tsv");
656 break;
657 case 'B':
658 (*info->fprintf_func) (info->stream, ",db");
659 if (GET_FIELD (insn, 20, 20))
660 (*info->fprintf_func) (info->stream, ",tsv");
661 break;
662 case 'b':
663 (*info->fprintf_func) (info->stream, ",b");
664 if (GET_FIELD (insn, 20, 20))
665 (*info->fprintf_func) (info->stream, ",tsv");
666 break;
667 case 'T':
668 if (GET_FIELD (insn, 25, 25))
669 (*info->fprintf_func) (info->stream, ",tc");
670 break;
1eee34f5
JL
671 case 'S':
672 /* EXTRD/W has a following condition. */
673 if (*(s + 1) == '?')
674 (*info->fprintf_func)
675 (info->stream, "%s", signed_unsigned_names[GET_FIELD
676 (insn, 21, 21)]);
677 else
678 (*info->fprintf_func)
679 (info->stream, "%s ", signed_unsigned_names[GET_FIELD
680 (insn, 21, 21)]);
681 break;
682 case 'h':
683 (*info->fprintf_func)
684 (info->stream, "%s", mix_half_names[GET_FIELD
685 (insn, 17, 17)]);
686 break;
687 case 'H':
688 (*info->fprintf_func)
689 (info->stream, "%s", saturation_names[GET_FIELD
690 (insn, 24, 25)]);
691 break;
692 case '*':
693 (*info->fprintf_func)
694 (info->stream, ",%d%d%d%d ",
695 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
696 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
697 break;
9c1faa82
JL
698
699 case 'q':
700 {
701 int m, a;
702
703 m = GET_FIELD (insn, 28, 28);
704 a = GET_FIELD (insn, 29, 29);
705
706 if (m && !a)
707 fputs_filtered (",ma ", info);
708 else if (m && a)
709 fputs_filtered (",mb ", info);
710 else
711 fputs_filtered (" ", info);
712 break;
713 }
714
715 case 'J':
716 {
6e09abd4 717 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 718
6e09abd4 719 if (opc == 0x16 || opc == 0x1e)
9c1faa82
JL
720 {
721 if (GET_FIELD (insn, 29, 29) == 0)
722 fputs_filtered (",ma ", info);
723 else
724 fputs_filtered (",mb ", info);
725 }
726 else
727 fputs_filtered (" ", info);
728 break;
729 }
730
1c170bd8 731 case 'e':
9c1faa82 732 {
6e09abd4 733 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 734
6e09abd4 735 if (opc == 0x13 || opc == 0x1b)
9c1faa82
JL
736 {
737 if (GET_FIELD (insn, 18, 18) == 1)
738 fputs_filtered (",mb ", info);
739 else
740 fputs_filtered (",ma ", info);
741 }
6e09abd4 742 else if (opc == 0x17 || opc == 0x1f)
9c1faa82
JL
743 {
744 if (GET_FIELD (insn, 31, 31) == 1)
745 fputs_filtered (",ma ", info);
746 else
747 fputs_filtered (",mb ", info);
748 }
749 else
750 fputs_filtered (" ", info);
751
752 break;
753 }
3281117a 754 }
252b5132 755 break;
feb12992
JL
756
757 /* Handle conditions. */
252b5132 758 case '?':
feb12992
JL
759 {
760 s++;
761 switch (*s)
762 {
763 case 'f':
764 (*info->fprintf_func) (info->stream, "%s ",
765 float_comp_names[GET_FIELD
766 (insn, 27, 31)]);
767 break;
768
769 /* these four conditions are for the set of instructions
770 which distinguish true/false conditions by opcode
771 rather than by the 'f' bit (sigh): comb, comib,
772 addb, addib */
773 case 't':
a349b151 774 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
feb12992
JL
775 info);
776 break;
1c170bd8 777 case 'n':
b333b6c6 778 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
1c170bd8 779 + GET_FIELD (insn, 4, 4) * 8], info);
b333b6c6 780 break;
1c170bd8 781 case 'N':
b333b6c6 782 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
1c170bd8 783 + GET_FIELD (insn, 2, 2) * 8], info);
b333b6c6
JL
784 break;
785 case 'Q':
786 fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
787 info);
788 break;
feb12992
JL
789 case '@':
790 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
791 + GET_FIELD (insn, 4, 4) * 8], info);
792 break;
793 case 's':
794 (*info->fprintf_func) (info->stream, "%s ",
795 compare_cond_names[GET_COND (insn)]);
796 break;
b333b6c6
JL
797 case 'S':
798 (*info->fprintf_func) (info->stream, "%s ",
799 compare_cond_64_names[GET_COND (insn)]);
800 break;
feb12992
JL
801 case 'a':
802 (*info->fprintf_func) (info->stream, "%s ",
803 add_cond_names[GET_COND (insn)]);
804 break;
b333b6c6
JL
805 case 'A':
806 (*info->fprintf_func) (info->stream, "%s ",
807 add_cond_64_names[GET_COND (insn)]);
808 break;
feb12992
JL
809 case 'd':
810 (*info->fprintf_func) (info->stream, "%s",
a349b151 811 add_cond_names[GET_FIELD (insn, 16, 18)]);
feb12992 812 break;
a349b151 813
b333b6c6 814 case 'W':
a349b151 815 (*info->fprintf_func)
b333b6c6 816 (info->stream, "%s",
1c170bd8
JL
817 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
818 GET_FIELD (insn, 4, 4) * 8]);
b333b6c6 819 break;
feb12992
JL
820
821 case 'l':
822 (*info->fprintf_func) (info->stream, "%s ",
823 logical_cond_names[GET_COND (insn)]);
824 break;
b333b6c6
JL
825 case 'L':
826 (*info->fprintf_func) (info->stream, "%s ",
827 logical_cond_64_names[GET_COND (insn)]);
828 break;
feb12992
JL
829 case 'u':
830 (*info->fprintf_func) (info->stream, "%s ",
831 unit_cond_names[GET_COND (insn)]);
832 break;
b333b6c6
JL
833 case 'U':
834 (*info->fprintf_func) (info->stream, "%s ",
835 unit_cond_64_names[GET_COND (insn)]);
836 break;
feb12992
JL
837 case 'y':
838 case 'x':
839 case 'b':
840 (*info->fprintf_func)
841 (info->stream, "%s",
842 shift_cond_names[GET_FIELD (insn, 16, 18)]);
843
844 /* If the next character in args is 'n', it will handle
845 putting out the space. */
846 if (s[1] != 'n')
847 (*info->fprintf_func) (info->stream, " ");
848 break;
b333b6c6 849 case 'X':
e46def7b 850 (*info->fprintf_func) (info->stream, "%s ",
b333b6c6
JL
851 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
852 break;
853 case 'B':
854 (*info->fprintf_func)
855 (info->stream, "%s",
856 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
feb12992 857
b333b6c6
JL
858 /* If the next character in args is 'n', it will handle
859 putting out the space. */
860 if (s[1] != 'n')
861 (*info->fprintf_func) (info->stream, " ");
862 break;
feb12992
JL
863 }
864 break;
865 }
252b5132 866
252b5132
RH
867 case 'V':
868 fput_const (extract_5_store (insn), info);
869 break;
870 case 'r':
871 fput_const (extract_5r_store (insn), info);
872 break;
873 case 'R':
874 fput_const (extract_5R_store (insn), info);
875 break;
3b67cf2b
JL
876 case 'U':
877 fput_const (extract_10U_store (insn), info);
878 break;
61e8273b 879 case 'B':
252b5132
RH
880 case 'Q':
881 fput_const (extract_5Q_store (insn), info);
882 break;
883 case 'i':
884 fput_const (extract_11 (insn), info);
885 break;
886 case 'j':
887 fput_const (extract_14 (insn), info);
888 break;
889 case 'k':
890 fput_const (extract_21 (insn), info);
891 break;
1328dc98 892 case '<':
91b1cc5d
JL
893 case 'l':
894 /* 16-bit long disp., PA2.0 wide only. */
895 fput_const (extract_16 (insn), info);
896 break;
252b5132
RH
897 case 'n':
898 if (insn & 0x2)
899 (*info->fprintf_func) (info->stream, ",n ");
900 else
901 (*info->fprintf_func) (info->stream, " ");
902 break;
903 case 'N':
904 if ((insn & 0x20) && s[1])
905 (*info->fprintf_func) (info->stream, ",n ");
906 else if (insn & 0x20)
907 (*info->fprintf_func) (info->stream, ",n");
908 else if (s[1])
909 (*info->fprintf_func) (info->stream, " ");
910 break;
911 case 'w':
912 (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
913 info);
914 break;
915 case 'W':
916 /* 17 bit PC-relative branch. */
917 (*info->print_address_func) ((memaddr + 8
918 + extract_17 (insn)),
919 info);
920 break;
921 case 'z':
922 /* 17 bit displacement. This is an offset from a register
923 so it gets disasssembled as just a number, not any sort
924 of address. */
925 fput_const (extract_17 (insn), info);
926 break;
d1e9bd1f
JL
927
928 case 'Z':
929 /* addil %r1 implicit output. */
2beaab59 930 (*info->fprintf_func) (info->stream, "%%r1");
d1e9bd1f 931 break;
1fb72ed1
JL
932
933 case 'Y':
934 /* be,l %sr0,%r31 implicit output. */
935 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
936 break;
d1e9bd1f 937
1c170bd8
JL
938 case '@':
939 (*info->fprintf_func) (info->stream, "0");
940 break;
941
46424e05
JL
942 case '.':
943 (*info->fprintf_func) (info->stream, "%d",
944 GET_FIELD (insn, 24, 25));
945 break;
3b67cf2b
JL
946 case '*':
947 (*info->fprintf_func) (info->stream, "%d",
948 GET_FIELD (insn, 22, 25));
949 break;
b7d6d485 950 case '!':
2beaab59 951 (*info->fprintf_func) (info->stream, "%%sar");
b7d6d485 952 break;
252b5132
RH
953 case 'p':
954 (*info->fprintf_func) (info->stream, "%d",
955 31 - GET_FIELD (insn, 22, 26));
956 break;
46424e05
JL
957 case '~':
958 {
959 int num;
960 num = GET_FIELD (insn, 20, 20) << 5;
961 num |= GET_FIELD (insn, 22, 26);
962 (*info->fprintf_func) (info->stream, "%d", 63 - num);
963 break;
964 }
252b5132
RH
965 case 'P':
966 (*info->fprintf_func) (info->stream, "%d",
967 GET_FIELD (insn, 22, 26));
968 break;
af10de82
JL
969 case 'q':
970 {
971 int num;
972 num = GET_FIELD (insn, 20, 20) << 5;
973 num |= GET_FIELD (insn, 22, 26);
974 (*info->fprintf_func) (info->stream, "%d", num);
975 break;
976 }
252b5132
RH
977 case 'T':
978 (*info->fprintf_func) (info->stream, "%d",
979 32 - GET_FIELD (insn, 27, 31));
980 break;
af10de82
JL
981 case '%':
982 {
983 int num;
984 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
985 num -= GET_FIELD (insn, 27, 31);
986 (*info->fprintf_func) (info->stream, "%d", num);
987 break;
988 }
989 case '|':
990 {
991 int num;
992 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
993 num -= GET_FIELD (insn, 27, 31);
994 (*info->fprintf_func) (info->stream, "%d", num);
995 break;
996 }
46424e05
JL
997 case '$':
998 fput_const (GET_FIELD (insn, 20, 28), info);
999 break;
252b5132
RH
1000 case 'A':
1001 fput_const (GET_FIELD (insn, 6, 18), info);
1002 break;
252b5132
RH
1003 case 'D':
1004 fput_const (GET_FIELD (insn, 6, 31), info);
1005 break;
a349b151 1006 case 'v':
252b5132
RH
1007 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1008 break;
1009 case 'O':
1010 fput_const ((GET_FIELD (insn, 6,20) << 5 |
1011 GET_FIELD (insn, 27, 31)), info);
1012 break;
1013 case 'o':
1014 fput_const (GET_FIELD (insn, 6, 20), info);
1015 break;
252b5132
RH
1016 case '2':
1017 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
1018 GET_FIELD (insn, 27, 31)), info);
1019 break;
1020 case '1':
1021 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
1022 GET_FIELD (insn, 27, 31)), info);
1023 break;
1024 case '0':
1025 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
1026 GET_FIELD (insn, 27, 31)), info);
1027 break;
1028 case 'u':
1029 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1030 break;
1031 case 'F':
1032 /* if no destination completer and not before a completer
1033 for fcmp, need a space here */
4f312591 1034 if (s[1] == 'G' || s[1] == '?')
252b5132
RH
1035 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
1036 info);
1037 else
1038 (*info->fprintf_func) (info->stream, "%s ",
1039 float_format_names[GET_FIELD
1040 (insn, 19, 20)]);
1041 break;
1042 case 'G':
1043 (*info->fprintf_func) (info->stream, "%s ",
1044 float_format_names[GET_FIELD (insn,
1045 17, 18)]);
1046 break;
1047 case 'H':
1048 if (GET_FIELD (insn, 26, 26) == 1)
1049 (*info->fprintf_func) (info->stream, "%s ",
1050 float_format_names[0]);
1051 else
1052 (*info->fprintf_func) (info->stream, "%s ",
1053 float_format_names[1]);
1054 break;
1055 case 'I':
1056 /* if no destination completer and not before a completer
1057 for fcmp, need a space here */
4f312591 1058 if (s[1] == '?')
252b5132
RH
1059 fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
1060 info);
1061 else
1062 (*info->fprintf_func) (info->stream, "%s ",
1063 float_format_names[GET_FIELD
1064 (insn, 20, 20)]);
1065 break;
eb32eb44
JL
1066
1067 case 'J':
1068 fput_const (extract_14 (insn), info);
1069 break;
1070
d758242c
JL
1071 case '#':
1072 {
1073 int sign = GET_FIELD (insn, 31, 31);
1074 int imm10 = GET_FIELD (insn, 18, 27);
1075 int disp;
1076
1077 if (sign)
1078 disp = (-1 << 10) | imm10;
1079 else
1080 disp = imm10;
1081
1082 disp <<= 3;
1083 fput_const (disp, info);
1084 break;
1085 }
eb32eb44 1086 case 'K':
d758242c
JL
1087 case 'd':
1088 {
1089 int sign = GET_FIELD (insn, 31, 31);
1090 int imm11 = GET_FIELD (insn, 18, 28);
1091 int disp;
1092
1093 if (sign)
1094 disp = (-1 << 11) | imm11;
1095 else
1096 disp = imm11;
1097
1098 disp <<= 2;
1099 fput_const (disp, info);
1100 break;
1101 }
1102
1328dc98 1103 case '>':
91b1cc5d
JL
1104 case 'y':
1105 {
1106 /* 16-bit long disp., PA2.0 wide only. */
1107 int disp = extract_16 (insn);
1108 disp &= ~3;
1109 fput_const (disp, info);
1110 break;
1111 }
1112
1113 case '&':
1114 {
1115 /* 16-bit long disp., PA2.0 wide only. */
1116 int disp = extract_16 (insn);
1117 disp &= ~7;
1118 fput_const (disp, info);
1119 break;
1120 }
1121
838c65f0
JL
1122 /* ?!? FIXME */
1123 case '_':
1124 case '{':
1125 fputs_filtered ("Disassembler botch.\n", info);
1126 break;
1127
1128 case 'm':
1129 {
1130 int y = GET_FIELD (insn, 16, 18);
1131
1132 if (y != 1)
1133 fput_const ((y ^ 1) - 1, info);
1134 }
1135 break;
1136
1137 case 'h':
1138 {
1139 int cbit;
1140
1141 cbit = GET_FIELD (insn, 16, 18);
1142
1143 if (cbit > 0)
1144 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1145 break;
1146 }
1147
1148 case '=':
1149 {
1150 int cond = GET_FIELD (insn, 27, 31);
1151
1152 if (cond == 0)
1153 fputs_filtered (" ", info);
1154 else if (cond == 1)
1155 fputs_filtered ("acc ", info);
1156 else if (cond == 2)
1157 fputs_filtered ("rej ", info);
1158 else if (cond == 5)
1159 fputs_filtered ("acc8 ", info);
1160 else if (cond == 6)
1161 fputs_filtered ("rej8 ", info);
1162 else if (cond == 9)
1163 fputs_filtered ("acc6 ", info);
1164 else if (cond == 13)
1165 fputs_filtered ("acc4 ", info);
1166 else if (cond == 17)
1167 fputs_filtered ("acc2 ", info);
1168 break;
1169 }
1170
3610d131
JL
1171 case 'X':
1172 (*info->print_address_func) ((memaddr + 8
1173 + extract_22 (insn)),
1174 info);
1175 break;
2784abe5
JL
1176 case 'L':
1177 fputs_filtered (",%r2", info);
1178 break;
252b5132
RH
1179 default:
1180 (*info->fprintf_func) (info->stream, "%c", *s);
1181 break;
1182 }
1183 }
1184 return sizeof(insn);
1185 }
1186 }
1187 (*info->fprintf_func) (info->stream, "#%8x", insn);
1188 return sizeof(insn);
1189}