*** empty log message ***
[deliverable/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':
8ef42b29
JL
557 (*info->fprintf_func) (info->stream, "%s",
558 index_compl_names[GET_COMPL (insn)]);
559 break;
560 case 'X':
3281117a
JL
561 (*info->fprintf_func) (info->stream, "%s ",
562 index_compl_names[GET_COMPL (insn)]);
563 break;
564 case 'm':
8ef42b29
JL
565 (*info->fprintf_func) (info->stream, "%s",
566 short_ldst_compl_names[GET_COMPL (insn)]);
567 break;
568 case 'M':
3281117a
JL
569 (*info->fprintf_func) (info->stream, "%s ",
570 short_ldst_compl_names[GET_COMPL (insn)]);
571 break;
8ef42b29 572 case 'A':
3281117a
JL
573 (*info->fprintf_func) (info->stream, "%s ",
574 short_bytes_compl_names[GET_COMPL (insn)]);
575 break;
8ef42b29
JL
576 case 's':
577 (*info->fprintf_func) (info->stream, "%s",
578 short_bytes_compl_names[GET_COMPL (insn)]);
579 break;
1c170bd8
JL
580 case 'c':
581 case 'C':
582 switch (GET_FIELD (insn, 20, 21))
583 {
584 case 1:
585 (*info->fprintf_func) (info->stream, ",bc ");
586 break;
587 case 2:
588 (*info->fprintf_func) (info->stream, ",sl ");
589 break;
590 default:
591 (*info->fprintf_func) (info->stream, " ");
592 }
593 break;
594 case 'd':
595 switch (GET_FIELD (insn, 20, 21))
596 {
597 case 1:
598 (*info->fprintf_func) (info->stream, ",co ");
599 break;
600 default:
601 (*info->fprintf_func) (info->stream, " ");
602 }
603 break;
604 case 'o':
605 (*info->fprintf_func) (info->stream, ",o");
606 break;
1fb72ed1
JL
607 case 'g':
608 (*info->fprintf_func) (info->stream, ",gate");
1c170bd8 609 break;
1fb72ed1
JL
610 case 'p':
611 (*info->fprintf_func) (info->stream, ",l,push");
612 break;
613 case 'P':
614 (*info->fprintf_func) (info->stream, ",pop");
615 break;
616 case 'l':
3b67cf2b
JL
617 case 'L':
618 (*info->fprintf_func) (info->stream, ",l");
619 break;
620 case 'w':
621 (*info->fprintf_func) (info->stream, "%s ",
622 read_write_names[GET_FIELD (insn, 25, 25)]);
623 break;
624 case 'W':
625 (*info->fprintf_func) (info->stream, ",w");
626 break;
627 case 'r':
628 if (GET_FIELD (insn, 23, 26) == 5)
629 (*info->fprintf_func) (info->stream, ",r");
630 break;
3281117a
JL
631 case 'Z':
632 if (GET_FIELD (insn, 26, 26))
633 (*info->fprintf_func) (info->stream, ",m ");
634 else
635 (*info->fprintf_func) (info->stream, " ");
636 break;
3b67cf2b
JL
637 case 'i':
638 if (GET_FIELD (insn, 25, 25))
639 (*info->fprintf_func) (info->stream, ",i");
640 break;
af10de82
JL
641 case 'z':
642 if (!GET_FIELD (insn, 21, 21))
643 (*info->fprintf_func) (info->stream, ",z");
644 break;
3b67cf2b
JL
645 case 'a':
646 (*info->fprintf_func)
647 (info->stream, "%s", add_compl_names[GET_FIELD
648 (insn, 20, 21)]);
649 break;
650 case 'Y':
651 (*info->fprintf_func)
652 (info->stream, ",dc%s", add_compl_names[GET_FIELD
653 (insn, 20, 21)]);
654 break;
655 case 'y':
656 (*info->fprintf_func)
657 (info->stream, ",c%s", add_compl_names[GET_FIELD
658 (insn, 20, 21)]);
659 break;
660 case 'v':
661 if (GET_FIELD (insn, 20, 20))
662 (*info->fprintf_func) (info->stream, ",tsv");
663 break;
664 case 't':
665 (*info->fprintf_func) (info->stream, ",tc");
666 if (GET_FIELD (insn, 20, 20))
667 (*info->fprintf_func) (info->stream, ",tsv");
668 break;
669 case 'B':
670 (*info->fprintf_func) (info->stream, ",db");
671 if (GET_FIELD (insn, 20, 20))
672 (*info->fprintf_func) (info->stream, ",tsv");
673 break;
674 case 'b':
675 (*info->fprintf_func) (info->stream, ",b");
676 if (GET_FIELD (insn, 20, 20))
677 (*info->fprintf_func) (info->stream, ",tsv");
678 break;
679 case 'T':
680 if (GET_FIELD (insn, 25, 25))
681 (*info->fprintf_func) (info->stream, ",tc");
682 break;
1eee34f5
JL
683 case 'S':
684 /* EXTRD/W has a following condition. */
685 if (*(s + 1) == '?')
686 (*info->fprintf_func)
687 (info->stream, "%s", signed_unsigned_names[GET_FIELD
688 (insn, 21, 21)]);
689 else
690 (*info->fprintf_func)
691 (info->stream, "%s ", signed_unsigned_names[GET_FIELD
692 (insn, 21, 21)]);
693 break;
694 case 'h':
695 (*info->fprintf_func)
696 (info->stream, "%s", mix_half_names[GET_FIELD
697 (insn, 17, 17)]);
698 break;
699 case 'H':
700 (*info->fprintf_func)
8ef42b29 701 (info->stream, "%s ", saturation_names[GET_FIELD
1eee34f5
JL
702 (insn, 24, 25)]);
703 break;
704 case '*':
705 (*info->fprintf_func)
706 (info->stream, ",%d%d%d%d ",
707 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
708 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
709 break;
9c1faa82
JL
710
711 case 'q':
712 {
713 int m, a;
714
715 m = GET_FIELD (insn, 28, 28);
716 a = GET_FIELD (insn, 29, 29);
717
718 if (m && !a)
719 fputs_filtered (",ma ", info);
720 else if (m && a)
721 fputs_filtered (",mb ", info);
722 else
723 fputs_filtered (" ", info);
724 break;
725 }
726
727 case 'J':
728 {
6e09abd4 729 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 730
6e09abd4 731 if (opc == 0x16 || opc == 0x1e)
9c1faa82
JL
732 {
733 if (GET_FIELD (insn, 29, 29) == 0)
734 fputs_filtered (",ma ", info);
735 else
736 fputs_filtered (",mb ", info);
737 }
738 else
739 fputs_filtered (" ", info);
740 break;
741 }
742
1c170bd8 743 case 'e':
9c1faa82 744 {
6e09abd4 745 int opc = GET_FIELD (insn, 0, 5);
9c1faa82 746
6e09abd4 747 if (opc == 0x13 || opc == 0x1b)
9c1faa82
JL
748 {
749 if (GET_FIELD (insn, 18, 18) == 1)
750 fputs_filtered (",mb ", info);
751 else
752 fputs_filtered (",ma ", info);
753 }
6e09abd4 754 else if (opc == 0x17 || opc == 0x1f)
9c1faa82
JL
755 {
756 if (GET_FIELD (insn, 31, 31) == 1)
757 fputs_filtered (",ma ", info);
758 else
759 fputs_filtered (",mb ", info);
760 }
761 else
762 fputs_filtered (" ", info);
763
764 break;
765 }
3281117a 766 }
252b5132 767 break;
feb12992
JL
768
769 /* Handle conditions. */
252b5132 770 case '?':
feb12992
JL
771 {
772 s++;
773 switch (*s)
774 {
775 case 'f':
776 (*info->fprintf_func) (info->stream, "%s ",
777 float_comp_names[GET_FIELD
778 (insn, 27, 31)]);
779 break;
780
781 /* these four conditions are for the set of instructions
782 which distinguish true/false conditions by opcode
783 rather than by the 'f' bit (sigh): comb, comib,
784 addb, addib */
785 case 't':
a349b151 786 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
feb12992
JL
787 info);
788 break;
1c170bd8 789 case 'n':
b333b6c6 790 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
1c170bd8 791 + GET_FIELD (insn, 4, 4) * 8], info);
b333b6c6 792 break;
1c170bd8 793 case 'N':
b333b6c6 794 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
1c170bd8 795 + GET_FIELD (insn, 2, 2) * 8], info);
b333b6c6
JL
796 break;
797 case 'Q':
798 fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
799 info);
800 break;
feb12992
JL
801 case '@':
802 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
803 + GET_FIELD (insn, 4, 4) * 8], info);
804 break;
805 case 's':
806 (*info->fprintf_func) (info->stream, "%s ",
807 compare_cond_names[GET_COND (insn)]);
808 break;
b333b6c6
JL
809 case 'S':
810 (*info->fprintf_func) (info->stream, "%s ",
811 compare_cond_64_names[GET_COND (insn)]);
812 break;
feb12992
JL
813 case 'a':
814 (*info->fprintf_func) (info->stream, "%s ",
815 add_cond_names[GET_COND (insn)]);
816 break;
b333b6c6
JL
817 case 'A':
818 (*info->fprintf_func) (info->stream, "%s ",
819 add_cond_64_names[GET_COND (insn)]);
820 break;
feb12992
JL
821 case 'd':
822 (*info->fprintf_func) (info->stream, "%s",
a349b151 823 add_cond_names[GET_FIELD (insn, 16, 18)]);
feb12992 824 break;
a349b151 825
b333b6c6 826 case 'W':
a349b151 827 (*info->fprintf_func)
b333b6c6 828 (info->stream, "%s",
1c170bd8
JL
829 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
830 GET_FIELD (insn, 4, 4) * 8]);
b333b6c6 831 break;
feb12992
JL
832
833 case 'l':
834 (*info->fprintf_func) (info->stream, "%s ",
835 logical_cond_names[GET_COND (insn)]);
836 break;
b333b6c6
JL
837 case 'L':
838 (*info->fprintf_func) (info->stream, "%s ",
839 logical_cond_64_names[GET_COND (insn)]);
840 break;
feb12992
JL
841 case 'u':
842 (*info->fprintf_func) (info->stream, "%s ",
843 unit_cond_names[GET_COND (insn)]);
844 break;
b333b6c6
JL
845 case 'U':
846 (*info->fprintf_func) (info->stream, "%s ",
847 unit_cond_64_names[GET_COND (insn)]);
848 break;
feb12992
JL
849 case 'y':
850 case 'x':
851 case 'b':
852 (*info->fprintf_func)
853 (info->stream, "%s",
854 shift_cond_names[GET_FIELD (insn, 16, 18)]);
855
856 /* If the next character in args is 'n', it will handle
857 putting out the space. */
858 if (s[1] != 'n')
859 (*info->fprintf_func) (info->stream, " ");
860 break;
b333b6c6 861 case 'X':
e46def7b 862 (*info->fprintf_func) (info->stream, "%s ",
b333b6c6
JL
863 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
864 break;
865 case 'B':
866 (*info->fprintf_func)
867 (info->stream, "%s",
868 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
feb12992 869
b333b6c6
JL
870 /* If the next character in args is 'n', it will handle
871 putting out the space. */
872 if (s[1] != 'n')
873 (*info->fprintf_func) (info->stream, " ");
874 break;
feb12992
JL
875 }
876 break;
877 }
252b5132 878
252b5132
RH
879 case 'V':
880 fput_const (extract_5_store (insn), info);
881 break;
882 case 'r':
883 fput_const (extract_5r_store (insn), info);
884 break;
885 case 'R':
886 fput_const (extract_5R_store (insn), info);
887 break;
3b67cf2b
JL
888 case 'U':
889 fput_const (extract_10U_store (insn), info);
890 break;
61e8273b 891 case 'B':
252b5132
RH
892 case 'Q':
893 fput_const (extract_5Q_store (insn), info);
894 break;
895 case 'i':
896 fput_const (extract_11 (insn), info);
897 break;
898 case 'j':
899 fput_const (extract_14 (insn), info);
900 break;
901 case 'k':
902 fput_const (extract_21 (insn), info);
903 break;
1328dc98 904 case '<':
91b1cc5d
JL
905 case 'l':
906 /* 16-bit long disp., PA2.0 wide only. */
907 fput_const (extract_16 (insn), info);
908 break;
252b5132
RH
909 case 'n':
910 if (insn & 0x2)
911 (*info->fprintf_func) (info->stream, ",n ");
912 else
913 (*info->fprintf_func) (info->stream, " ");
914 break;
915 case 'N':
916 if ((insn & 0x20) && s[1])
917 (*info->fprintf_func) (info->stream, ",n ");
918 else if (insn & 0x20)
919 (*info->fprintf_func) (info->stream, ",n");
920 else if (s[1])
921 (*info->fprintf_func) (info->stream, " ");
922 break;
923 case 'w':
924 (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
925 info);
926 break;
927 case 'W':
928 /* 17 bit PC-relative branch. */
929 (*info->print_address_func) ((memaddr + 8
930 + extract_17 (insn)),
931 info);
932 break;
933 case 'z':
934 /* 17 bit displacement. This is an offset from a register
935 so it gets disasssembled as just a number, not any sort
936 of address. */
937 fput_const (extract_17 (insn), info);
938 break;
d1e9bd1f
JL
939
940 case 'Z':
941 /* addil %r1 implicit output. */
2beaab59 942 (*info->fprintf_func) (info->stream, "%%r1");
d1e9bd1f 943 break;
1fb72ed1
JL
944
945 case 'Y':
946 /* be,l %sr0,%r31 implicit output. */
947 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
948 break;
d1e9bd1f 949
1c170bd8
JL
950 case '@':
951 (*info->fprintf_func) (info->stream, "0");
952 break;
953
46424e05
JL
954 case '.':
955 (*info->fprintf_func) (info->stream, "%d",
956 GET_FIELD (insn, 24, 25));
957 break;
3b67cf2b
JL
958 case '*':
959 (*info->fprintf_func) (info->stream, "%d",
960 GET_FIELD (insn, 22, 25));
961 break;
b7d6d485 962 case '!':
2beaab59 963 (*info->fprintf_func) (info->stream, "%%sar");
b7d6d485 964 break;
252b5132
RH
965 case 'p':
966 (*info->fprintf_func) (info->stream, "%d",
967 31 - GET_FIELD (insn, 22, 26));
968 break;
46424e05
JL
969 case '~':
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", 63 - num);
975 break;
976 }
252b5132
RH
977 case 'P':
978 (*info->fprintf_func) (info->stream, "%d",
979 GET_FIELD (insn, 22, 26));
980 break;
af10de82
JL
981 case 'q':
982 {
983 int num;
984 num = GET_FIELD (insn, 20, 20) << 5;
985 num |= GET_FIELD (insn, 22, 26);
986 (*info->fprintf_func) (info->stream, "%d", num);
987 break;
988 }
252b5132
RH
989 case 'T':
990 (*info->fprintf_func) (info->stream, "%d",
991 32 - GET_FIELD (insn, 27, 31));
992 break;
af10de82
JL
993 case '%':
994 {
995 int num;
996 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
997 num -= GET_FIELD (insn, 27, 31);
998 (*info->fprintf_func) (info->stream, "%d", num);
999 break;
1000 }
1001 case '|':
1002 {
1003 int num;
1004 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
1005 num -= GET_FIELD (insn, 27, 31);
1006 (*info->fprintf_func) (info->stream, "%d", num);
1007 break;
1008 }
46424e05
JL
1009 case '$':
1010 fput_const (GET_FIELD (insn, 20, 28), info);
1011 break;
252b5132
RH
1012 case 'A':
1013 fput_const (GET_FIELD (insn, 6, 18), info);
1014 break;
252b5132
RH
1015 case 'D':
1016 fput_const (GET_FIELD (insn, 6, 31), info);
1017 break;
a349b151 1018 case 'v':
252b5132
RH
1019 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1020 break;
1021 case 'O':
1022 fput_const ((GET_FIELD (insn, 6,20) << 5 |
1023 GET_FIELD (insn, 27, 31)), info);
1024 break;
1025 case 'o':
1026 fput_const (GET_FIELD (insn, 6, 20), info);
1027 break;
252b5132
RH
1028 case '2':
1029 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
1030 GET_FIELD (insn, 27, 31)), info);
1031 break;
1032 case '1':
1033 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
1034 GET_FIELD (insn, 27, 31)), info);
1035 break;
1036 case '0':
1037 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
1038 GET_FIELD (insn, 27, 31)), info);
1039 break;
1040 case 'u':
1041 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1042 break;
1043 case 'F':
1044 /* if no destination completer and not before a completer
1045 for fcmp, need a space here */
4f312591 1046 if (s[1] == 'G' || s[1] == '?')
252b5132
RH
1047 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
1048 info);
1049 else
1050 (*info->fprintf_func) (info->stream, "%s ",
1051 float_format_names[GET_FIELD
1052 (insn, 19, 20)]);
1053 break;
1054 case 'G':
1055 (*info->fprintf_func) (info->stream, "%s ",
1056 float_format_names[GET_FIELD (insn,
1057 17, 18)]);
1058 break;
1059 case 'H':
1060 if (GET_FIELD (insn, 26, 26) == 1)
1061 (*info->fprintf_func) (info->stream, "%s ",
1062 float_format_names[0]);
1063 else
1064 (*info->fprintf_func) (info->stream, "%s ",
1065 float_format_names[1]);
1066 break;
1067 case 'I':
1068 /* if no destination completer and not before a completer
1069 for fcmp, need a space here */
4f312591 1070 if (s[1] == '?')
252b5132
RH
1071 fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
1072 info);
1073 else
1074 (*info->fprintf_func) (info->stream, "%s ",
1075 float_format_names[GET_FIELD
1076 (insn, 20, 20)]);
1077 break;
eb32eb44
JL
1078
1079 case 'J':
1080 fput_const (extract_14 (insn), info);
1081 break;
1082
d758242c
JL
1083 case '#':
1084 {
1085 int sign = GET_FIELD (insn, 31, 31);
1086 int imm10 = GET_FIELD (insn, 18, 27);
1087 int disp;
1088
1089 if (sign)
1090 disp = (-1 << 10) | imm10;
1091 else
1092 disp = imm10;
1093
1094 disp <<= 3;
1095 fput_const (disp, info);
1096 break;
1097 }
eb32eb44 1098 case 'K':
d758242c
JL
1099 case 'd':
1100 {
1101 int sign = GET_FIELD (insn, 31, 31);
1102 int imm11 = GET_FIELD (insn, 18, 28);
1103 int disp;
1104
1105 if (sign)
1106 disp = (-1 << 11) | imm11;
1107 else
1108 disp = imm11;
1109
1110 disp <<= 2;
1111 fput_const (disp, info);
1112 break;
1113 }
1114
1328dc98 1115 case '>':
91b1cc5d
JL
1116 case 'y':
1117 {
1118 /* 16-bit long disp., PA2.0 wide only. */
1119 int disp = extract_16 (insn);
1120 disp &= ~3;
1121 fput_const (disp, info);
1122 break;
1123 }
1124
1125 case '&':
1126 {
1127 /* 16-bit long disp., PA2.0 wide only. */
1128 int disp = extract_16 (insn);
1129 disp &= ~7;
1130 fput_const (disp, info);
1131 break;
1132 }
1133
838c65f0
JL
1134 /* ?!? FIXME */
1135 case '_':
1136 case '{':
1137 fputs_filtered ("Disassembler botch.\n", info);
1138 break;
1139
1140 case 'm':
1141 {
1142 int y = GET_FIELD (insn, 16, 18);
1143
1144 if (y != 1)
1145 fput_const ((y ^ 1) - 1, info);
1146 }
1147 break;
1148
1149 case 'h':
1150 {
1151 int cbit;
1152
1153 cbit = GET_FIELD (insn, 16, 18);
1154
1155 if (cbit > 0)
1156 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1157 break;
1158 }
1159
1160 case '=':
1161 {
1162 int cond = GET_FIELD (insn, 27, 31);
1163
1164 if (cond == 0)
1165 fputs_filtered (" ", info);
1166 else if (cond == 1)
1167 fputs_filtered ("acc ", info);
1168 else if (cond == 2)
1169 fputs_filtered ("rej ", info);
1170 else if (cond == 5)
1171 fputs_filtered ("acc8 ", info);
1172 else if (cond == 6)
1173 fputs_filtered ("rej8 ", info);
1174 else if (cond == 9)
1175 fputs_filtered ("acc6 ", info);
1176 else if (cond == 13)
1177 fputs_filtered ("acc4 ", info);
1178 else if (cond == 17)
1179 fputs_filtered ("acc2 ", info);
1180 break;
1181 }
1182
3610d131
JL
1183 case 'X':
1184 (*info->print_address_func) ((memaddr + 8
1185 + extract_22 (insn)),
1186 info);
1187 break;
2784abe5
JL
1188 case 'L':
1189 fputs_filtered (",%r2", info);
1190 break;
252b5132
RH
1191 default:
1192 (*info->fprintf_func) (info->stream, "%c", *s);
1193 break;
1194 }
1195 }
1196 return sizeof(insn);
1197 }
1198 }
1199 (*info->fprintf_func) (info->stream, "#%8x", insn);
1200 return sizeof(insn);
1201}
This page took 0.225422 seconds and 4 git commands to generate.