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