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