* hppa-dis.c (unit_cond_names): Add PA2.0 unit condition names.
[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 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
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;
61e8273b 826 case 'B':
252b5132
RH
827 case 'Q':
828 fput_const (extract_5Q_store (insn), info);
829 break;
830 case 'i':
831 fput_const (extract_11 (insn), info);
832 break;
833 case 'j':
834 fput_const (extract_14 (insn), info);
835 break;
836 case 'k':
837 fput_const (extract_21 (insn), info);
838 break;
839 case 'n':
840 if (insn & 0x2)
841 (*info->fprintf_func) (info->stream, ",n ");
842 else
843 (*info->fprintf_func) (info->stream, " ");
844 break;
845 case 'N':
846 if ((insn & 0x20) && s[1])
847 (*info->fprintf_func) (info->stream, ",n ");
848 else if (insn & 0x20)
849 (*info->fprintf_func) (info->stream, ",n");
850 else if (s[1])
851 (*info->fprintf_func) (info->stream, " ");
852 break;
853 case 'w':
854 (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
855 info);
856 break;
857 case 'W':
858 /* 17 bit PC-relative branch. */
859 (*info->print_address_func) ((memaddr + 8
860 + extract_17 (insn)),
861 info);
862 break;
863 case 'z':
864 /* 17 bit displacement. This is an offset from a register
865 so it gets disasssembled as just a number, not any sort
866 of address. */
867 fput_const (extract_17 (insn), info);
868 break;
d1e9bd1f
JL
869
870 case 'Z':
871 /* addil %r1 implicit output. */
2beaab59 872 (*info->fprintf_func) (info->stream, "%%r1");
d1e9bd1f 873 break;
1fb72ed1
JL
874
875 case 'Y':
876 /* be,l %sr0,%r31 implicit output. */
877 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
878 break;
d1e9bd1f 879
1c170bd8
JL
880 case '@':
881 (*info->fprintf_func) (info->stream, "0");
882 break;
883
46424e05
JL
884 case '.':
885 (*info->fprintf_func) (info->stream, "%d",
886 GET_FIELD (insn, 24, 25));
887 break;
3b67cf2b
JL
888 case '*':
889 (*info->fprintf_func) (info->stream, "%d",
890 GET_FIELD (insn, 22, 25));
891 break;
b7d6d485 892 case '!':
2beaab59 893 (*info->fprintf_func) (info->stream, "%%sar");
b7d6d485 894 break;
252b5132
RH
895 case 'p':
896 (*info->fprintf_func) (info->stream, "%d",
897 31 - GET_FIELD (insn, 22, 26));
898 break;
46424e05
JL
899 case '~':
900 {
901 int num;
902 num = GET_FIELD (insn, 20, 20) << 5;
903 num |= GET_FIELD (insn, 22, 26);
904 (*info->fprintf_func) (info->stream, "%d", 63 - num);
905 break;
906 }
252b5132
RH
907 case 'P':
908 (*info->fprintf_func) (info->stream, "%d",
909 GET_FIELD (insn, 22, 26));
910 break;
af10de82
JL
911 case 'q':
912 {
913 int num;
914 num = GET_FIELD (insn, 20, 20) << 5;
915 num |= GET_FIELD (insn, 22, 26);
916 (*info->fprintf_func) (info->stream, "%d", num);
917 break;
918 }
252b5132
RH
919 case 'T':
920 (*info->fprintf_func) (info->stream, "%d",
921 32 - GET_FIELD (insn, 27, 31));
922 break;
af10de82
JL
923 case '%':
924 {
925 int num;
926 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
927 num -= GET_FIELD (insn, 27, 31);
928 (*info->fprintf_func) (info->stream, "%d", num);
929 break;
930 }
931 case '|':
932 {
933 int num;
934 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
935 num -= GET_FIELD (insn, 27, 31);
936 (*info->fprintf_func) (info->stream, "%d", num);
937 break;
938 }
46424e05
JL
939 case '$':
940 fput_const (GET_FIELD (insn, 20, 28), info);
941 break;
252b5132
RH
942 case 'A':
943 fput_const (GET_FIELD (insn, 6, 18), info);
944 break;
252b5132
RH
945 case 'D':
946 fput_const (GET_FIELD (insn, 6, 31), info);
947 break;
a349b151 948 case 'v':
252b5132
RH
949 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
950 break;
951 case 'O':
952 fput_const ((GET_FIELD (insn, 6,20) << 5 |
953 GET_FIELD (insn, 27, 31)), info);
954 break;
955 case 'o':
956 fput_const (GET_FIELD (insn, 6, 20), info);
957 break;
252b5132
RH
958 case '2':
959 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
960 GET_FIELD (insn, 27, 31)), info);
961 break;
962 case '1':
963 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
964 GET_FIELD (insn, 27, 31)), info);
965 break;
966 case '0':
967 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
968 GET_FIELD (insn, 27, 31)), info);
969 break;
970 case 'u':
971 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
972 break;
973 case 'F':
974 /* if no destination completer and not before a completer
975 for fcmp, need a space here */
4f312591 976 if (s[1] == 'G' || s[1] == '?')
252b5132
RH
977 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
978 info);
979 else
980 (*info->fprintf_func) (info->stream, "%s ",
981 float_format_names[GET_FIELD
982 (insn, 19, 20)]);
983 break;
984 case 'G':
985 (*info->fprintf_func) (info->stream, "%s ",
986 float_format_names[GET_FIELD (insn,
987 17, 18)]);
988 break;
989 case 'H':
990 if (GET_FIELD (insn, 26, 26) == 1)
991 (*info->fprintf_func) (info->stream, "%s ",
992 float_format_names[0]);
993 else
994 (*info->fprintf_func) (info->stream, "%s ",
995 float_format_names[1]);
996 break;
997 case 'I':
998 /* if no destination completer and not before a completer
999 for fcmp, need a space here */
4f312591 1000 if (s[1] == '?')
252b5132
RH
1001 fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
1002 info);
1003 else
1004 (*info->fprintf_func) (info->stream, "%s ",
1005 float_format_names[GET_FIELD
1006 (insn, 20, 20)]);
1007 break;
eb32eb44
JL
1008
1009 case 'J':
1010 fput_const (extract_14 (insn), info);
1011 break;
1012
d758242c
JL
1013 case '#':
1014 {
1015 int sign = GET_FIELD (insn, 31, 31);
1016 int imm10 = GET_FIELD (insn, 18, 27);
1017 int disp;
1018
1019 if (sign)
1020 disp = (-1 << 10) | imm10;
1021 else
1022 disp = imm10;
1023
1024 disp <<= 3;
1025 fput_const (disp, info);
1026 break;
1027 }
eb32eb44 1028 case 'K':
d758242c
JL
1029 case 'd':
1030 {
1031 int sign = GET_FIELD (insn, 31, 31);
1032 int imm11 = GET_FIELD (insn, 18, 28);
1033 int disp;
1034
1035 if (sign)
1036 disp = (-1 << 11) | imm11;
1037 else
1038 disp = imm11;
1039
1040 disp <<= 2;
1041 fput_const (disp, info);
1042 break;
1043 }
1044
838c65f0
JL
1045 /* ?!? FIXME */
1046 case '_':
1047 case '{':
1048 fputs_filtered ("Disassembler botch.\n", info);
1049 break;
1050
1051 case 'm':
1052 {
1053 int y = GET_FIELD (insn, 16, 18);
1054
1055 if (y != 1)
1056 fput_const ((y ^ 1) - 1, info);
1057 }
1058 break;
1059
1060 case 'h':
1061 {
1062 int cbit;
1063
1064 cbit = GET_FIELD (insn, 16, 18);
1065
1066 if (cbit > 0)
1067 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1068 break;
1069 }
1070
1071 case '=':
1072 {
1073 int cond = GET_FIELD (insn, 27, 31);
1074
1075 if (cond == 0)
1076 fputs_filtered (" ", info);
1077 else if (cond == 1)
1078 fputs_filtered ("acc ", info);
1079 else if (cond == 2)
1080 fputs_filtered ("rej ", info);
1081 else if (cond == 5)
1082 fputs_filtered ("acc8 ", info);
1083 else if (cond == 6)
1084 fputs_filtered ("rej8 ", info);
1085 else if (cond == 9)
1086 fputs_filtered ("acc6 ", info);
1087 else if (cond == 13)
1088 fputs_filtered ("acc4 ", info);
1089 else if (cond == 17)
1090 fputs_filtered ("acc2 ", info);
1091 break;
1092 }
1093
3610d131
JL
1094 case 'X':
1095 (*info->print_address_func) ((memaddr + 8
1096 + extract_22 (insn)),
1097 info);
1098 break;
2784abe5
JL
1099 case 'L':
1100 fputs_filtered (",%r2", info);
1101 break;
252b5132
RH
1102 default:
1103 (*info->fprintf_func) (info->stream, "%c", *s);
1104 break;
1105 }
1106 }
1107 return sizeof(insn);
1108 }
1109 }
1110 (*info->fprintf_func) (info->stream, "#%8x", insn);
1111 return sizeof(insn);
1112}
This page took 0.161392 seconds and 4 git commands to generate.