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