gas/
[deliverable/binutils-gdb.git] / opcodes / hppa-dis.c
CommitLineData
252b5132 1/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
ca504dff 2 Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003
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
f4321104 20Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132 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. */
ca504dff 29static const char *const reg_names[] =
252b5132
RH
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. */
ca504dff
AM
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",
252b5132
RH
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"};
ca504dff
AM
126static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
127static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
58d0c905 128static const char *const float_comp_names[] =
252b5132
RH
129{
130 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
131 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
132 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
133 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
134};
58d0c905
JL
135static const char *const signed_unsigned_names[] = {",u", ",s"};
136static const char *const mix_half_names[] = {",l", ",r"};
137static const char *const saturation_names[] = {",us", ",ss", 0, ""};
138static const char *const read_write_names[] = {",r", ",w"};
139static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
252b5132 140
ca504dff 141/* For a bunch of different instructions form an index into a
91b1cc5d 142 completer name table. */
252b5132
RH
143#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
144 GET_FIELD (insn, 18, 18) << 1)
145
146#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
147 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
148
6e09abd4
AM
149static void fput_reg PARAMS ((unsigned int, disassemble_info *));
150static void fput_fp_reg PARAMS ((unsigned int, disassemble_info *));
151static void fput_fp_reg_r PARAMS ((unsigned int, disassemble_info *));
152static void fput_creg PARAMS ((unsigned int, disassemble_info *));
153static void fput_const PARAMS ((unsigned int, disassemble_info *));
154static int extract_3 PARAMS ((unsigned int));
155static int extract_5_load PARAMS ((unsigned int));
156static int extract_5_store PARAMS ((unsigned int));
157static unsigned extract_5r_store PARAMS ((unsigned int));
158static unsigned extract_5R_store PARAMS ((unsigned int));
159static unsigned extract_10U_store PARAMS ((unsigned int));
160static unsigned extract_5Q_store PARAMS ((unsigned int));
161static int extract_11 PARAMS ((unsigned int));
162static int extract_14 PARAMS ((unsigned int));
163static int extract_16 PARAMS ((unsigned int));
164static int extract_21 PARAMS ((unsigned int));
165static int extract_12 PARAMS ((unsigned int));
166static int extract_17 PARAMS ((unsigned int));
167static int extract_22 PARAMS ((unsigned int));
168
252b5132
RH
169/* Utility function to print registers. Put these first, so gcc's function
170 inlining can do its stuff. */
171
172#define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
173
174static void
175fput_reg (reg, info)
176 unsigned reg;
177 disassemble_info *info;
178{
179 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
180}
181
182static void
183fput_fp_reg (reg, info)
184 unsigned reg;
185 disassemble_info *info;
186{
187 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
188}
189
190static void
191fput_fp_reg_r (reg, info)
192 unsigned reg;
193 disassemble_info *info;
194{
195 /* Special case floating point exception registers. */
196 if (reg < 4)
197 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
198 else
ca504dff
AM
199 (*info->fprintf_func) (info->stream, "%sR",
200 reg ? fp_reg_names[reg] : "fr0");
252b5132
RH
201}
202
203static void
204fput_creg (reg, info)
205 unsigned reg;
206 disassemble_info *info;
207{
208 (*info->fprintf_func) (info->stream, control_reg[reg]);
209}
210
91b1cc5d 211/* Print constants with sign. */
252b5132
RH
212
213static void
214fput_const (num, info)
215 unsigned num;
216 disassemble_info *info;
217{
218 if ((int)num < 0)
219 (*info->fprintf_func) (info->stream, "-%x", -(int)num);
220 else
221 (*info->fprintf_func) (info->stream, "%x", num);
222}
223
224/* Routines to extract various sized constants out of hppa
91b1cc5d 225 instructions. */
252b5132 226
91b1cc5d 227/* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */
252b5132
RH
228static int
229extract_3 (word)
230 unsigned word;
231{
232 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
233}
234
235static int
236extract_5_load (word)
237 unsigned word;
238{
239 return low_sign_extend (word >> 16 & MASK_5, 5);
240}
241
91b1cc5d 242/* Extract the immediate field from a st{bhw}s instruction. */
252b5132
RH
243static int
244extract_5_store (word)
245 unsigned word;
246{
247 return low_sign_extend (word & MASK_5, 5);
248}
249
91b1cc5d 250/* Extract the immediate field from a break instruction. */
252b5132
RH
251static unsigned
252extract_5r_store (word)
253 unsigned word;
254{
255 return (word & MASK_5);
256}
257
91b1cc5d 258/* Extract the immediate field from a {sr}sm instruction. */
252b5132
RH
259static unsigned
260extract_5R_store (word)
261 unsigned word;
262{
263 return (word >> 16 & MASK_5);
264}
265
91b1cc5d 266/* Extract the 10 bit immediate field from a {sr}sm instruction. */
3b67cf2b
JL
267static unsigned
268extract_10U_store (word)
269 unsigned word;
270{
271 return (word >> 16 & MASK_10);
272}
273
91b1cc5d 274/* Extract the immediate field from a bb instruction. */
252b5132
RH
275static unsigned
276extract_5Q_store (word)
277 unsigned word;
278{
279 return (word >> 21 & MASK_5);
280}
281
91b1cc5d 282/* Extract an 11 bit immediate field. */
252b5132
RH
283static int
284extract_11 (word)
285 unsigned word;
286{
287 return low_sign_extend (word & MASK_11, 11);
288}
289
91b1cc5d 290/* Extract a 14 bit immediate field. */
252b5132
RH
291static int
292extract_14 (word)
293 unsigned word;
294{
295 return low_sign_extend (word & MASK_14, 14);
296}
297
91b1cc5d
JL
298/* Extract a 16 bit immediate field (PA2.0 wide only). */
299static int
300extract_16 (word)
301 unsigned word;
302{
303 int m15, m0, m1;
304 m0 = GET_BIT (word, 16);
305 m1 = GET_BIT (word, 17);
306 m15 = GET_BIT (word, 31);
307 word = (word >> 1) & 0x1fff;
308 word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
309 return sign_extend (word, 16);
310}
311
312/* Extract a 21 bit constant. */
252b5132
RH
313
314static int
315extract_21 (word)
316 unsigned word;
317{
318 int val;
319
320 word &= MASK_21;
321 word <<= 11;
322 val = GET_FIELD (word, 20, 20);
323 val <<= 11;
324 val |= GET_FIELD (word, 9, 19);
325 val <<= 2;
326 val |= GET_FIELD (word, 5, 6);
327 val <<= 5;
328 val |= GET_FIELD (word, 0, 4);
329 val <<= 2;
330 val |= GET_FIELD (word, 7, 8);
331 return sign_extend (val, 21) << 11;
332}
333
91b1cc5d 334/* Extract a 12 bit constant from branch instructions. */
252b5132
RH
335
336static int
337extract_12 (word)
338 unsigned word;
339{
340 return sign_extend (GET_FIELD (word, 19, 28) |
ca504dff
AM
341 GET_FIELD (word, 29, 29) << 10 |
342 (word & 0x1) << 11, 12) << 2;
252b5132
RH
343}
344
91b1cc5d
JL
345/* Extract a 17 bit constant from branch instructions, returning the
346 19 bit signed value. */
252b5132
RH
347
348static int
349extract_17 (word)
350 unsigned word;
351{
352 return sign_extend (GET_FIELD (word, 19, 28) |
ca504dff
AM
353 GET_FIELD (word, 29, 29) << 10 |
354 GET_FIELD (word, 11, 15) << 11 |
355 (word & 0x1) << 16, 17) << 2;
252b5132
RH
356}
357
b3fe7ee2
JL
358static int
359extract_22 (word)
360 unsigned word;
361{
362 return sign_extend (GET_FIELD (word, 19, 28) |
ca504dff
AM
363 GET_FIELD (word, 29, 29) << 10 |
364 GET_FIELD (word, 11, 15) << 11 |
365 GET_FIELD (word, 6, 10) << 16 |
366 (word & 0x1) << 21, 22) << 2;
b3fe7ee2
JL
367}
368
252b5132
RH
369/* Print one instruction. */
370int
371print_insn_hppa (memaddr, info)
372 bfd_vma memaddr;
373 disassemble_info *info;
374{
375 bfd_byte buffer[4];
376 unsigned int insn, i;
377
378 {
379 int status =
380 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
381 if (status != 0)
382 {
383 (*info->memory_error_func) (status, memaddr, info);
384 return -1;
385 }
386 }
387
388 insn = bfd_getb32 (buffer);
389
390 for (i = 0; i < NUMOPCODES; ++i)
391 {
392 const struct pa_opcode *opcode = &pa_opcodes[i];
393 if ((insn & opcode->mask) == opcode->match)
394 {
395 register const char *s;
91b1cc5d
JL
396#ifndef BFD64
397 if (opcode->arch == pa20w)
398 continue;
399#endif
252b5132
RH
400 (*info->fprintf_func) (info->stream, "%s", opcode->name);
401
ca504dff 402 if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
252b5132
RH
403 (*info->fprintf_func) (info->stream, " ");
404 for (s = opcode->args; *s != '\0'; ++s)
405 {
406 switch (*s)
407 {
408 case 'x':
409 fput_reg (GET_FIELD (insn, 11, 15), info);
410 break;
1eee34f5 411 case 'a':
252b5132
RH
412 case 'b':
413 fput_reg (GET_FIELD (insn, 6, 10), info);
414 break;
415 case '^':
416 fput_creg (GET_FIELD (insn, 6, 10), info);
417 break;
252b5132
RH
418 case 't':
419 fput_reg (GET_FIELD (insn, 27, 31), info);
420 break;
a349b151 421
ca504dff 422 /* Handle floating point registers. */
a349b151
JL
423 case 'f':
424 switch (*++s)
425 {
426 case 't':
252b5132 427 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
a349b151
JL
428 break;
429 case 'T':
430 if (GET_FIELD (insn, 25, 25))
431 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
432 else
433 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
434 break;
435 case 'a':
436 if (GET_FIELD (insn, 25, 25))
437 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
438 else
439 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
440 break;
debc018d 441
ca504dff
AM
442 /* 'fA' will not generate a space before the regsiter
443 name. Normally that is fine. Except that it
444 causes problems with xmpyu which has no FP format
445 completer. */
debc018d
JL
446 case 'X':
447 fputs_filtered (" ", info);
ca504dff 448 /* FALLTHRU */
debc018d 449
a349b151
JL
450 case 'A':
451 if (GET_FIELD (insn, 24, 24))
452 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
453 else
454 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
a349b151
JL
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 518
ca504dff
AM
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. */
91b1cc5d
JL
523 case 'E':
524 fputs_filtered (" ", info);
ca504dff 525 /* FALLTHRU */
91b1cc5d 526
f322c2c2 527 case 'e':
91b1cc5d 528 if (GET_FIELD (insn, 30, 30))
f322c2c2
JL
529 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
530 else
531 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
532 break;
91b1cc5d
JL
533 case 'x':
534 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
535 break;
a349b151 536 }
2f87f883 537 break;
252b5132 538
252b5132
RH
539 case '5':
540 fput_const (extract_5_load (insn), info);
541 break;
542 case 's':
75776faa
AM
543 {
544 int space = GET_FIELD (insn, 16, 17);
545 /* Zero means implicit addressing, not use of sr0. */
546 if (space != 0)
547 (*info->fprintf_func) (info->stream, "sr%d", space);
548 }
252b5132 549 break;
b333b6c6 550
252b5132 551 case 'S':
ca504dff
AM
552 (*info->fprintf_func) (info->stream, "sr%d",
553 extract_3 (insn));
252b5132 554 break;
3281117a 555
ca504dff 556 /* Handle completers. */
252b5132 557 case 'c':
3281117a
JL
558 switch (*++s)
559 {
560 case 'x':
ca504dff
AM
561 (*info->fprintf_func)
562 (info->stream, "%s",
563 index_compl_names[GET_COMPL (insn)]);
8ef42b29
JL
564 break;
565 case 'X':
ca504dff
AM
566 (*info->fprintf_func)
567 (info->stream, "%s ",
568 index_compl_names[GET_COMPL (insn)]);
3281117a
JL
569 break;
570 case 'm':
ca504dff
AM
571 (*info->fprintf_func)
572 (info->stream, "%s",
573 short_ldst_compl_names[GET_COMPL (insn)]);
8ef42b29
JL
574 break;
575 case 'M':
ca504dff
AM
576 (*info->fprintf_func)
577 (info->stream, "%s ",
578 short_ldst_compl_names[GET_COMPL (insn)]);
3281117a 579 break;
8ef42b29 580 case 'A':
ca504dff
AM
581 (*info->fprintf_func)
582 (info->stream, "%s ",
583 short_bytes_compl_names[GET_COMPL (insn)]);
3281117a 584 break;
8ef42b29 585 case 's':
ca504dff
AM
586 (*info->fprintf_func)
587 (info->stream, "%s",
588 short_bytes_compl_names[GET_COMPL (insn)]);
8ef42b29 589 break;
1c170bd8
JL
590 case 'c':
591 case 'C':
592 switch (GET_FIELD (insn, 20, 21))
593 {
594 case 1:
595 (*info->fprintf_func) (info->stream, ",bc ");
596 break;
597 case 2:
598 (*info->fprintf_func) (info->stream, ",sl ");
599 break;
600 default:
601 (*info->fprintf_func) (info->stream, " ");
602 }
603 break;
604 case 'd':
605 switch (GET_FIELD (insn, 20, 21))
606 {
607 case 1:
608 (*info->fprintf_func) (info->stream, ",co ");
609 break;
610 default:
611 (*info->fprintf_func) (info->stream, " ");
612 }
613 break;
614 case 'o':
615 (*info->fprintf_func) (info->stream, ",o");
616 break;
1fb72ed1
JL
617 case 'g':
618 (*info->fprintf_func) (info->stream, ",gate");
1c170bd8 619 break;
1fb72ed1
JL
620 case 'p':
621 (*info->fprintf_func) (info->stream, ",l,push");
622 break;
623 case 'P':
624 (*info->fprintf_func) (info->stream, ",pop");
625 break;
626 case 'l':
3b67cf2b
JL
627 case 'L':
628 (*info->fprintf_func) (info->stream, ",l");
629 break;
630 case 'w':
ca504dff
AM
631 (*info->fprintf_func)
632 (info->stream, "%s ",
633 read_write_names[GET_FIELD (insn, 25, 25)]);
3b67cf2b
JL
634 break;
635 case 'W':
636 (*info->fprintf_func) (info->stream, ",w");
637 break;
638 case 'r':
639 if (GET_FIELD (insn, 23, 26) == 5)
640 (*info->fprintf_func) (info->stream, ",r");
641 break;
3281117a
JL
642 case 'Z':
643 if (GET_FIELD (insn, 26, 26))
644 (*info->fprintf_func) (info->stream, ",m ");
645 else
646 (*info->fprintf_func) (info->stream, " ");
647 break;
3b67cf2b
JL
648 case 'i':
649 if (GET_FIELD (insn, 25, 25))
650 (*info->fprintf_func) (info->stream, ",i");
651 break;
af10de82
JL
652 case 'z':
653 if (!GET_FIELD (insn, 21, 21))
654 (*info->fprintf_func) (info->stream, ",z");
655 break;
3b67cf2b
JL
656 case 'a':
657 (*info->fprintf_func)
ca504dff
AM
658 (info->stream, "%s",
659 add_compl_names[GET_FIELD (insn, 20, 21)]);
3b67cf2b
JL
660 break;
661 case 'Y':
662 (*info->fprintf_func)
ca504dff
AM
663 (info->stream, ",dc%s",
664 add_compl_names[GET_FIELD (insn, 20, 21)]);
3b67cf2b
JL
665 break;
666 case 'y':
667 (*info->fprintf_func)
ca504dff
AM
668 (info->stream, ",c%s",
669 add_compl_names[GET_FIELD (insn, 20, 21)]);
3b67cf2b
JL
670 break;
671 case 'v':
672 if (GET_FIELD (insn, 20, 20))
673 (*info->fprintf_func) (info->stream, ",tsv");
674 break;
675 case 't':
676 (*info->fprintf_func) (info->stream, ",tc");
677 if (GET_FIELD (insn, 20, 20))
678 (*info->fprintf_func) (info->stream, ",tsv");
679 break;
680 case 'B':
681 (*info->fprintf_func) (info->stream, ",db");
682 if (GET_FIELD (insn, 20, 20))
683 (*info->fprintf_func) (info->stream, ",tsv");
684 break;
685 case 'b':
686 (*info->fprintf_func) (info->stream, ",b");
687 if (GET_FIELD (insn, 20, 20))
688 (*info->fprintf_func) (info->stream, ",tsv");
689 break;
690 case 'T':
691 if (GET_FIELD (insn, 25, 25))
692 (*info->fprintf_func) (info->stream, ",tc");
693 break;
1eee34f5
JL
694 case 'S':
695 /* EXTRD/W has a following condition. */
696 if (*(s + 1) == '?')
697 (*info->fprintf_func)
ca504dff
AM
698 (info->stream, "%s",
699 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
1eee34f5
JL
700 else
701 (*info->fprintf_func)
ca504dff
AM
702 (info->stream, "%s ",
703 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
1eee34f5
JL
704 break;
705 case 'h':
706 (*info->fprintf_func)
ca504dff
AM
707 (info->stream, "%s",
708 mix_half_names[GET_FIELD (insn, 17, 17)]);
1eee34f5
JL
709 break;
710 case 'H':
711 (*info->fprintf_func)
ca504dff
AM
712 (info->stream, "%s ",
713 saturation_names[GET_FIELD (insn, 24, 25)]);
1eee34f5
JL
714 break;
715 case '*':
716 (*info->fprintf_func)
ca504dff
AM
717 (info->stream, ",%d%d%d%d ",
718 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
719 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
1eee34f5 720 break;
9c1faa82
JL
721
722 case 'q':
723 {
724 int m, a;
725
726 m = GET_FIELD (insn, 28, 28);
727 a = GET_FIELD (insn, 29, 29);
728
729 if (m && !a)
730 fputs_filtered (",ma ", info);
731 else if (m && a)
732 fputs_filtered (",mb ", info);
733 else
734 fputs_filtered (" ", info);
735 break;
736 }
737
738 case 'J':
739 {
6e09abd4 740 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 741
6e09abd4 742 if (opc == 0x16 || opc == 0x1e)
9c1faa82
JL
743 {
744 if (GET_FIELD (insn, 29, 29) == 0)
745 fputs_filtered (",ma ", info);
746 else
747 fputs_filtered (",mb ", info);
748 }
749 else
750 fputs_filtered (" ", info);
751 break;
752 }
753
1c170bd8 754 case 'e':
9c1faa82 755 {
6e09abd4 756 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 757
6e09abd4 758 if (opc == 0x13 || opc == 0x1b)
9c1faa82
JL
759 {
760 if (GET_FIELD (insn, 18, 18) == 1)
761 fputs_filtered (",mb ", info);
762 else
763 fputs_filtered (",ma ", info);
764 }
6e09abd4 765 else if (opc == 0x17 || opc == 0x1f)
9c1faa82
JL
766 {
767 if (GET_FIELD (insn, 31, 31) == 1)
768 fputs_filtered (",ma ", info);
769 else
770 fputs_filtered (",mb ", info);
771 }
772 else
773 fputs_filtered (" ", info);
774
775 break;
776 }
3281117a 777 }
252b5132 778 break;
feb12992 779
ca504dff 780 /* Handle conditions. */
252b5132 781 case '?':
feb12992
JL
782 {
783 s++;
784 switch (*s)
785 {
786 case 'f':
ca504dff
AM
787 (*info->fprintf_func)
788 (info->stream, "%s ",
789 float_comp_names[GET_FIELD (insn, 27, 31)]);
feb12992
JL
790 break;
791
ca504dff 792 /* these four conditions are for the set of instructions
feb12992
JL
793 which distinguish true/false conditions by opcode
794 rather than by the 'f' bit (sigh): comb, comib,
795 addb, addib */
796 case 't':
ca504dff
AM
797 fputs_filtered
798 (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
feb12992 799 break;
1c170bd8 800 case 'n':
ca504dff
AM
801 fputs_filtered
802 (compare_cond_names[GET_FIELD (insn, 16, 18)
803 + GET_FIELD (insn, 4, 4) * 8],
804 info);
b333b6c6 805 break;
1c170bd8 806 case 'N':
ca504dff
AM
807 fputs_filtered
808 (compare_cond_64_names[GET_FIELD (insn, 16, 18)
809 + GET_FIELD (insn, 2, 2) * 8],
810 info);
b333b6c6
JL
811 break;
812 case 'Q':
ca504dff
AM
813 fputs_filtered
814 (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
815 info);
b333b6c6 816 break;
feb12992 817 case '@':
ca504dff
AM
818 fputs_filtered
819 (add_cond_names[GET_FIELD (insn, 16, 18)
820 + GET_FIELD (insn, 4, 4) * 8],
821 info);
feb12992
JL
822 break;
823 case 's':
ca504dff
AM
824 (*info->fprintf_func)
825 (info->stream, "%s ",
826 compare_cond_names[GET_COND (insn)]);
feb12992 827 break;
b333b6c6 828 case 'S':
ca504dff
AM
829 (*info->fprintf_func)
830 (info->stream, "%s ",
831 compare_cond_64_names[GET_COND (insn)]);
b333b6c6 832 break;
feb12992 833 case 'a':
ca504dff
AM
834 (*info->fprintf_func)
835 (info->stream, "%s ",
836 add_cond_names[GET_COND (insn)]);
feb12992 837 break;
b333b6c6 838 case 'A':
ca504dff
AM
839 (*info->fprintf_func)
840 (info->stream, "%s ",
841 add_cond_64_names[GET_COND (insn)]);
b333b6c6 842 break;
feb12992 843 case 'd':
ca504dff
AM
844 (*info->fprintf_func)
845 (info->stream, "%s",
846 add_cond_names[GET_FIELD (insn, 16, 18)]);
feb12992 847 break;
a349b151 848
b333b6c6 849 case 'W':
ca504dff 850 (*info->fprintf_func)
b333b6c6 851 (info->stream, "%s",
ca504dff
AM
852 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
853 GET_FIELD (insn, 4, 4) * 8]);
b333b6c6 854 break;
feb12992
JL
855
856 case 'l':
ca504dff
AM
857 (*info->fprintf_func)
858 (info->stream, "%s ",
859 logical_cond_names[GET_COND (insn)]);
feb12992 860 break;
b333b6c6 861 case 'L':
ca504dff
AM
862 (*info->fprintf_func)
863 (info->stream, "%s ",
864 logical_cond_64_names[GET_COND (insn)]);
b333b6c6 865 break;
feb12992 866 case 'u':
ca504dff
AM
867 (*info->fprintf_func)
868 (info->stream, "%s ",
869 unit_cond_names[GET_COND (insn)]);
feb12992 870 break;
b333b6c6 871 case 'U':
ca504dff
AM
872 (*info->fprintf_func)
873 (info->stream, "%s ",
874 unit_cond_64_names[GET_COND (insn)]);
b333b6c6 875 break;
feb12992
JL
876 case 'y':
877 case 'x':
878 case 'b':
879 (*info->fprintf_func)
880 (info->stream, "%s",
881 shift_cond_names[GET_FIELD (insn, 16, 18)]);
882
883 /* If the next character in args is 'n', it will handle
884 putting out the space. */
885 if (s[1] != 'n')
886 (*info->fprintf_func) (info->stream, " ");
887 break;
b333b6c6 888 case 'X':
ca504dff
AM
889 (*info->fprintf_func)
890 (info->stream, "%s ",
891 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
b333b6c6
JL
892 break;
893 case 'B':
894 (*info->fprintf_func)
895 (info->stream, "%s",
896 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
feb12992 897
b333b6c6
JL
898 /* If the next character in args is 'n', it will handle
899 putting out the space. */
900 if (s[1] != 'n')
901 (*info->fprintf_func) (info->stream, " ");
902 break;
feb12992
JL
903 }
904 break;
905 }
252b5132 906
252b5132
RH
907 case 'V':
908 fput_const (extract_5_store (insn), info);
909 break;
910 case 'r':
911 fput_const (extract_5r_store (insn), info);
912 break;
913 case 'R':
914 fput_const (extract_5R_store (insn), info);
915 break;
3b67cf2b
JL
916 case 'U':
917 fput_const (extract_10U_store (insn), info);
918 break;
61e8273b 919 case 'B':
252b5132
RH
920 case 'Q':
921 fput_const (extract_5Q_store (insn), info);
922 break;
923 case 'i':
924 fput_const (extract_11 (insn), info);
925 break;
926 case 'j':
927 fput_const (extract_14 (insn), info);
928 break;
929 case 'k':
930 fput_const (extract_21 (insn), info);
931 break;
1328dc98 932 case '<':
91b1cc5d
JL
933 case 'l':
934 /* 16-bit long disp., PA2.0 wide only. */
935 fput_const (extract_16 (insn), info);
936 break;
252b5132
RH
937 case 'n':
938 if (insn & 0x2)
939 (*info->fprintf_func) (info->stream, ",n ");
940 else
941 (*info->fprintf_func) (info->stream, " ");
942 break;
943 case 'N':
944 if ((insn & 0x20) && s[1])
945 (*info->fprintf_func) (info->stream, ",n ");
946 else if (insn & 0x20)
947 (*info->fprintf_func) (info->stream, ",n");
948 else if (s[1])
949 (*info->fprintf_func) (info->stream, " ");
950 break;
951 case 'w':
ca504dff
AM
952 (*info->print_address_func)
953 (memaddr + 8 + extract_12 (insn), info);
252b5132
RH
954 break;
955 case 'W':
956 /* 17 bit PC-relative branch. */
ca504dff
AM
957 (*info->print_address_func)
958 ((memaddr + 8 + extract_17 (insn)), info);
252b5132
RH
959 break;
960 case 'z':
961 /* 17 bit displacement. This is an offset from a register
962 so it gets disasssembled as just a number, not any sort
963 of address. */
964 fput_const (extract_17 (insn), info);
965 break;
d1e9bd1f
JL
966
967 case 'Z':
968 /* addil %r1 implicit output. */
2beaab59 969 (*info->fprintf_func) (info->stream, "%%r1");
d1e9bd1f 970 break;
1fb72ed1
JL
971
972 case 'Y':
973 /* be,l %sr0,%r31 implicit output. */
974 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
975 break;
ca504dff 976
1c170bd8
JL
977 case '@':
978 (*info->fprintf_func) (info->stream, "0");
979 break;
980
46424e05
JL
981 case '.':
982 (*info->fprintf_func) (info->stream, "%d",
ca504dff 983 GET_FIELD (insn, 24, 25));
46424e05 984 break;
3b67cf2b
JL
985 case '*':
986 (*info->fprintf_func) (info->stream, "%d",
ca504dff 987 GET_FIELD (insn, 22, 25));
3b67cf2b 988 break;
b7d6d485 989 case '!':
2beaab59 990 (*info->fprintf_func) (info->stream, "%%sar");
b7d6d485 991 break;
252b5132
RH
992 case 'p':
993 (*info->fprintf_func) (info->stream, "%d",
ca504dff 994 31 - GET_FIELD (insn, 22, 26));
252b5132 995 break;
46424e05
JL
996 case '~':
997 {
998 int num;
999 num = GET_FIELD (insn, 20, 20) << 5;
1000 num |= GET_FIELD (insn, 22, 26);
1001 (*info->fprintf_func) (info->stream, "%d", 63 - num);
1002 break;
1003 }
252b5132
RH
1004 case 'P':
1005 (*info->fprintf_func) (info->stream, "%d",
ca504dff 1006 GET_FIELD (insn, 22, 26));
252b5132 1007 break;
af10de82
JL
1008 case 'q':
1009 {
1010 int num;
1011 num = GET_FIELD (insn, 20, 20) << 5;
1012 num |= GET_FIELD (insn, 22, 26);
1013 (*info->fprintf_func) (info->stream, "%d", num);
1014 break;
1015 }
252b5132
RH
1016 case 'T':
1017 (*info->fprintf_func) (info->stream, "%d",
ca504dff 1018 32 - GET_FIELD (insn, 27, 31));
252b5132 1019 break;
af10de82
JL
1020 case '%':
1021 {
1022 int num;
1023 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
1024 num -= GET_FIELD (insn, 27, 31);
1025 (*info->fprintf_func) (info->stream, "%d", num);
1026 break;
1027 }
1028 case '|':
1029 {
1030 int num;
1031 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
1032 num -= GET_FIELD (insn, 27, 31);
1033 (*info->fprintf_func) (info->stream, "%d", num);
1034 break;
1035 }
46424e05
JL
1036 case '$':
1037 fput_const (GET_FIELD (insn, 20, 28), info);
1038 break;
252b5132
RH
1039 case 'A':
1040 fput_const (GET_FIELD (insn, 6, 18), info);
1041 break;
252b5132
RH
1042 case 'D':
1043 fput_const (GET_FIELD (insn, 6, 31), info);
1044 break;
a349b151 1045 case 'v':
ca504dff
AM
1046 (*info->fprintf_func) (info->stream, ",%d",
1047 GET_FIELD (insn, 23, 25));
252b5132
RH
1048 break;
1049 case 'O':
1050 fput_const ((GET_FIELD (insn, 6,20) << 5 |
1051 GET_FIELD (insn, 27, 31)), info);
1052 break;
1053 case 'o':
1054 fput_const (GET_FIELD (insn, 6, 20), info);
1055 break;
252b5132
RH
1056 case '2':
1057 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
1058 GET_FIELD (insn, 27, 31)), info);
1059 break;
1060 case '1':
1061 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
1062 GET_FIELD (insn, 27, 31)), info);
1063 break;
1064 case '0':
1065 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
1066 GET_FIELD (insn, 27, 31)), info);
1067 break;
1068 case 'u':
ca504dff
AM
1069 (*info->fprintf_func) (info->stream, ",%d",
1070 GET_FIELD (insn, 23, 25));
252b5132
RH
1071 break;
1072 case 'F':
1073 /* if no destination completer and not before a completer
1074 for fcmp, need a space here */
4f312591 1075 if (s[1] == 'G' || s[1] == '?')
ca504dff
AM
1076 fputs_filtered
1077 (float_format_names[GET_FIELD (insn, 19, 20)], info);
252b5132 1078 else
ca504dff
AM
1079 (*info->fprintf_func)
1080 (info->stream, "%s ",
1081 float_format_names[GET_FIELD (insn, 19, 20)]);
252b5132
RH
1082 break;
1083 case 'G':
ca504dff
AM
1084 (*info->fprintf_func)
1085 (info->stream, "%s ",
1086 float_format_names[GET_FIELD (insn, 17, 18)]);
252b5132
RH
1087 break;
1088 case 'H':
1089 if (GET_FIELD (insn, 26, 26) == 1)
1090 (*info->fprintf_func) (info->stream, "%s ",
ca504dff 1091 float_format_names[0]);
252b5132
RH
1092 else
1093 (*info->fprintf_func) (info->stream, "%s ",
ca504dff 1094 float_format_names[1]);
252b5132
RH
1095 break;
1096 case 'I':
1097 /* if no destination completer and not before a completer
1098 for fcmp, need a space here */
4f312591 1099 if (s[1] == '?')
ca504dff
AM
1100 fputs_filtered
1101 (float_format_names[GET_FIELD (insn, 20, 20)], info);
252b5132 1102 else
ca504dff
AM
1103 (*info->fprintf_func)
1104 (info->stream, "%s ",
1105 float_format_names[GET_FIELD (insn, 20, 20)]);
252b5132 1106 break;
eb32eb44 1107
ca504dff
AM
1108 case 'J':
1109 fput_const (extract_14 (insn), info);
1110 break;
eb32eb44 1111
d758242c
JL
1112 case '#':
1113 {
1114 int sign = GET_FIELD (insn, 31, 31);
1115 int imm10 = GET_FIELD (insn, 18, 27);
1116 int disp;
1117
1118 if (sign)
1119 disp = (-1 << 10) | imm10;
1120 else
1121 disp = imm10;
1122
1123 disp <<= 3;
1124 fput_const (disp, info);
1125 break;
1126 }
ca504dff 1127 case 'K':
d758242c
JL
1128 case 'd':
1129 {
1130 int sign = GET_FIELD (insn, 31, 31);
1131 int imm11 = GET_FIELD (insn, 18, 28);
1132 int disp;
1133
1134 if (sign)
1135 disp = (-1 << 11) | imm11;
1136 else
1137 disp = imm11;
1138
1139 disp <<= 2;
1140 fput_const (disp, info);
1141 break;
1142 }
1143
1328dc98 1144 case '>':
91b1cc5d
JL
1145 case 'y':
1146 {
1147 /* 16-bit long disp., PA2.0 wide only. */
1148 int disp = extract_16 (insn);
1149 disp &= ~3;
1150 fput_const (disp, info);
1151 break;
1152 }
1153
1154 case '&':
1155 {
1156 /* 16-bit long disp., PA2.0 wide only. */
1157 int disp = extract_16 (insn);
1158 disp &= ~7;
1159 fput_const (disp, info);
1160 break;
1161 }
1162
838c65f0 1163 case '_':
ca504dff
AM
1164 break; /* Dealt with by '{' */
1165
838c65f0 1166 case '{':
ca504dff
AM
1167 {
1168 int sub = GET_FIELD (insn, 14, 16);
1169 int df = GET_FIELD (insn, 17, 18);
1170 int sf = GET_FIELD (insn, 19, 20);
1171 const char * const * source = float_format_names;
1172 const char * const * dest = float_format_names;
1173 char *t = "";
1174 if (sub == 4)
1175 {
1176 fputs_filtered (",UND ", info);
1177 break;
1178 }
1179 if ((sub & 3) == 3)
1180 t = ",t";
1181 if ((sub & 3) == 1)
1182 source = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
1183 if (sub & 2)
1184 dest = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
1185
1186 (*info->fprintf_func) (info->stream, "%s%s%s ",
1187 t, source[sf], dest[df]);
1188 break;
1189 }
838c65f0
JL
1190
1191 case 'm':
1192 {
1193 int y = GET_FIELD (insn, 16, 18);
1194
1195 if (y != 1)
1196 fput_const ((y ^ 1) - 1, info);
1197 }
1198 break;
1199
1200 case 'h':
1201 {
1202 int cbit;
1203
1204 cbit = GET_FIELD (insn, 16, 18);
1205
1206 if (cbit > 0)
1207 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1208 break;
1209 }
1210
1211 case '=':
1212 {
1213 int cond = GET_FIELD (insn, 27, 31);
1214
1215 if (cond == 0)
1216 fputs_filtered (" ", info);
1217 else if (cond == 1)
1218 fputs_filtered ("acc ", info);
1219 else if (cond == 2)
1220 fputs_filtered ("rej ", info);
1221 else if (cond == 5)
1222 fputs_filtered ("acc8 ", info);
1223 else if (cond == 6)
1224 fputs_filtered ("rej8 ", info);
1225 else if (cond == 9)
1226 fputs_filtered ("acc6 ", info);
1227 else if (cond == 13)
1228 fputs_filtered ("acc4 ", info);
1229 else if (cond == 17)
1230 fputs_filtered ("acc2 ", info);
1231 break;
1232 }
1233
3610d131 1234 case 'X':
ca504dff
AM
1235 (*info->print_address_func)
1236 (memaddr + 8 + extract_22 (insn), info);
3610d131 1237 break;
2784abe5
JL
1238 case 'L':
1239 fputs_filtered (",%r2", info);
1240 break;
252b5132
RH
1241 default:
1242 (*info->fprintf_func) (info->stream, "%c", *s);
1243 break;
1244 }
1245 }
1246 return sizeof(insn);
1247 }
1248 }
1249 (*info->fprintf_func) (info->stream, "#%8x", insn);
1250 return sizeof(insn);
1251}
This page took 0.363638 seconds and 4 git commands to generate.