* configure.in: Add NetBSD/sparc ELF and NetBSD/sparc64 support.
[deliverable/binutils-gdb.git] / opcodes / hppa-dis.c
CommitLineData
252b5132
RH
1/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2 Copyright 1989, 1990, 1992, 1993 Free Software Foundation, Inc.
3
4 Contributed by the Center for Software Science at the
5 University of Utah (pa-gdb-bugs@cs.utah.edu).
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
252b5132
RH
21#include "sysdep.h"
22#include "dis-asm.h"
23#include "libhppa.h"
24#include "opcode/hppa.h"
25
26/* Integer register names, indexed by the numbers which appear in the
27 opcodes. */
28static const char *const reg_names[] =
29 {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
30 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
31 "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
32 "sp", "r31"};
33
34/* Floating point register names, indexed by the numbers which appear in the
35 opcodes. */
36static const char *const fp_reg_names[] =
37 {"fpsr", "fpe2", "fpe4", "fpe6",
38 "fr4", "fr5", "fr6", "fr7", "fr8",
39 "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
40 "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
41 "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
42
43typedef unsigned int CORE_ADDR;
44
45/* Get at various relevent fields of an instruction word. */
46
47#define MASK_5 0x1f
3b67cf2b 48#define MASK_10 0x3ff
252b5132
RH
49#define MASK_11 0x7ff
50#define MASK_14 0x3fff
51#define MASK_21 0x1fffff
52
53/* This macro gets bit fields using HP's numbering (MSB = 0) */
54
55#define GET_FIELD(X, FROM, TO) \
56 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
57
58/* Some of these have been converted to 2-d arrays because they
59 consume less storage this way. If the maintenance becomes a
60 problem, convert them back to const 1-d pointer arrays. */
58d0c905 61static const char *const control_reg[] = {
252b5132
RH
62 "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
63 "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
64 "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
65 "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
66 "tr4", "tr5", "tr6", "tr7"
67};
68
58d0c905 69static const char *const compare_cond_names[] = {
b333b6c6
JL
70 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
71 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
72};
58d0c905 73static const char *const compare_cond_64_names[] = {
b333b6c6
JL
74 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
75 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
76};
58d0c905 77static const char *const cmpib_cond_64_names[] = {
b333b6c6 78 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
252b5132 79};
58d0c905 80static const char *const add_cond_names[] = {
b333b6c6
JL
81 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
82 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
83};
58d0c905 84static const char *const add_cond_64_names[] = {
d1e9bd1f 85 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
b333b6c6
JL
86 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
87};
58d0c905 88static const char *const wide_add_cond_names[] = {
b333b6c6
JL
89 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
90 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
252b5132
RH
91};
92static const char *const logical_cond_names[] = {
93 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
94 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
b333b6c6 95static const char *const logical_cond_64_names[] = {
d1e9bd1f 96 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
b333b6c6 97 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
252b5132 98static const char *const unit_cond_names[] = {
61e8273b
JL
99 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
100 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
252b5132 101};
b333b6c6 102static const char *const unit_cond_64_names[] = {
d1e9bd1f 103 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
b333b6c6
JL
104 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
105};
58d0c905 106static const char *const shift_cond_names[] = {
252b5132
RH
107 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
108};
58d0c905 109static const char *const shift_cond_64_names[] = {
d1e9bd1f 110 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
b333b6c6 111};
58d0c905 112static const char *const bb_cond_64_names[] = {
b333b6c6
JL
113 ",*<", ",*>="
114};
58d0c905
JL
115static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
116static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
252b5132
RH
117static const char *const short_bytes_compl_names[] = {
118 "", ",b,m", ",e", ",e,m"
119};
120static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
58d0c905 121static const char *const float_comp_names[] =
252b5132
RH
122{
123 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
124 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
125 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
126 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
127};
58d0c905
JL
128static const char *const signed_unsigned_names[] = {",u", ",s"};
129static const char *const mix_half_names[] = {",l", ",r"};
130static const char *const saturation_names[] = {",us", ",ss", 0, ""};
131static const char *const read_write_names[] = {",r", ",w"};
132static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
252b5132
RH
133
134/* For a bunch of different instructions form an index into a
135 completer name table. */
136#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
137 GET_FIELD (insn, 18, 18) << 1)
138
139#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
140 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
141
142/* Utility function to print registers. Put these first, so gcc's function
143 inlining can do its stuff. */
144
145#define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
146
147static void
148fput_reg (reg, info)
149 unsigned reg;
150 disassemble_info *info;
151{
152 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
153}
154
155static void
156fput_fp_reg (reg, info)
157 unsigned reg;
158 disassemble_info *info;
159{
160 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
161}
162
163static void
164fput_fp_reg_r (reg, info)
165 unsigned reg;
166 disassemble_info *info;
167{
168 /* Special case floating point exception registers. */
169 if (reg < 4)
170 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
171 else
172 (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg]
173 : "fr0");
174}
175
176static void
177fput_creg (reg, info)
178 unsigned reg;
179 disassemble_info *info;
180{
181 (*info->fprintf_func) (info->stream, control_reg[reg]);
182}
183
184/* print constants with sign */
185
186static void
187fput_const (num, info)
188 unsigned num;
189 disassemble_info *info;
190{
191 if ((int)num < 0)
192 (*info->fprintf_func) (info->stream, "-%x", -(int)num);
193 else
194 (*info->fprintf_func) (info->stream, "%x", num);
195}
196
197/* Routines to extract various sized constants out of hppa
198 instructions. */
199
200/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
201static int
202extract_3 (word)
203 unsigned word;
204{
205 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
206}
207
208static int
209extract_5_load (word)
210 unsigned word;
211{
212 return low_sign_extend (word >> 16 & MASK_5, 5);
213}
214
215/* extract the immediate field from a st{bhw}s instruction */
216static int
217extract_5_store (word)
218 unsigned word;
219{
220 return low_sign_extend (word & MASK_5, 5);
221}
222
223/* extract the immediate field from a break instruction */
224static unsigned
225extract_5r_store (word)
226 unsigned word;
227{
228 return (word & MASK_5);
229}
230
231/* extract the immediate field from a {sr}sm instruction */
232static unsigned
233extract_5R_store (word)
234 unsigned word;
235{
236 return (word >> 16 & MASK_5);
237}
238
3b67cf2b
JL
239/* extract the 10 bit immediate field from a {sr}sm instruction */
240static unsigned
241extract_10U_store (word)
242 unsigned word;
243{
244 return (word >> 16 & MASK_10);
245}
246
252b5132
RH
247/* extract the immediate field from a bb instruction */
248static unsigned
249extract_5Q_store (word)
250 unsigned word;
251{
252 return (word >> 21 & MASK_5);
253}
254
255/* extract an 11 bit immediate field */
256static int
257extract_11 (word)
258 unsigned word;
259{
260 return low_sign_extend (word & MASK_11, 11);
261}
262
263/* extract a 14 bit immediate field */
264static int
265extract_14 (word)
266 unsigned word;
267{
268 return low_sign_extend (word & MASK_14, 14);
269}
270
271/* extract a 21 bit constant */
272
273static int
274extract_21 (word)
275 unsigned word;
276{
277 int val;
278
279 word &= MASK_21;
280 word <<= 11;
281 val = GET_FIELD (word, 20, 20);
282 val <<= 11;
283 val |= GET_FIELD (word, 9, 19);
284 val <<= 2;
285 val |= GET_FIELD (word, 5, 6);
286 val <<= 5;
287 val |= GET_FIELD (word, 0, 4);
288 val <<= 2;
289 val |= GET_FIELD (word, 7, 8);
290 return sign_extend (val, 21) << 11;
291}
292
293/* extract a 12 bit constant from branch instructions */
294
295static int
296extract_12 (word)
297 unsigned word;
298{
299 return sign_extend (GET_FIELD (word, 19, 28) |
300 GET_FIELD (word, 29, 29) << 10 |
301 (word & 0x1) << 11, 12) << 2;
302}
303
304/* extract a 17 bit constant from branch instructions, returning the
305 19 bit signed value. */
306
307static int
308extract_17 (word)
309 unsigned word;
310{
311 return sign_extend (GET_FIELD (word, 19, 28) |
312 GET_FIELD (word, 29, 29) << 10 |
313 GET_FIELD (word, 11, 15) << 11 |
314 (word & 0x1) << 16, 17) << 2;
315}
316
b3fe7ee2
JL
317static int
318extract_22 (word)
319 unsigned word;
320{
321 return sign_extend (GET_FIELD (word, 19, 28) |
322 GET_FIELD (word, 29, 29) << 10 |
323 GET_FIELD (word, 11, 15) << 11 |
324 GET_FIELD (word, 6, 10) << 16 |
325 (word & 0x1) << 21, 22) << 2;
326}
327
252b5132
RH
328/* Print one instruction. */
329int
330print_insn_hppa (memaddr, info)
331 bfd_vma memaddr;
332 disassemble_info *info;
333{
334 bfd_byte buffer[4];
335 unsigned int insn, i;
336
337 {
338 int status =
339 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
340 if (status != 0)
341 {
342 (*info->memory_error_func) (status, memaddr, info);
343 return -1;
344 }
345 }
346
347 insn = bfd_getb32 (buffer);
348
349 for (i = 0; i < NUMOPCODES; ++i)
350 {
351 const struct pa_opcode *opcode = &pa_opcodes[i];
352 if ((insn & opcode->mask) == opcode->match)
353 {
354 register const char *s;
355
356 (*info->fprintf_func) (info->stream, "%s", opcode->name);
357
46e36b17 358 if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0]))
252b5132
RH
359 (*info->fprintf_func) (info->stream, " ");
360 for (s = opcode->args; *s != '\0'; ++s)
361 {
362 switch (*s)
363 {
364 case 'x':
365 fput_reg (GET_FIELD (insn, 11, 15), info);
366 break;
1eee34f5 367 case 'a':
252b5132
RH
368 case 'b':
369 fput_reg (GET_FIELD (insn, 6, 10), info);
370 break;
371 case '^':
372 fput_creg (GET_FIELD (insn, 6, 10), info);
373 break;
252b5132
RH
374 case 't':
375 fput_reg (GET_FIELD (insn, 27, 31), info);
376 break;
a349b151
JL
377
378 /* Handle floating point registers. */
379 case 'f':
380 switch (*++s)
381 {
382 case 't':
252b5132 383 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
a349b151
JL
384 break;
385 case 'T':
386 if (GET_FIELD (insn, 25, 25))
387 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
388 else
389 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
390 break;
391 case 'a':
392 if (GET_FIELD (insn, 25, 25))
393 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
394 else
395 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
396 break;
debc018d
JL
397
398 /* 'fA' will not generate a space before the regsiter
399 name. Normally that is fine. Except that it
400 causes problems with xmpyu which has no FP format
401 completer. */
402 case 'X':
403 fputs_filtered (" ", info);
404
405 /* FALLTHRU */
406
a349b151
JL
407 case 'A':
408 if (GET_FIELD (insn, 24, 24))
409 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
410 else
411 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
412
413 break;
414 case 'b':
415 if (GET_FIELD (insn, 25, 25))
416 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
417 else
418 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
419 break;
420 case 'B':
421 if (GET_FIELD (insn, 19, 19))
422 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
423 else
424 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
425 break;
426 case 'C':
427 {
428 int reg = GET_FIELD (insn, 21, 22);
429 reg |= GET_FIELD (insn, 16, 18) << 2;
430 if (GET_FIELD (insn, 23, 23) != 0)
431 fput_fp_reg_r (reg, info);
432 else
433 fput_fp_reg (reg, info);
434 break;
435 }
436 case 'i':
437 {
438 int reg = GET_FIELD (insn, 6, 10);
252b5132 439
a349b151
JL
440 reg |= (GET_FIELD (insn, 26, 26) << 4);
441 fput_fp_reg (reg, info);
442 break;
443 }
444 case 'j':
445 {
446 int reg = GET_FIELD (insn, 11, 15);
252b5132 447
a349b151
JL
448 reg |= (GET_FIELD (insn, 26, 26) << 4);
449 fput_fp_reg (reg, info);
450 break;
451 }
452 case 'k':
453 {
454 int reg = GET_FIELD (insn, 27, 31);
252b5132 455
a349b151
JL
456 reg |= (GET_FIELD (insn, 26, 26) << 4);
457 fput_fp_reg (reg, info);
458 break;
459 }
460 case 'l':
461 {
462 int reg = GET_FIELD (insn, 21, 25);
252b5132 463
a349b151
JL
464 reg |= (GET_FIELD (insn, 26, 26) << 4);
465 fput_fp_reg (reg, info);
466 break;
467 }
468 case 'm':
469 {
470 int reg = GET_FIELD (insn, 16, 20);
471
472 reg |= (GET_FIELD (insn, 26, 26) << 4);
473 fput_fp_reg (reg, info);
474 break;
475 }
f322c2c2
JL
476 case 'e':
477 if (GET_FIELD (insn, 25, 25))
478 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
479 else
480 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
481 break;
482
a349b151 483 }
2f87f883 484 break;
252b5132 485
252b5132
RH
486 case '5':
487 fput_const (extract_5_load (insn), info);
488 break;
489 case 's':
490 (*info->fprintf_func) (info->stream,
491 "sr%d", GET_FIELD (insn, 16, 17));
492 break;
b333b6c6 493
252b5132
RH
494 case 'S':
495 (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
496 break;
3281117a
JL
497
498 /* Handle completers. */
252b5132 499 case 'c':
3281117a
JL
500 switch (*++s)
501 {
502 case 'x':
503 (*info->fprintf_func) (info->stream, "%s ",
504 index_compl_names[GET_COMPL (insn)]);
505 break;
506 case 'm':
507 (*info->fprintf_func) (info->stream, "%s ",
508 short_ldst_compl_names[GET_COMPL (insn)]);
509 break;
510 case 's':
511 (*info->fprintf_func) (info->stream, "%s ",
512 short_bytes_compl_names[GET_COMPL (insn)]);
513 break;
1c170bd8
JL
514 case 'c':
515 case 'C':
516 switch (GET_FIELD (insn, 20, 21))
517 {
518 case 1:
519 (*info->fprintf_func) (info->stream, ",bc ");
520 break;
521 case 2:
522 (*info->fprintf_func) (info->stream, ",sl ");
523 break;
524 default:
525 (*info->fprintf_func) (info->stream, " ");
526 }
527 break;
528 case 'd':
529 switch (GET_FIELD (insn, 20, 21))
530 {
531 case 1:
532 (*info->fprintf_func) (info->stream, ",co ");
533 break;
534 default:
535 (*info->fprintf_func) (info->stream, " ");
536 }
537 break;
538 case 'o':
539 (*info->fprintf_func) (info->stream, ",o");
540 break;
1fb72ed1
JL
541 case 'g':
542 (*info->fprintf_func) (info->stream, ",gate");
1c170bd8 543 break;
1fb72ed1
JL
544 case 'p':
545 (*info->fprintf_func) (info->stream, ",l,push");
546 break;
547 case 'P':
548 (*info->fprintf_func) (info->stream, ",pop");
549 break;
550 case 'l':
3b67cf2b
JL
551 case 'L':
552 (*info->fprintf_func) (info->stream, ",l");
553 break;
554 case 'w':
555 (*info->fprintf_func) (info->stream, "%s ",
556 read_write_names[GET_FIELD (insn, 25, 25)]);
557 break;
558 case 'W':
559 (*info->fprintf_func) (info->stream, ",w");
560 break;
561 case 'r':
562 if (GET_FIELD (insn, 23, 26) == 5)
563 (*info->fprintf_func) (info->stream, ",r");
564 break;
3281117a
JL
565 case 'Z':
566 if (GET_FIELD (insn, 26, 26))
567 (*info->fprintf_func) (info->stream, ",m ");
568 else
569 (*info->fprintf_func) (info->stream, " ");
570 break;
3b67cf2b
JL
571 case 'i':
572 if (GET_FIELD (insn, 25, 25))
573 (*info->fprintf_func) (info->stream, ",i");
574 break;
af10de82
JL
575 case 'z':
576 if (!GET_FIELD (insn, 21, 21))
577 (*info->fprintf_func) (info->stream, ",z");
578 break;
3b67cf2b
JL
579 case 'a':
580 (*info->fprintf_func)
581 (info->stream, "%s", add_compl_names[GET_FIELD
582 (insn, 20, 21)]);
583 break;
584 case 'Y':
585 (*info->fprintf_func)
586 (info->stream, ",dc%s", add_compl_names[GET_FIELD
587 (insn, 20, 21)]);
588 break;
589 case 'y':
590 (*info->fprintf_func)
591 (info->stream, ",c%s", add_compl_names[GET_FIELD
592 (insn, 20, 21)]);
593 break;
594 case 'v':
595 if (GET_FIELD (insn, 20, 20))
596 (*info->fprintf_func) (info->stream, ",tsv");
597 break;
598 case 't':
599 (*info->fprintf_func) (info->stream, ",tc");
600 if (GET_FIELD (insn, 20, 20))
601 (*info->fprintf_func) (info->stream, ",tsv");
602 break;
603 case 'B':
604 (*info->fprintf_func) (info->stream, ",db");
605 if (GET_FIELD (insn, 20, 20))
606 (*info->fprintf_func) (info->stream, ",tsv");
607 break;
608 case 'b':
609 (*info->fprintf_func) (info->stream, ",b");
610 if (GET_FIELD (insn, 20, 20))
611 (*info->fprintf_func) (info->stream, ",tsv");
612 break;
613 case 'T':
614 if (GET_FIELD (insn, 25, 25))
615 (*info->fprintf_func) (info->stream, ",tc");
616 break;
1eee34f5
JL
617 case 'S':
618 /* EXTRD/W has a following condition. */
619 if (*(s + 1) == '?')
620 (*info->fprintf_func)
621 (info->stream, "%s", signed_unsigned_names[GET_FIELD
622 (insn, 21, 21)]);
623 else
624 (*info->fprintf_func)
625 (info->stream, "%s ", signed_unsigned_names[GET_FIELD
626 (insn, 21, 21)]);
627 break;
628 case 'h':
629 (*info->fprintf_func)
630 (info->stream, "%s", mix_half_names[GET_FIELD
631 (insn, 17, 17)]);
632 break;
633 case 'H':
634 (*info->fprintf_func)
635 (info->stream, "%s", saturation_names[GET_FIELD
636 (insn, 24, 25)]);
637 break;
638 case '*':
639 (*info->fprintf_func)
640 (info->stream, ",%d%d%d%d ",
641 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
642 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
643 break;
9c1faa82
JL
644
645 case 'q':
646 {
647 int m, a;
648
649 m = GET_FIELD (insn, 28, 28);
650 a = GET_FIELD (insn, 29, 29);
651
652 if (m && !a)
653 fputs_filtered (",ma ", info);
654 else if (m && a)
655 fputs_filtered (",mb ", info);
656 else
657 fputs_filtered (" ", info);
658 break;
659 }
660
661 case 'J':
662 {
663 int opcode = GET_FIELD (insn, 0, 5);
664
665 if (opcode == 0x16 || opcode == 0x1e)
666 {
667 if (GET_FIELD (insn, 29, 29) == 0)
668 fputs_filtered (",ma ", info);
669 else
670 fputs_filtered (",mb ", info);
671 }
672 else
673 fputs_filtered (" ", info);
674 break;
675 }
676
1c170bd8 677 case 'e':
9c1faa82
JL
678 {
679 int opcode = GET_FIELD (insn, 0, 5);
680
681 if (opcode == 0x13 || opcode == 0x1b)
682 {
683 if (GET_FIELD (insn, 18, 18) == 1)
684 fputs_filtered (",mb ", info);
685 else
686 fputs_filtered (",ma ", info);
687 }
688 else if (opcode == 0x17 || opcode == 0x1f)
689 {
690 if (GET_FIELD (insn, 31, 31) == 1)
691 fputs_filtered (",ma ", info);
692 else
693 fputs_filtered (",mb ", info);
694 }
695 else
696 fputs_filtered (" ", info);
697
698 break;
699 }
3281117a 700 }
252b5132 701 break;
feb12992
JL
702
703 /* Handle conditions. */
252b5132 704 case '?':
feb12992
JL
705 {
706 s++;
707 switch (*s)
708 {
709 case 'f':
710 (*info->fprintf_func) (info->stream, "%s ",
711 float_comp_names[GET_FIELD
712 (insn, 27, 31)]);
713 break;
714
715 /* these four conditions are for the set of instructions
716 which distinguish true/false conditions by opcode
717 rather than by the 'f' bit (sigh): comb, comib,
718 addb, addib */
719 case 't':
a349b151 720 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
feb12992
JL
721 info);
722 break;
1c170bd8 723 case 'n':
b333b6c6 724 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
1c170bd8 725 + GET_FIELD (insn, 4, 4) * 8], info);
b333b6c6 726 break;
1c170bd8 727 case 'N':
b333b6c6 728 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
1c170bd8 729 + GET_FIELD (insn, 2, 2) * 8], info);
b333b6c6
JL
730 break;
731 case 'Q':
732 fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
733 info);
734 break;
feb12992
JL
735 case '@':
736 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
737 + GET_FIELD (insn, 4, 4) * 8], info);
738 break;
739 case 's':
740 (*info->fprintf_func) (info->stream, "%s ",
741 compare_cond_names[GET_COND (insn)]);
742 break;
b333b6c6
JL
743 case 'S':
744 (*info->fprintf_func) (info->stream, "%s ",
745 compare_cond_64_names[GET_COND (insn)]);
746 break;
feb12992
JL
747 case 'a':
748 (*info->fprintf_func) (info->stream, "%s ",
749 add_cond_names[GET_COND (insn)]);
750 break;
b333b6c6
JL
751 case 'A':
752 (*info->fprintf_func) (info->stream, "%s ",
753 add_cond_64_names[GET_COND (insn)]);
754 break;
feb12992
JL
755 case 'd':
756 (*info->fprintf_func) (info->stream, "%s",
a349b151 757 add_cond_names[GET_FIELD (insn, 16, 18)]);
feb12992 758 break;
a349b151 759
b333b6c6 760 case 'W':
a349b151 761 (*info->fprintf_func)
b333b6c6 762 (info->stream, "%s",
1c170bd8
JL
763 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
764 GET_FIELD (insn, 4, 4) * 8]);
b333b6c6 765 break;
feb12992
JL
766
767 case 'l':
768 (*info->fprintf_func) (info->stream, "%s ",
769 logical_cond_names[GET_COND (insn)]);
770 break;
b333b6c6
JL
771 case 'L':
772 (*info->fprintf_func) (info->stream, "%s ",
773 logical_cond_64_names[GET_COND (insn)]);
774 break;
feb12992
JL
775 case 'u':
776 (*info->fprintf_func) (info->stream, "%s ",
777 unit_cond_names[GET_COND (insn)]);
778 break;
b333b6c6
JL
779 case 'U':
780 (*info->fprintf_func) (info->stream, "%s ",
781 unit_cond_64_names[GET_COND (insn)]);
782 break;
feb12992
JL
783 case 'y':
784 case 'x':
785 case 'b':
786 (*info->fprintf_func)
787 (info->stream, "%s",
788 shift_cond_names[GET_FIELD (insn, 16, 18)]);
789
790 /* If the next character in args is 'n', it will handle
791 putting out the space. */
792 if (s[1] != 'n')
793 (*info->fprintf_func) (info->stream, " ");
794 break;
b333b6c6 795 case 'X':
e46def7b 796 (*info->fprintf_func) (info->stream, "%s ",
b333b6c6
JL
797 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
798 break;
799 case 'B':
800 (*info->fprintf_func)
801 (info->stream, "%s",
802 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
feb12992 803
b333b6c6
JL
804 /* If the next character in args is 'n', it will handle
805 putting out the space. */
806 if (s[1] != 'n')
807 (*info->fprintf_func) (info->stream, " ");
808 break;
feb12992
JL
809 }
810 break;
811 }
252b5132 812
252b5132
RH
813 case 'V':
814 fput_const (extract_5_store (insn), info);
815 break;
816 case 'r':
817 fput_const (extract_5r_store (insn), info);
818 break;
819 case 'R':
820 fput_const (extract_5R_store (insn), info);
821 break;
3b67cf2b
JL
822 case 'U':
823 fput_const (extract_10U_store (insn), info);
824 break;
61e8273b 825 case 'B':
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.097739 seconds and 4 git commands to generate.