* config/tc-hppa.c (pa_ip): Add parens to silence compiler.
[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
21#include <ansidecl.h>
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
3b67cf2b 49#define MASK_10 0x3ff
252b5132
RH
50#define MASK_11 0x7ff
51#define MASK_14 0x3fff
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
RH
99static const char *const unit_cond_names[] = {
100 "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
101 ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
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
136 completer name table. */
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
185/* print constants with sign */
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
199 instructions. */
200
201/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
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
216/* extract the immediate field from a st{bhw}s instruction */
217static int
218extract_5_store (word)
219 unsigned word;
220{
221 return low_sign_extend (word & MASK_5, 5);
222}
223
224/* extract the immediate field from a break instruction */
225static unsigned
226extract_5r_store (word)
227 unsigned word;
228{
229 return (word & MASK_5);
230}
231
232/* extract the immediate field from a {sr}sm instruction */
233static unsigned
234extract_5R_store (word)
235 unsigned word;
236{
237 return (word >> 16 & MASK_5);
238}
239
3b67cf2b
JL
240/* extract the 10 bit immediate field from a {sr}sm instruction */
241static unsigned
242extract_10U_store (word)
243 unsigned word;
244{
245 return (word >> 16 & MASK_10);
246}
247
252b5132
RH
248/* extract the immediate field from a bb instruction */
249static unsigned
250extract_5Q_store (word)
251 unsigned word;
252{
253 return (word >> 21 & MASK_5);
254}
255
256/* extract an 11 bit immediate field */
257static int
258extract_11 (word)
259 unsigned word;
260{
261 return low_sign_extend (word & MASK_11, 11);
262}
263
264/* extract a 14 bit immediate field */
265static int
266extract_14 (word)
267 unsigned word;
268{
269 return low_sign_extend (word & MASK_14, 14);
270}
271
272/* extract a 21 bit constant */
273
274static int
275extract_21 (word)
276 unsigned word;
277{
278 int val;
279
280 word &= MASK_21;
281 word <<= 11;
282 val = GET_FIELD (word, 20, 20);
283 val <<= 11;
284 val |= GET_FIELD (word, 9, 19);
285 val <<= 2;
286 val |= GET_FIELD (word, 5, 6);
287 val <<= 5;
288 val |= GET_FIELD (word, 0, 4);
289 val <<= 2;
290 val |= GET_FIELD (word, 7, 8);
291 return sign_extend (val, 21) << 11;
292}
293
294/* extract a 12 bit constant from branch instructions */
295
296static int
297extract_12 (word)
298 unsigned word;
299{
300 return sign_extend (GET_FIELD (word, 19, 28) |
301 GET_FIELD (word, 29, 29) << 10 |
302 (word & 0x1) << 11, 12) << 2;
303}
304
305/* extract a 17 bit constant from branch instructions, returning the
306 19 bit signed value. */
307
308static int
309extract_17 (word)
310 unsigned word;
311{
312 return sign_extend (GET_FIELD (word, 19, 28) |
313 GET_FIELD (word, 29, 29) << 10 |
314 GET_FIELD (word, 11, 15) << 11 |
315 (word & 0x1) << 16, 17) << 2;
316}
317
b3fe7ee2
JL
318static int
319extract_22 (word)
320 unsigned word;
321{
322 return sign_extend (GET_FIELD (word, 19, 28) |
323 GET_FIELD (word, 29, 29) << 10 |
324 GET_FIELD (word, 11, 15) << 11 |
325 GET_FIELD (word, 6, 10) << 16 |
326 (word & 0x1) << 21, 22) << 2;
327}
328
252b5132
RH
329/* Print one instruction. */
330int
331print_insn_hppa (memaddr, info)
332 bfd_vma memaddr;
333 disassemble_info *info;
334{
335 bfd_byte buffer[4];
336 unsigned int insn, i;
337
338 {
339 int status =
340 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
341 if (status != 0)
342 {
343 (*info->memory_error_func) (status, memaddr, info);
344 return -1;
345 }
346 }
347
348 insn = bfd_getb32 (buffer);
349
350 for (i = 0; i < NUMOPCODES; ++i)
351 {
352 const struct pa_opcode *opcode = &pa_opcodes[i];
353 if ((insn & opcode->mask) == opcode->match)
354 {
355 register const char *s;
356
357 (*info->fprintf_func) (info->stream, "%s", opcode->name);
358
46e36b17 359 if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0]))
252b5132
RH
360 (*info->fprintf_func) (info->stream, " ");
361 for (s = opcode->args; *s != '\0'; ++s)
362 {
363 switch (*s)
364 {
365 case 'x':
366 fput_reg (GET_FIELD (insn, 11, 15), info);
367 break;
1eee34f5 368 case 'a':
252b5132
RH
369 case 'b':
370 fput_reg (GET_FIELD (insn, 6, 10), info);
371 break;
372 case '^':
373 fput_creg (GET_FIELD (insn, 6, 10), info);
374 break;
252b5132
RH
375 case 't':
376 fput_reg (GET_FIELD (insn, 27, 31), info);
377 break;
a349b151
JL
378
379 /* Handle floating point registers. */
380 case 'f':
381 switch (*++s)
382 {
383 case 't':
252b5132 384 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
a349b151
JL
385 break;
386 case 'T':
387 if (GET_FIELD (insn, 25, 25))
388 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
389 else
390 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
391 break;
392 case 'a':
393 if (GET_FIELD (insn, 25, 25))
394 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
395 else
396 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
397 break;
debc018d
JL
398
399 /* 'fA' will not generate a space before the regsiter
400 name. Normally that is fine. Except that it
401 causes problems with xmpyu which has no FP format
402 completer. */
403 case 'X':
404 fputs_filtered (" ", info);
405
406 /* FALLTHRU */
407
a349b151
JL
408 case 'A':
409 if (GET_FIELD (insn, 24, 24))
410 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
411 else
412 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
413
414 break;
415 case 'b':
416 if (GET_FIELD (insn, 25, 25))
417 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
418 else
419 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
420 break;
421 case 'B':
422 if (GET_FIELD (insn, 19, 19))
423 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
424 else
425 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
426 break;
427 case 'C':
428 {
429 int reg = GET_FIELD (insn, 21, 22);
430 reg |= GET_FIELD (insn, 16, 18) << 2;
431 if (GET_FIELD (insn, 23, 23) != 0)
432 fput_fp_reg_r (reg, info);
433 else
434 fput_fp_reg (reg, info);
435 break;
436 }
437 case 'i':
438 {
439 int reg = GET_FIELD (insn, 6, 10);
252b5132 440
a349b151
JL
441 reg |= (GET_FIELD (insn, 26, 26) << 4);
442 fput_fp_reg (reg, info);
443 break;
444 }
445 case 'j':
446 {
447 int reg = GET_FIELD (insn, 11, 15);
252b5132 448
a349b151
JL
449 reg |= (GET_FIELD (insn, 26, 26) << 4);
450 fput_fp_reg (reg, info);
451 break;
452 }
453 case 'k':
454 {
455 int reg = GET_FIELD (insn, 27, 31);
252b5132 456
a349b151
JL
457 reg |= (GET_FIELD (insn, 26, 26) << 4);
458 fput_fp_reg (reg, info);
459 break;
460 }
461 case 'l':
462 {
463 int reg = GET_FIELD (insn, 21, 25);
252b5132 464
a349b151
JL
465 reg |= (GET_FIELD (insn, 26, 26) << 4);
466 fput_fp_reg (reg, info);
467 break;
468 }
469 case 'm':
470 {
471 int reg = GET_FIELD (insn, 16, 20);
472
473 reg |= (GET_FIELD (insn, 26, 26) << 4);
474 fput_fp_reg (reg, info);
475 break;
476 }
f322c2c2
JL
477 case 'e':
478 if (GET_FIELD (insn, 25, 25))
479 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
480 else
481 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
482 break;
483
a349b151 484 }
2f87f883 485 break;
252b5132 486
252b5132
RH
487 case '5':
488 fput_const (extract_5_load (insn), info);
489 break;
490 case 's':
491 (*info->fprintf_func) (info->stream,
492 "sr%d", GET_FIELD (insn, 16, 17));
493 break;
b333b6c6 494
252b5132
RH
495 case 'S':
496 (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
497 break;
3281117a
JL
498
499 /* Handle completers. */
252b5132 500 case 'c':
3281117a
JL
501 switch (*++s)
502 {
503 case 'x':
504 (*info->fprintf_func) (info->stream, "%s ",
505 index_compl_names[GET_COMPL (insn)]);
506 break;
507 case 'm':
508 (*info->fprintf_func) (info->stream, "%s ",
509 short_ldst_compl_names[GET_COMPL (insn)]);
510 break;
511 case 's':
512 (*info->fprintf_func) (info->stream, "%s ",
513 short_bytes_compl_names[GET_COMPL (insn)]);
514 break;
3b67cf2b
JL
515 case 'L':
516 (*info->fprintf_func) (info->stream, ",l");
517 break;
518 case 'w':
519 (*info->fprintf_func) (info->stream, "%s ",
520 read_write_names[GET_FIELD (insn, 25, 25)]);
521 break;
522 case 'W':
523 (*info->fprintf_func) (info->stream, ",w");
524 break;
525 case 'r':
526 if (GET_FIELD (insn, 23, 26) == 5)
527 (*info->fprintf_func) (info->stream, ",r");
528 break;
3281117a
JL
529 case 'Z':
530 if (GET_FIELD (insn, 26, 26))
531 (*info->fprintf_func) (info->stream, ",m ");
532 else
533 (*info->fprintf_func) (info->stream, " ");
534 break;
3b67cf2b
JL
535 case 'i':
536 if (GET_FIELD (insn, 25, 25))
537 (*info->fprintf_func) (info->stream, ",i");
538 break;
af10de82
JL
539 case 'z':
540 if (!GET_FIELD (insn, 21, 21))
541 (*info->fprintf_func) (info->stream, ",z");
542 break;
3b67cf2b
JL
543 case 'a':
544 (*info->fprintf_func)
545 (info->stream, "%s", add_compl_names[GET_FIELD
546 (insn, 20, 21)]);
547 break;
548 case 'Y':
549 (*info->fprintf_func)
550 (info->stream, ",dc%s", add_compl_names[GET_FIELD
551 (insn, 20, 21)]);
552 break;
553 case 'y':
554 (*info->fprintf_func)
555 (info->stream, ",c%s", add_compl_names[GET_FIELD
556 (insn, 20, 21)]);
557 break;
558 case 'v':
559 if (GET_FIELD (insn, 20, 20))
560 (*info->fprintf_func) (info->stream, ",tsv");
561 break;
562 case 't':
563 (*info->fprintf_func) (info->stream, ",tc");
564 if (GET_FIELD (insn, 20, 20))
565 (*info->fprintf_func) (info->stream, ",tsv");
566 break;
567 case 'B':
568 (*info->fprintf_func) (info->stream, ",db");
569 if (GET_FIELD (insn, 20, 20))
570 (*info->fprintf_func) (info->stream, ",tsv");
571 break;
572 case 'b':
573 (*info->fprintf_func) (info->stream, ",b");
574 if (GET_FIELD (insn, 20, 20))
575 (*info->fprintf_func) (info->stream, ",tsv");
576 break;
577 case 'T':
578 if (GET_FIELD (insn, 25, 25))
579 (*info->fprintf_func) (info->stream, ",tc");
580 break;
1eee34f5
JL
581 case 'S':
582 /* EXTRD/W has a following condition. */
583 if (*(s + 1) == '?')
584 (*info->fprintf_func)
585 (info->stream, "%s", signed_unsigned_names[GET_FIELD
586 (insn, 21, 21)]);
587 else
588 (*info->fprintf_func)
589 (info->stream, "%s ", signed_unsigned_names[GET_FIELD
590 (insn, 21, 21)]);
591 break;
592 case 'h':
593 (*info->fprintf_func)
594 (info->stream, "%s", mix_half_names[GET_FIELD
595 (insn, 17, 17)]);
596 break;
597 case 'H':
598 (*info->fprintf_func)
599 (info->stream, "%s", saturation_names[GET_FIELD
600 (insn, 24, 25)]);
601 break;
602 case '*':
603 (*info->fprintf_func)
604 (info->stream, ",%d%d%d%d ",
605 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
606 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
607 break;
9c1faa82
JL
608
609 case 'q':
610 {
611 int m, a;
612
613 m = GET_FIELD (insn, 28, 28);
614 a = GET_FIELD (insn, 29, 29);
615
616 if (m && !a)
617 fputs_filtered (",ma ", info);
618 else if (m && a)
619 fputs_filtered (",mb ", info);
620 else
621 fputs_filtered (" ", info);
622 break;
623 }
624
625 case 'J':
626 {
627 int opcode = GET_FIELD (insn, 0, 5);
628
629 if (opcode == 0x16 || opcode == 0x1e)
630 {
631 if (GET_FIELD (insn, 29, 29) == 0)
632 fputs_filtered (",ma ", info);
633 else
634 fputs_filtered (",mb ", info);
635 }
636 else
637 fputs_filtered (" ", info);
638 break;
639 }
640
641 case 'c':
642 {
643 int opcode = GET_FIELD (insn, 0, 5);
644
645 if (opcode == 0x13 || opcode == 0x1b)
646 {
647 if (GET_FIELD (insn, 18, 18) == 1)
648 fputs_filtered (",mb ", info);
649 else
650 fputs_filtered (",ma ", info);
651 }
652 else if (opcode == 0x17 || opcode == 0x1f)
653 {
654 if (GET_FIELD (insn, 31, 31) == 1)
655 fputs_filtered (",ma ", info);
656 else
657 fputs_filtered (",mb ", info);
658 }
659 else
660 fputs_filtered (" ", info);
661
662 break;
663 }
3281117a 664 }
252b5132 665 break;
feb12992
JL
666
667 /* Handle conditions. */
252b5132 668 case '?':
feb12992
JL
669 {
670 s++;
671 switch (*s)
672 {
673 case 'f':
674 (*info->fprintf_func) (info->stream, "%s ",
675 float_comp_names[GET_FIELD
676 (insn, 27, 31)]);
677 break;
678
679 /* these four conditions are for the set of instructions
680 which distinguish true/false conditions by opcode
681 rather than by the 'f' bit (sigh): comb, comib,
682 addb, addib */
683 case 't':
a349b151 684 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
feb12992
JL
685 info);
686 break;
b333b6c6
JL
687 case 'T':
688 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
689 + 8], info);
690 break;
691 case 'r':
692 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)],
693 info);
694 break;
695 case 'R':
696 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
697 + 8], info);
698 break;
699 case 'Q':
700 fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
701 info);
702 break;
feb12992 703 case 'n':
a349b151 704 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
feb12992
JL
705 + GET_FIELD (insn, 4, 4) * 8], info);
706 break;
707 case '@':
708 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
709 + GET_FIELD (insn, 4, 4) * 8], info);
710 break;
711 case 's':
712 (*info->fprintf_func) (info->stream, "%s ",
713 compare_cond_names[GET_COND (insn)]);
714 break;
b333b6c6
JL
715 case 'S':
716 (*info->fprintf_func) (info->stream, "%s ",
717 compare_cond_64_names[GET_COND (insn)]);
718 break;
feb12992
JL
719 case 'a':
720 (*info->fprintf_func) (info->stream, "%s ",
721 add_cond_names[GET_COND (insn)]);
722 break;
b333b6c6
JL
723 case 'A':
724 (*info->fprintf_func) (info->stream, "%s ",
725 add_cond_64_names[GET_COND (insn)]);
726 break;
feb12992
JL
727 case 'd':
728 (*info->fprintf_func) (info->stream, "%s",
a349b151 729 add_cond_names[GET_FIELD (insn, 16, 18)]);
feb12992 730 break;
a349b151 731
b333b6c6
JL
732 case 'D':
733 (*info->fprintf_func) (info->stream, "%s",
a349b151
JL
734 add_cond_names[GET_FIELD (insn, 16, 18)
735 + 8]);
b333b6c6
JL
736 break;
737 case 'w':
a349b151 738 (*info->fprintf_func)
b333b6c6
JL
739 (info->stream, "%s",
740 wide_add_cond_names[GET_FIELD (insn, 16, 18)]);
741 break;
742
743 case 'W':
a349b151 744 (*info->fprintf_func)
b333b6c6
JL
745 (info->stream, "%s",
746 wide_add_cond_names[GET_FIELD (insn, 16, 18) + 8]);
747 break;
feb12992
JL
748
749 case 'l':
750 (*info->fprintf_func) (info->stream, "%s ",
751 logical_cond_names[GET_COND (insn)]);
752 break;
b333b6c6
JL
753 case 'L':
754 (*info->fprintf_func) (info->stream, "%s ",
755 logical_cond_64_names[GET_COND (insn)]);
756 break;
feb12992
JL
757 case 'u':
758 (*info->fprintf_func) (info->stream, "%s ",
759 unit_cond_names[GET_COND (insn)]);
760 break;
b333b6c6
JL
761 case 'U':
762 (*info->fprintf_func) (info->stream, "%s ",
763 unit_cond_64_names[GET_COND (insn)]);
764 break;
feb12992
JL
765 case 'y':
766 case 'x':
767 case 'b':
768 (*info->fprintf_func)
769 (info->stream, "%s",
770 shift_cond_names[GET_FIELD (insn, 16, 18)]);
771
772 /* If the next character in args is 'n', it will handle
773 putting out the space. */
774 if (s[1] != 'n')
775 (*info->fprintf_func) (info->stream, " ");
776 break;
b333b6c6 777 case 'X':
e46def7b 778 (*info->fprintf_func) (info->stream, "%s ",
b333b6c6
JL
779 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
780 break;
781 case 'B':
782 (*info->fprintf_func)
783 (info->stream, "%s",
784 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
feb12992 785
b333b6c6
JL
786 /* If the next character in args is 'n', it will handle
787 putting out the space. */
788 if (s[1] != 'n')
789 (*info->fprintf_func) (info->stream, " ");
790 break;
feb12992
JL
791 }
792 break;
793 }
252b5132 794
252b5132
RH
795 case 'V':
796 fput_const (extract_5_store (insn), info);
797 break;
798 case 'r':
799 fput_const (extract_5r_store (insn), info);
800 break;
801 case 'R':
802 fput_const (extract_5R_store (insn), info);
803 break;
3b67cf2b
JL
804 case 'U':
805 fput_const (extract_10U_store (insn), info);
806 break;
252b5132
RH
807 case 'Q':
808 fput_const (extract_5Q_store (insn), info);
809 break;
810 case 'i':
811 fput_const (extract_11 (insn), info);
812 break;
813 case 'j':
814 fput_const (extract_14 (insn), info);
815 break;
816 case 'k':
817 fput_const (extract_21 (insn), info);
818 break;
819 case 'n':
820 if (insn & 0x2)
821 (*info->fprintf_func) (info->stream, ",n ");
822 else
823 (*info->fprintf_func) (info->stream, " ");
824 break;
825 case 'N':
826 if ((insn & 0x20) && s[1])
827 (*info->fprintf_func) (info->stream, ",n ");
828 else if (insn & 0x20)
829 (*info->fprintf_func) (info->stream, ",n");
830 else if (s[1])
831 (*info->fprintf_func) (info->stream, " ");
832 break;
833 case 'w':
834 (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
835 info);
836 break;
837 case 'W':
838 /* 17 bit PC-relative branch. */
839 (*info->print_address_func) ((memaddr + 8
840 + extract_17 (insn)),
841 info);
842 break;
843 case 'z':
844 /* 17 bit displacement. This is an offset from a register
845 so it gets disasssembled as just a number, not any sort
846 of address. */
847 fput_const (extract_17 (insn), info);
848 break;
d1e9bd1f
JL
849
850 case 'Z':
851 /* addil %r1 implicit output. */
2beaab59 852 (*info->fprintf_func) (info->stream, "%%r1");
d1e9bd1f
JL
853 break;
854
46424e05
JL
855 case '.':
856 (*info->fprintf_func) (info->stream, "%d",
857 GET_FIELD (insn, 24, 25));
858 break;
3b67cf2b
JL
859 case '*':
860 (*info->fprintf_func) (info->stream, "%d",
861 GET_FIELD (insn, 22, 25));
862 break;
b7d6d485 863 case '!':
2beaab59 864 (*info->fprintf_func) (info->stream, "%%sar");
b7d6d485 865 break;
252b5132
RH
866 case 'p':
867 (*info->fprintf_func) (info->stream, "%d",
868 31 - GET_FIELD (insn, 22, 26));
869 break;
46424e05
JL
870 case '~':
871 {
872 int num;
873 num = GET_FIELD (insn, 20, 20) << 5;
874 num |= GET_FIELD (insn, 22, 26);
875 (*info->fprintf_func) (info->stream, "%d", 63 - num);
876 break;
877 }
252b5132
RH
878 case 'P':
879 (*info->fprintf_func) (info->stream, "%d",
880 GET_FIELD (insn, 22, 26));
881 break;
af10de82
JL
882 case 'q':
883 {
884 int num;
885 num = GET_FIELD (insn, 20, 20) << 5;
886 num |= GET_FIELD (insn, 22, 26);
887 (*info->fprintf_func) (info->stream, "%d", num);
888 break;
889 }
252b5132
RH
890 case 'T':
891 (*info->fprintf_func) (info->stream, "%d",
892 32 - GET_FIELD (insn, 27, 31));
893 break;
af10de82
JL
894 case '%':
895 {
896 int num;
897 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
898 num -= GET_FIELD (insn, 27, 31);
899 (*info->fprintf_func) (info->stream, "%d", num);
900 break;
901 }
902 case '|':
903 {
904 int num;
905 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
906 num -= GET_FIELD (insn, 27, 31);
907 (*info->fprintf_func) (info->stream, "%d", num);
908 break;
909 }
46424e05
JL
910 case '$':
911 fput_const (GET_FIELD (insn, 20, 28), info);
912 break;
252b5132
RH
913 case 'A':
914 fput_const (GET_FIELD (insn, 6, 18), info);
915 break;
252b5132
RH
916 case 'D':
917 fput_const (GET_FIELD (insn, 6, 31), info);
918 break;
a349b151 919 case 'v':
252b5132
RH
920 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
921 break;
922 case 'O':
923 fput_const ((GET_FIELD (insn, 6,20) << 5 |
924 GET_FIELD (insn, 27, 31)), info);
925 break;
926 case 'o':
927 fput_const (GET_FIELD (insn, 6, 20), info);
928 break;
252b5132
RH
929 case '2':
930 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
931 GET_FIELD (insn, 27, 31)), info);
932 break;
933 case '1':
934 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
935 GET_FIELD (insn, 27, 31)), info);
936 break;
937 case '0':
938 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
939 GET_FIELD (insn, 27, 31)), info);
940 break;
941 case 'u':
942 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
943 break;
944 case 'F':
945 /* if no destination completer and not before a completer
946 for fcmp, need a space here */
4f312591 947 if (s[1] == 'G' || s[1] == '?')
252b5132
RH
948 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
949 info);
950 else
951 (*info->fprintf_func) (info->stream, "%s ",
952 float_format_names[GET_FIELD
953 (insn, 19, 20)]);
954 break;
955 case 'G':
956 (*info->fprintf_func) (info->stream, "%s ",
957 float_format_names[GET_FIELD (insn,
958 17, 18)]);
959 break;
960 case 'H':
961 if (GET_FIELD (insn, 26, 26) == 1)
962 (*info->fprintf_func) (info->stream, "%s ",
963 float_format_names[0]);
964 else
965 (*info->fprintf_func) (info->stream, "%s ",
966 float_format_names[1]);
967 break;
968 case 'I':
969 /* if no destination completer and not before a completer
970 for fcmp, need a space here */
4f312591 971 if (s[1] == '?')
252b5132
RH
972 fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
973 info);
974 else
975 (*info->fprintf_func) (info->stream, "%s ",
976 float_format_names[GET_FIELD
977 (insn, 20, 20)]);
978 break;
eb32eb44
JL
979
980 case 'J':
981 fput_const (extract_14 (insn), info);
982 break;
983
d758242c
JL
984 case '#':
985 {
986 int sign = GET_FIELD (insn, 31, 31);
987 int imm10 = GET_FIELD (insn, 18, 27);
988 int disp;
989
990 if (sign)
991 disp = (-1 << 10) | imm10;
992 else
993 disp = imm10;
994
995 disp <<= 3;
996 fput_const (disp, info);
997 break;
998 }
eb32eb44 999 case 'K':
d758242c
JL
1000 case 'd':
1001 {
1002 int sign = GET_FIELD (insn, 31, 31);
1003 int imm11 = GET_FIELD (insn, 18, 28);
1004 int disp;
1005
1006 if (sign)
1007 disp = (-1 << 11) | imm11;
1008 else
1009 disp = imm11;
1010
1011 disp <<= 2;
1012 fput_const (disp, info);
1013 break;
1014 }
1015
838c65f0
JL
1016 /* ?!? FIXME */
1017 case '_':
1018 case '{':
1019 fputs_filtered ("Disassembler botch.\n", info);
1020 break;
1021
1022 case 'm':
1023 {
1024 int y = GET_FIELD (insn, 16, 18);
1025
1026 if (y != 1)
1027 fput_const ((y ^ 1) - 1, info);
1028 }
1029 break;
1030
1031 case 'h':
1032 {
1033 int cbit;
1034
1035 cbit = GET_FIELD (insn, 16, 18);
1036
1037 if (cbit > 0)
1038 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1039 break;
1040 }
1041
1042 case '=':
1043 {
1044 int cond = GET_FIELD (insn, 27, 31);
1045
1046 if (cond == 0)
1047 fputs_filtered (" ", info);
1048 else if (cond == 1)
1049 fputs_filtered ("acc ", info);
1050 else if (cond == 2)
1051 fputs_filtered ("rej ", info);
1052 else if (cond == 5)
1053 fputs_filtered ("acc8 ", info);
1054 else if (cond == 6)
1055 fputs_filtered ("rej8 ", info);
1056 else if (cond == 9)
1057 fputs_filtered ("acc6 ", info);
1058 else if (cond == 13)
1059 fputs_filtered ("acc4 ", info);
1060 else if (cond == 17)
1061 fputs_filtered ("acc2 ", info);
1062 break;
1063 }
1064
3610d131
JL
1065 case 'X':
1066 (*info->print_address_func) ((memaddr + 8
1067 + extract_22 (insn)),
1068 info);
1069 break;
69138680
JL
1070 case 'B':
1071 fputs_filtered (",pop", info);
1072 break;
2784abe5
JL
1073 case 'M':
1074 fputs_filtered (",push", info);
1075 break;
1076 case 'L':
1077 fputs_filtered (",%r2", info);
1078 break;
321e8dac
JL
1079 case 'g':
1080 fputs_filtered (",gate", info);
1081 break;
a5c4b2b4
JL
1082 case 'l':
1083 fputs_filtered (",l", info);
1084 break;
252b5132
RH
1085 default:
1086 (*info->fprintf_func) (info->stream, "%c", *s);
1087 break;
1088 }
1089 }
1090 return sizeof(insn);
1091 }
1092 }
1093 (*info->fprintf_func) (info->stream, "#%8x", insn);
1094 return sizeof(insn);
1095}
This page took 0.086173 seconds and 4 git commands to generate.