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