source: branches/libc-0.6/src/binutils/opcodes/hppa-dis.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 32.1 KB
Line 
1/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2 Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003
3 Free Software Foundation, Inc.
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
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
46/* Get at various relevent fields of an instruction word. */
47
48#define MASK_5 0x1f
49#define MASK_10 0x3ff
50#define MASK_11 0x7ff
51#define MASK_14 0x3fff
52#define MASK_16 0xffff
53#define MASK_21 0x1fffff
54
55/* These macros get bit fields using HP's numbering (MSB = 0) */
56
57#define GET_FIELD(X, FROM, TO) \
58 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
59
60#define GET_BIT(X, WHICH) \
61 GET_FIELD (X, WHICH, WHICH)
62
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. */
66static const char *const control_reg[] = {
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
74static const char *const compare_cond_names[] = {
75 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
76 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
77};
78static const char *const compare_cond_64_names[] = {
79 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
80 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
81};
82static const char *const cmpib_cond_64_names[] = {
83 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
84};
85static const char *const add_cond_names[] = {
86 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
87 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
88};
89static const char *const add_cond_64_names[] = {
90 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
91 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
92};
93static const char *const wide_add_cond_names[] = {
94 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
95 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
96};
97static const char *const logical_cond_names[] = {
98 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
99 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
100static const char *const logical_cond_64_names[] = {
101 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
102 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
103static const char *const unit_cond_names[] = {
104 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
105 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
106};
107static const char *const unit_cond_64_names[] = {
108 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
109 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
110};
111static const char *const shift_cond_names[] = {
112 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
113};
114static const char *const shift_cond_64_names[] = {
115 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
116};
117static const char *const bb_cond_64_names[] = {
118 ",*<", ",*>="
119};
120static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
121static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
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"};
126static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
127static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
128static const char *const float_comp_names[] =
129{
130 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
131 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
132 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
133 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
134};
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" };
140
141/* For a bunch of different instructions form an index into a
142 completer name table. */
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
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
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
199 (*info->fprintf_func) (info->stream, "%sR",
200 reg ? fp_reg_names[reg] : "fr0");
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
211/* Print constants with sign. */
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
225 instructions. */
226
227/* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */
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
242/* Extract the immediate field from a st{bhw}s instruction. */
243static int
244extract_5_store (word)
245 unsigned word;
246{
247 return low_sign_extend (word & MASK_5, 5);
248}
249
250/* Extract the immediate field from a break instruction. */
251static unsigned
252extract_5r_store (word)
253 unsigned word;
254{
255 return (word & MASK_5);
256}
257
258/* Extract the immediate field from a {sr}sm instruction. */
259static unsigned
260extract_5R_store (word)
261 unsigned word;
262{
263 return (word >> 16 & MASK_5);
264}
265
266/* Extract the 10 bit immediate field from a {sr}sm instruction. */
267static unsigned
268extract_10U_store (word)
269 unsigned word;
270{
271 return (word >> 16 & MASK_10);
272}
273
274/* Extract the immediate field from a bb instruction. */
275static unsigned
276extract_5Q_store (word)
277 unsigned word;
278{
279 return (word >> 21 & MASK_5);
280}
281
282/* Extract an 11 bit immediate field. */
283static int
284extract_11 (word)
285 unsigned word;
286{
287 return low_sign_extend (word & MASK_11, 11);
288}
289
290/* Extract a 14 bit immediate field. */
291static int
292extract_14 (word)
293 unsigned word;
294{
295 return low_sign_extend (word & MASK_14, 14);
296}
297
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. */
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
334/* Extract a 12 bit constant from branch instructions. */
335
336static int
337extract_12 (word)
338 unsigned word;
339{
340 return sign_extend (GET_FIELD (word, 19, 28) |
341 GET_FIELD (word, 29, 29) << 10 |
342 (word & 0x1) << 11, 12) << 2;
343}
344
345/* Extract a 17 bit constant from branch instructions, returning the
346 19 bit signed value. */
347
348static int
349extract_17 (word)
350 unsigned word;
351{
352 return sign_extend (GET_FIELD (word, 19, 28) |
353 GET_FIELD (word, 29, 29) << 10 |
354 GET_FIELD (word, 11, 15) << 11 |
355 (word & 0x1) << 16, 17) << 2;
356}
357
358static int
359extract_22 (word)
360 unsigned word;
361{
362 return sign_extend (GET_FIELD (word, 19, 28) |
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;
367}
368
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;
396#ifndef BFD64
397 if (opcode->arch == pa20w)
398 continue;
399#endif
400 (*info->fprintf_func) (info->stream, "%s", opcode->name);
401
402 if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
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;
411 case 'a':
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;
418 case 't':
419 fput_reg (GET_FIELD (insn, 27, 31), info);
420 break;
421
422 /* Handle floating point registers. */
423 case 'f':
424 switch (*++s)
425 {
426 case 't':
427 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
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;
441
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. */
446 case 'X':
447 fputs_filtered (" ", info);
448 /* FALLTHRU */
449
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);
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);
481
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);
489
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);
497
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);
505
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 }
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 /* FALLTHRU */
526
527 case 'e':
528 if (GET_FIELD (insn, 30, 30))
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;
533 case 'x':
534 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
535 break;
536 }
537 break;
538
539 case '5':
540 fput_const (extract_5_load (insn), info);
541 break;
542 case 's':
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 }
549 break;
550
551 case 'S':
552 (*info->fprintf_func) (info->stream, "sr%d",
553 extract_3 (insn));
554 break;
555
556 /* Handle completers. */
557 case 'c':
558 switch (*++s)
559 {
560 case 'x':
561 (*info->fprintf_func)
562 (info->stream, "%s",
563 index_compl_names[GET_COMPL (insn)]);
564 break;
565 case 'X':
566 (*info->fprintf_func)
567 (info->stream, "%s ",
568 index_compl_names[GET_COMPL (insn)]);
569 break;
570 case 'm':
571 (*info->fprintf_func)
572 (info->stream, "%s",
573 short_ldst_compl_names[GET_COMPL (insn)]);
574 break;
575 case 'M':
576 (*info->fprintf_func)
577 (info->stream, "%s ",
578 short_ldst_compl_names[GET_COMPL (insn)]);
579 break;
580 case 'A':
581 (*info->fprintf_func)
582 (info->stream, "%s ",
583 short_bytes_compl_names[GET_COMPL (insn)]);
584 break;
585 case 's':
586 (*info->fprintf_func)
587 (info->stream, "%s",
588 short_bytes_compl_names[GET_COMPL (insn)]);
589 break;
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;
617 case 'g':
618 (*info->fprintf_func) (info->stream, ",gate");
619 break;
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':
627 case 'L':
628 (*info->fprintf_func) (info->stream, ",l");
629 break;
630 case 'w':
631 (*info->fprintf_func)
632 (info->stream, "%s ",
633 read_write_names[GET_FIELD (insn, 25, 25)]);
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;
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;
648 case 'i':
649 if (GET_FIELD (insn, 25, 25))
650 (*info->fprintf_func) (info->stream, ",i");
651 break;
652 case 'z':
653 if (!GET_FIELD (insn, 21, 21))
654 (*info->fprintf_func) (info->stream, ",z");
655 break;
656 case 'a':
657 (*info->fprintf_func)
658 (info->stream, "%s",
659 add_compl_names[GET_FIELD (insn, 20, 21)]);
660 break;
661 case 'Y':
662 (*info->fprintf_func)
663 (info->stream, ",dc%s",
664 add_compl_names[GET_FIELD (insn, 20, 21)]);
665 break;
666 case 'y':
667 (*info->fprintf_func)
668 (info->stream, ",c%s",
669 add_compl_names[GET_FIELD (insn, 20, 21)]);
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;
694 case 'S':
695 /* EXTRD/W has a following condition. */
696 if (*(s + 1) == '?')
697 (*info->fprintf_func)
698 (info->stream, "%s",
699 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
700 else
701 (*info->fprintf_func)
702 (info->stream, "%s ",
703 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
704 break;
705 case 'h':
706 (*info->fprintf_func)
707 (info->stream, "%s",
708 mix_half_names[GET_FIELD (insn, 17, 17)]);
709 break;
710 case 'H':
711 (*info->fprintf_func)
712 (info->stream, "%s ",
713 saturation_names[GET_FIELD (insn, 24, 25)]);
714 break;
715 case '*':
716 (*info->fprintf_func)
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));
720 break;
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 {
740 int opc = GET_FIELD (insn, 0, 5);
741
742 if (opc == 0x16 || opc == 0x1e)
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
754 case 'e':
755 {
756 int opc = GET_FIELD (insn, 0, 5);
757
758 if (opc == 0x13 || opc == 0x1b)
759 {
760 if (GET_FIELD (insn, 18, 18) == 1)
761 fputs_filtered (",mb ", info);
762 else
763 fputs_filtered (",ma ", info);
764 }
765 else if (opc == 0x17 || opc == 0x1f)
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 }
777 }
778 break;
779
780 /* Handle conditions. */
781 case '?':
782 {
783 s++;
784 switch (*s)
785 {
786 case 'f':
787 (*info->fprintf_func)
788 (info->stream, "%s ",
789 float_comp_names[GET_FIELD (insn, 27, 31)]);
790 break;
791
792 /* these four conditions are for the set of instructions
793 which distinguish true/false conditions by opcode
794 rather than by the 'f' bit (sigh): comb, comib,
795 addb, addib */
796 case 't':
797 fputs_filtered
798 (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
799 break;
800 case 'n':
801 fputs_filtered
802 (compare_cond_names[GET_FIELD (insn, 16, 18)
803 + GET_FIELD (insn, 4, 4) * 8],
804 info);
805 break;
806 case 'N':
807 fputs_filtered
808 (compare_cond_64_names[GET_FIELD (insn, 16, 18)
809 + GET_FIELD (insn, 2, 2) * 8],
810 info);
811 break;
812 case 'Q':
813 fputs_filtered
814 (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
815 info);
816 break;
817 case '@':
818 fputs_filtered
819 (add_cond_names[GET_FIELD (insn, 16, 18)
820 + GET_FIELD (insn, 4, 4) * 8],
821 info);
822 break;
823 case 's':
824 (*info->fprintf_func)
825 (info->stream, "%s ",
826 compare_cond_names[GET_COND (insn)]);
827 break;
828 case 'S':
829 (*info->fprintf_func)
830 (info->stream, "%s ",
831 compare_cond_64_names[GET_COND (insn)]);
832 break;
833 case 'a':
834 (*info->fprintf_func)
835 (info->stream, "%s ",
836 add_cond_names[GET_COND (insn)]);
837 break;
838 case 'A':
839 (*info->fprintf_func)
840 (info->stream, "%s ",
841 add_cond_64_names[GET_COND (insn)]);
842 break;
843 case 'd':
844 (*info->fprintf_func)
845 (info->stream, "%s",
846 add_cond_names[GET_FIELD (insn, 16, 18)]);
847 break;
848
849 case 'W':
850 (*info->fprintf_func)
851 (info->stream, "%s",
852 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
853 GET_FIELD (insn, 4, 4) * 8]);
854 break;
855
856 case 'l':
857 (*info->fprintf_func)
858 (info->stream, "%s ",
859 logical_cond_names[GET_COND (insn)]);
860 break;
861 case 'L':
862 (*info->fprintf_func)
863 (info->stream, "%s ",
864 logical_cond_64_names[GET_COND (insn)]);
865 break;
866 case 'u':
867 (*info->fprintf_func)
868 (info->stream, "%s ",
869 unit_cond_names[GET_COND (insn)]);
870 break;
871 case 'U':
872 (*info->fprintf_func)
873 (info->stream, "%s ",
874 unit_cond_64_names[GET_COND (insn)]);
875 break;
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;
888 case 'X':
889 (*info->fprintf_func)
890 (info->stream, "%s ",
891 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
892 break;
893 case 'B':
894 (*info->fprintf_func)
895 (info->stream, "%s",
896 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
897
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;
903 }
904 break;
905 }
906
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;
916 case 'U':
917 fput_const (extract_10U_store (insn), info);
918 break;
919 case 'B':
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;
932 case '<':
933 case 'l':
934 /* 16-bit long disp., PA2.0 wide only. */
935 fput_const (extract_16 (insn), info);
936 break;
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':
952 (*info->print_address_func)
953 (memaddr + 8 + extract_12 (insn), info);
954 break;
955 case 'W':
956 /* 17 bit PC-relative branch. */
957 (*info->print_address_func)
958 ((memaddr + 8 + extract_17 (insn)), info);
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;
966
967 case 'Z':
968 /* addil %r1 implicit output. */
969 (*info->fprintf_func) (info->stream, "%%r1");
970 break;
971
972 case 'Y':
973 /* be,l %sr0,%r31 implicit output. */
974 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
975 break;
976
977 case '@':
978 (*info->fprintf_func) (info->stream, "0");
979 break;
980
981 case '.':
982 (*info->fprintf_func) (info->stream, "%d",
983 GET_FIELD (insn, 24, 25));
984 break;
985 case '*':
986 (*info->fprintf_func) (info->stream, "%d",
987 GET_FIELD (insn, 22, 25));
988 break;
989 case '!':
990 (*info->fprintf_func) (info->stream, "%%sar");
991 break;
992 case 'p':
993 (*info->fprintf_func) (info->stream, "%d",
994 31 - GET_FIELD (insn, 22, 26));
995 break;
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 }
1004 case 'P':
1005 (*info->fprintf_func) (info->stream, "%d",
1006 GET_FIELD (insn, 22, 26));
1007 break;
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 }
1016 case 'T':
1017 (*info->fprintf_func) (info->stream, "%d",
1018 32 - GET_FIELD (insn, 27, 31));
1019 break;
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 }
1036 case '$':
1037 fput_const (GET_FIELD (insn, 20, 28), info);
1038 break;
1039 case 'A':
1040 fput_const (GET_FIELD (insn, 6, 18), info);
1041 break;
1042 case 'D':
1043 fput_const (GET_FIELD (insn, 6, 31), info);
1044 break;
1045 case 'v':
1046 (*info->fprintf_func) (info->stream, ",%d",
1047 GET_FIELD (insn, 23, 25));
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;
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':
1069 (*info->fprintf_func) (info->stream, ",%d",
1070 GET_FIELD (insn, 23, 25));
1071 break;
1072 case 'F':
1073 /* if no destination completer and not before a completer
1074 for fcmp, need a space here */
1075 if (s[1] == 'G' || s[1] == '?')
1076 fputs_filtered
1077 (float_format_names[GET_FIELD (insn, 19, 20)], info);
1078 else
1079 (*info->fprintf_func)
1080 (info->stream, "%s ",
1081 float_format_names[GET_FIELD (insn, 19, 20)]);
1082 break;
1083 case 'G':
1084 (*info->fprintf_func)
1085 (info->stream, "%s ",
1086 float_format_names[GET_FIELD (insn, 17, 18)]);
1087 break;
1088 case 'H':
1089 if (GET_FIELD (insn, 26, 26) == 1)
1090 (*info->fprintf_func) (info->stream, "%s ",
1091 float_format_names[0]);
1092 else
1093 (*info->fprintf_func) (info->stream, "%s ",
1094 float_format_names[1]);
1095 break;
1096 case 'I':
1097 /* if no destination completer and not before a completer
1098 for fcmp, need a space here */
1099 if (s[1] == '?')
1100 fputs_filtered
1101 (float_format_names[GET_FIELD (insn, 20, 20)], info);
1102 else
1103 (*info->fprintf_func)
1104 (info->stream, "%s ",
1105 float_format_names[GET_FIELD (insn, 20, 20)]);
1106 break;
1107
1108 case 'J':
1109 fput_const (extract_14 (insn), info);
1110 break;
1111
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 }
1127 case 'K':
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
1144 case '>':
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
1163 case '_':
1164 break; /* Dealt with by '{' */
1165
1166 case '{':
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 }
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
1234 case 'X':
1235 (*info->print_address_func)
1236 (memaddr + 8 + extract_22 (insn), info);
1237 break;
1238 case 'L':
1239 fputs_filtered (",%r2", info);
1240 break;
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}
Note: See TracBrowser for help on using the repository browser.