blob: 49e2231ae62ad8d2c95d5eadf41cabdb8b3d9fae [file] [log] [blame]
Richard Henderson429b31a2016-09-29 10:55:53 -07001/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2 Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003,
3 2005 Free Software Foundation, Inc.
4
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>. */
20
21#include "qemu/osdep.h"
Markus Armbruster3979fca2019-04-17 21:18:04 +020022#include "disas/dis-asm.h"
Richard Henderson429b31a2016-09-29 10:55:53 -070023
24/* HP PA-RISC SOM object file format: definitions internal to BFD.
25 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
26 2003 Free Software Foundation, Inc.
27
28 Contributed by the Center for Software Science at the
29 University of Utah (pa-gdb-bugs@cs.utah.edu).
30
31 This file is part of BFD, the Binary File Descriptor library.
32
33 This program is free software; you can redistribute it and/or modify
34 it under the terms of the GNU General Public License as published by
35 the Free Software Foundation; either version 2 of the License, or
36 (at your option) any later version.
37
38 This program is distributed in the hope that it will be useful,
39 but WITHOUT ANY WARRANTY; without even the implied warranty of
40 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 GNU General Public License for more details.
42
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, see <http://www.gnu.org/licenses/>. */
45
46#ifndef _LIBHPPA_H
47#define _LIBHPPA_H
48
49#define BYTES_IN_WORD 4
50#define PA_PAGESIZE 0x1000
51
52/* The PA instruction set variants. */
53enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
54
55/* HP PA-RISC relocation types */
56
57enum hppa_reloc_field_selector_type
58 {
59 R_HPPA_FSEL = 0x0,
60 R_HPPA_LSSEL = 0x1,
61 R_HPPA_RSSEL = 0x2,
62 R_HPPA_LSEL = 0x3,
63 R_HPPA_RSEL = 0x4,
64 R_HPPA_LDSEL = 0x5,
65 R_HPPA_RDSEL = 0x6,
66 R_HPPA_LRSEL = 0x7,
67 R_HPPA_RRSEL = 0x8,
68 R_HPPA_NSEL = 0x9,
69 R_HPPA_NLSEL = 0xa,
70 R_HPPA_NLRSEL = 0xb,
71 R_HPPA_PSEL = 0xc,
72 R_HPPA_LPSEL = 0xd,
73 R_HPPA_RPSEL = 0xe,
74 R_HPPA_TSEL = 0xf,
75 R_HPPA_LTSEL = 0x10,
76 R_HPPA_RTSEL = 0x11,
77 R_HPPA_LTPSEL = 0x12,
78 R_HPPA_RTPSEL = 0x13
79 };
80
81/* /usr/include/reloc.h defines these to constants. We want to use
82 them in enums, so #undef them before we start using them. We might
83 be able to fix this another way by simply managing not to include
84 /usr/include/reloc.h, but currently GDB picks up these defines
85 somewhere. */
86#undef e_fsel
87#undef e_lssel
88#undef e_rssel
89#undef e_lsel
90#undef e_rsel
91#undef e_ldsel
92#undef e_rdsel
93#undef e_lrsel
94#undef e_rrsel
95#undef e_nsel
96#undef e_nlsel
97#undef e_nlrsel
98#undef e_psel
99#undef e_lpsel
100#undef e_rpsel
101#undef e_tsel
102#undef e_ltsel
103#undef e_rtsel
104#undef e_one
105#undef e_two
106#undef e_pcrel
107#undef e_con
108#undef e_plabel
109#undef e_abs
110
111/* for compatibility */
112enum hppa_reloc_field_selector_type_alt
113 {
114 e_fsel = R_HPPA_FSEL,
115 e_lssel = R_HPPA_LSSEL,
116 e_rssel = R_HPPA_RSSEL,
117 e_lsel = R_HPPA_LSEL,
118 e_rsel = R_HPPA_RSEL,
119 e_ldsel = R_HPPA_LDSEL,
120 e_rdsel = R_HPPA_RDSEL,
121 e_lrsel = R_HPPA_LRSEL,
122 e_rrsel = R_HPPA_RRSEL,
123 e_nsel = R_HPPA_NSEL,
124 e_nlsel = R_HPPA_NLSEL,
125 e_nlrsel = R_HPPA_NLRSEL,
126 e_psel = R_HPPA_PSEL,
127 e_lpsel = R_HPPA_LPSEL,
128 e_rpsel = R_HPPA_RPSEL,
129 e_tsel = R_HPPA_TSEL,
130 e_ltsel = R_HPPA_LTSEL,
131 e_rtsel = R_HPPA_RTSEL,
132 e_ltpsel = R_HPPA_LTPSEL,
133 e_rtpsel = R_HPPA_RTPSEL
134 };
135
136enum hppa_reloc_expr_type
137 {
138 R_HPPA_E_ONE = 0,
139 R_HPPA_E_TWO = 1,
140 R_HPPA_E_PCREL = 2,
141 R_HPPA_E_CON = 3,
142 R_HPPA_E_PLABEL = 7,
143 R_HPPA_E_ABS = 18
144 };
145
146/* for compatibility */
147enum hppa_reloc_expr_type_alt
148 {
149 e_one = R_HPPA_E_ONE,
150 e_two = R_HPPA_E_TWO,
151 e_pcrel = R_HPPA_E_PCREL,
152 e_con = R_HPPA_E_CON,
153 e_plabel = R_HPPA_E_PLABEL,
154 e_abs = R_HPPA_E_ABS
155 };
156
157
158/* Relocations for function calls must be accompanied by parameter
159 relocation bits. These bits describe exactly where the caller has
160 placed the function's arguments and where it expects to find a return
161 value.
162
163 Both ELF and SOM encode this information within the addend field
164 of the call relocation. (Note this could break very badly if one
165 was to make a call like bl foo + 0x12345678).
166
167 The high order 10 bits contain parameter relocation information,
168 the low order 22 bits contain the constant offset. */
169
170#define HPPA_R_ARG_RELOC(a) \
171 (((a) >> 22) & 0x3ff)
172#define HPPA_R_CONSTANT(a) \
173 ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
174#define HPPA_R_ADDEND(r, c) \
175 (((r) << 22) + ((c) & 0x3fffff))
176
177
178/* Some functions to manipulate PA instructions. */
179
180/* Declare the functions with the unused attribute to avoid warnings. */
181static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
182static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
183static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
184static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
185static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
186static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
187static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
188static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
189static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
190static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
191static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
192static inline bfd_signed_vma hppa_field_adjust
193 (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
194 ATTRIBUTE_UNUSED;
195static inline int hppa_rebuild_insn (int, int, int) ATTRIBUTE_UNUSED;
196
197
198/* The *sign_extend functions are used to assemble various bitfields
199 taken from an instruction and return the resulting immediate
200 value. */
201
202static inline int
203sign_extend (int x, int len)
204{
205 int signbit = (1 << (len - 1));
206 int mask = (signbit << 1) - 1;
207 return ((x & mask) ^ signbit) - signbit;
208}
209
210static inline int
211low_sign_extend (int x, int len)
212{
213 return (x >> 1) - ((x & 1) << (len - 1));
214}
215
216
217/* The re_assemble_* functions prepare an immediate value for
218 insertion into an opcode. pa-risc uses all sorts of weird bitfields
219 in the instruction to hold the value. */
220
221static inline int
222sign_unext (int x, int len)
223{
224 int len_ones;
225
226 len_ones = (1 << len) - 1;
227
228 return x & len_ones;
229}
230
231static inline int
232low_sign_unext (int x, int len)
233{
234 int temp;
235 int sign;
236
237 sign = (x >> (len-1)) & 1;
238
239 temp = sign_unext (x, len-1);
240
241 return (temp << 1) | sign;
242}
243
244static inline int
245re_assemble_3 (int as3)
246{
247 return (( (as3 & 4) << (13-2))
248 | ((as3 & 3) << (13+1)));
249}
250
251static inline int
252re_assemble_12 (int as12)
253{
254 return (( (as12 & 0x800) >> 11)
255 | ((as12 & 0x400) >> (10 - 2))
256 | ((as12 & 0x3ff) << (1 + 2)));
257}
258
259static inline int
260re_assemble_14 (int as14)
261{
262 return (( (as14 & 0x1fff) << 1)
263 | ((as14 & 0x2000) >> 13));
264}
265
266static inline int
267re_assemble_16 (int as16)
268{
269 int s, t;
270
271 /* Unusual 16-bit encoding, for wide mode only. */
272 t = (as16 << 1) & 0xffff;
273 s = (as16 & 0x8000);
274 return (t ^ s ^ (s >> 1)) | (s >> 15);
275}
276
277static inline int
278re_assemble_17 (int as17)
279{
280 return (( (as17 & 0x10000) >> 16)
281 | ((as17 & 0x0f800) << (16 - 11))
282 | ((as17 & 0x00400) >> (10 - 2))
283 | ((as17 & 0x003ff) << (1 + 2)));
284}
285
286static inline int
287re_assemble_21 (int as21)
288{
289 return (( (as21 & 0x100000) >> 20)
290 | ((as21 & 0x0ffe00) >> 8)
291 | ((as21 & 0x000180) << 7)
292 | ((as21 & 0x00007c) << 14)
293 | ((as21 & 0x000003) << 12));
294}
295
296static inline int
297re_assemble_22 (int as22)
298{
299 return (( (as22 & 0x200000) >> 21)
300 | ((as22 & 0x1f0000) << (21 - 16))
301 | ((as22 & 0x00f800) << (16 - 11))
302 | ((as22 & 0x000400) >> (10 - 2))
303 | ((as22 & 0x0003ff) << (1 + 2)));
304}
305
306
307/* Handle field selectors for PA instructions.
308 The L and R (and LS, RS etc.) selectors are used in pairs to form a
309 full 32 bit address. eg.
310
311 LDIL L'start,%r1 ; put left part into r1
312 LDW R'start(%r1),%r2 ; add r1 and right part to form address
313
314 This function returns sign extended values in all cases.
315*/
316
317static inline bfd_signed_vma
318hppa_field_adjust (bfd_vma sym_val,
319 bfd_signed_vma addend,
320 enum hppa_reloc_field_selector_type_alt r_field)
321{
322 bfd_signed_vma value;
323
324 value = sym_val + addend;
325 switch (r_field)
326 {
327 case e_fsel:
328 /* F: No change. */
329 break;
330
331 case e_nsel:
332 /* N: null selector. I don't really understand what this is all
333 about, but HP's documentation says "this indicates that zero
334 bits are to be used for the displacement on the instruction.
335 This fixup is used to identify three-instruction sequences to
336 access data (for importing shared library data)." */
337 value = 0;
338 break;
339
340 case e_lsel:
341 case e_nlsel:
342 /* L: Select top 21 bits. */
343 value = value >> 11;
344 break;
345
346 case e_rsel:
347 /* R: Select bottom 11 bits. */
348 value = value & 0x7ff;
349 break;
350
351 case e_lssel:
352 /* LS: Round to nearest multiple of 2048 then select top 21 bits. */
353 value = value + 0x400;
354 value = value >> 11;
355 break;
356
357 case e_rssel:
358 /* RS: Select bottom 11 bits for LS.
359 We need to return a value such that 2048 * LS'x + RS'x == x.
360 ie. RS'x = x - ((x + 0x400) & -0x800)
361 this is just a sign extension from bit 21. */
362 value = ((value & 0x7ff) ^ 0x400) - 0x400;
363 break;
364
365 case e_ldsel:
366 /* LD: Round to next multiple of 2048 then select top 21 bits.
367 Yes, if we are already on a multiple of 2048, we go up to the
368 next one. RD in this case will be -2048. */
369 value = value + 0x800;
370 value = value >> 11;
371 break;
372
373 case e_rdsel:
374 /* RD: Set bits 0-20 to one. */
375 value = value | -0x800;
376 break;
377
378 case e_lrsel:
379 case e_nlrsel:
380 /* LR: L with rounding of the addend to nearest 8k. */
381 value = sym_val + ((addend + 0x1000) & -0x2000);
382 value = value >> 11;
383 break;
384
385 case e_rrsel:
386 /* RR: R with rounding of the addend to nearest 8k.
387 We need to return a value such that 2048 * LR'x + RR'x == x
388 ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
389 . = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
390 . = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000) */
391 value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
392 break;
393
394 default:
395 abort ();
396 }
397 return value;
398}
399
400/* PA-RISC OPCODES */
401#define get_opcode(insn) (((insn) >> 26) & 0x3f)
402
403enum hppa_opcode_type
404{
405 /* None of the opcodes in the first group generate relocs, so we
406 aren't too concerned about them. */
407 OP_SYSOP = 0x00,
408 OP_MEMMNG = 0x01,
409 OP_ALU = 0x02,
410 OP_NDXMEM = 0x03,
411 OP_SPOP = 0x04,
412 OP_DIAG = 0x05,
413 OP_FMPYADD = 0x06,
414 OP_UNDEF07 = 0x07,
415 OP_COPRW = 0x09,
416 OP_COPRDW = 0x0b,
417 OP_COPR = 0x0c,
418 OP_FLOAT = 0x0e,
419 OP_PRDSPEC = 0x0f,
420 OP_UNDEF15 = 0x15,
421 OP_UNDEF1d = 0x1d,
422 OP_FMPYSUB = 0x26,
423 OP_FPFUSED = 0x2e,
424 OP_SHEXDP0 = 0x34,
425 OP_SHEXDP1 = 0x35,
426 OP_SHEXDP2 = 0x36,
427 OP_UNDEF37 = 0x37,
428 OP_SHEXDP3 = 0x3c,
429 OP_SHEXDP4 = 0x3d,
430 OP_MULTMED = 0x3e,
431 OP_UNDEF3f = 0x3f,
432
433 OP_LDIL = 0x08,
434 OP_ADDIL = 0x0a,
435
436 OP_LDO = 0x0d,
437 OP_LDB = 0x10,
438 OP_LDH = 0x11,
439 OP_LDW = 0x12,
440 OP_LDWM = 0x13,
441 OP_STB = 0x18,
442 OP_STH = 0x19,
443 OP_STW = 0x1a,
444 OP_STWM = 0x1b,
445
446 OP_LDD = 0x14,
447 OP_STD = 0x1c,
448
449 OP_FLDW = 0x16,
450 OP_LDWL = 0x17,
451 OP_FSTW = 0x1e,
452 OP_STWL = 0x1f,
453
454 OP_COMBT = 0x20,
455 OP_COMIBT = 0x21,
456 OP_COMBF = 0x22,
457 OP_COMIBF = 0x23,
458 OP_CMPBDT = 0x27,
459 OP_ADDBT = 0x28,
460 OP_ADDIBT = 0x29,
461 OP_ADDBF = 0x2a,
462 OP_ADDIBF = 0x2b,
463 OP_CMPBDF = 0x2f,
464 OP_BVB = 0x30,
465 OP_BB = 0x31,
466 OP_MOVB = 0x32,
467 OP_MOVIB = 0x33,
468 OP_CMPIBD = 0x3b,
469
470 OP_COMICLR = 0x24,
471 OP_SUBI = 0x25,
472 OP_ADDIT = 0x2c,
473 OP_ADDI = 0x2d,
474
475 OP_BE = 0x38,
476 OP_BLE = 0x39,
477 OP_BL = 0x3a
478};
479
480
481/* Insert VALUE into INSN using R_FORMAT to determine exactly what
482 bits to change. */
483
484static inline int
485hppa_rebuild_insn (int insn, int value, int r_format)
486{
487 switch (r_format)
488 {
489 case 11:
490 return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
491
492 case 12:
493 return (insn & ~ 0x1ffd) | re_assemble_12 (value);
494
495
496 case 10:
497 return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
498
499 case -11:
500 return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
501
502 case 14:
503 return (insn & ~ 0x3fff) | re_assemble_14 (value);
504
505
506 case -10:
507 return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
508
509 case -16:
510 return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
511
512 case 16:
513 return (insn & ~ 0xffff) | re_assemble_16 (value);
514
515
516 case 17:
517 return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
518
519 case 21:
520 return (insn & ~ 0x1fffff) | re_assemble_21 (value);
521
522 case 22:
523 return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
524
525 case 32:
526 return value;
527
528 default:
529 abort ();
530 }
531 return insn;
532}
533
534#endif /* _LIBHPPA_H */
535/* Table of opcodes for the PA-RISC.
536 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
537 2001, 2002, 2003, 2004, 2005
538 Free Software Foundation, Inc.
539
540 Contributed by the Center for Software Science at the
541 University of Utah (pa-gdb-bugs@cs.utah.edu).
542
543This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
544
545GAS/GDB is free software; you can redistribute it and/or modify
546it under the terms of the GNU General Public License as published by
547the Free Software Foundation; either version 1, or (at your option)
548any later version.
549
550GAS/GDB is distributed in the hope that it will be useful,
551but WITHOUT ANY WARRANTY; without even the implied warranty of
552MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
553GNU General Public License for more details.
554
555You should have received a copy of the GNU General Public License
556along with GAS or GDB; see the file COPYING.
557If not, see <http://www.gnu.org/licenses/>. */
558
559#if !defined(__STDC__) && !defined(const)
560#define const
561#endif
562
563/*
564 * Structure of an opcode table entry.
565 */
566
567/* There are two kinds of delay slot nullification: normal which is
568 * controlled by the nullification bit, and conditional, which depends
569 * on the direction of the branch and its success or failure.
570 *
571 * NONE is unfortunately #defined in the hiux system include files.
572 * #undef it away.
573 */
574#undef NONE
575struct pa_opcode
576{
577 const char *name;
578 unsigned long int match; /* Bits that must be set... */
579 unsigned long int mask; /* ... in these bits. */
580 const char *args;
581 enum pa_arch arch;
582 char flags;
583};
584
585/* Enables strict matching. Opcodes with match errors are skipped
586 when this bit is set. */
587#define FLAG_STRICT 0x1
588
589/*
590 All hppa opcodes are 32 bits.
591
592 The match component is a mask saying which bits must match a
593 particular opcode in order for an instruction to be an instance
594 of that opcode.
595
596 The args component is a string containing one character for each operand of
597 the instruction. Characters used as a prefix allow any second character to
598 be used without conflicting with the main operand characters.
599
600 Bit positions in this description follow HP usage of lsb = 31,
601 "at" is lsb of field.
602
603 In the args field, the following characters must match exactly:
604
605 '+,() '
606
607 In the args field, the following characters are unused:
608
609 ' " - / 34 6789:; '
610 '@ C M [\] '
611 '` e g } '
612
613 Here are all the characters:
614
615 ' !"#$%&'()*+-,./0123456789:;<=>?'
616 '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'
617 '`abcdefghijklmnopqrstuvwxyz{|}~ '
618
619Kinds of operands:
620 x integer register field at 15.
621 b integer register field at 10.
622 t integer register field at 31.
623 a integer register field at 10 and 15 (for PERMH)
624 5 5 bit immediate at 15.
625 s 2 bit space specifier at 17.
626 S 3 bit space specifier at 18.
627 V 5 bit immediate value at 31
628 i 11 bit immediate value at 31
629 j 14 bit immediate value at 31
630 k 21 bit immediate value at 31
631 l 16 bit immediate value at 31 (wide mode only, unusual encoding).
632 n nullification for branch instructions
633 N nullification for spop and copr instructions
634 w 12 bit branch displacement
635 W 17 bit branch displacement (PC relative)
636 X 22 bit branch displacement (PC relative)
637 z 17 bit branch displacement (just a number, not an address)
638
639Also these:
640
641 . 2 bit shift amount at 25
642 * 4 bit shift amount at 25
643 p 5 bit shift count at 26 (to support the SHD instruction) encoded as
644 31-p
645 ~ 6 bit shift count at 20,22:26 encoded as 63-~.
646 P 5 bit bit position at 26
647 q 6 bit bit position at 20,22:26
648 T 5 bit field length at 31 (encoded as 32-T)
649 % 6 bit field length at 23,27:31 (variable extract/deposit)
650 | 6 bit field length at 19,27:31 (fixed extract/deposit)
651 A 13 bit immediate at 18 (to support the BREAK instruction)
652 ^ like b, but describes a control register
653 ! sar (cr11) register
654 D 26 bit immediate at 31 (to support the DIAG instruction)
655 $ 9 bit immediate at 28 (to support POPBTS)
656
657 v 3 bit Special Function Unit identifier at 25
658 O 20 bit Special Function Unit operation split between 15 bits at 20
659 and 5 bits at 31
660 o 15 bit Special Function Unit operation at 20
661 2 22 bit Special Function Unit operation split between 17 bits at 20
662 and 5 bits at 31
663 1 15 bit Special Function Unit operation split between 10 bits at 20
664 and 5 bits at 31
665 0 10 bit Special Function Unit operation split between 5 bits at 20
666 and 5 bits at 31
667 u 3 bit coprocessor unit identifier at 25
668 F Source Floating Point Operand Format Completer encoded 2 bits at 20
669 I Source Floating Point Operand Format Completer encoded 1 bits at 20
670 (for 0xe format FP instructions)
671 G Destination Floating Point Operand Format Completer encoded 2 bits at 18
672 H Floating Point Operand Format at 26 for 'fmpyadd' and 'fmpysub'
673 (very similar to 'F')
674
675 r 5 bit immediate value at 31 (for the break instruction)
676 (very similar to V above, except the value is unsigned instead of
677 low_sign_ext)
678 R 5 bit immediate value at 15 (for the ssm, rsm, probei instructions)
679 (same as r above, except the value is in a different location)
680 U 10 bit immediate value at 15 (for SSM, RSM on pa2.0)
681 Q 5 bit immediate value at 10 (a bit position specified in
682 the bb instruction. It's the same as r above, except the
683 value is in a different location)
684 B 5 bit immediate value at 10 (a bit position specified in
685 the bb instruction. Similar to Q, but 64 bit handling is
686 different.
687 Z %r1 -- implicit target of addil instruction.
688 L ,%r2 completer for new syntax branch
689 { Source format completer for fcnv
690 _ Destination format completer for fcnv
691 h cbit for fcmp
692 = gfx tests for ftest
693 d 14 bit offset for single precision FP long load/store.
694 # 14 bit offset for double precision FP load long/store.
695 J Yet another 14 bit offset for load/store with ma,mb completers.
696 K Yet another 14 bit offset for load/store with ma,mb completers.
697 y 16 bit offset for word aligned load/store (PA2.0 wide).
698 & 16 bit offset for dword aligned load/store (PA2.0 wide).
699 < 16 bit offset for load/store with ma,mb completers (PA2.0 wide).
700 > 16 bit offset for load/store with ma,mb completers (PA2.0 wide).
701 Y %sr0,%r31 -- implicit target of be,l instruction.
702 @ implicit immediate value of 0
703
704Completer operands all have 'c' as the prefix:
705
706 cx indexed load and store completer.
707 cX indexed load and store completer. Like cx, but emits a space
708 after in disassembler.
709 cm short load and store completer.
710 cM short load and store completer. Like cm, but emits a space
711 after in disassembler.
712 cq long load and store completer (like cm, but inserted into a
713 different location in the target instruction).
714 cs store bytes short completer.
715 cA store bytes short completer. Like cs, but emits a space
716 after in disassembler.
717 ce long load/store completer for LDW/STW with a different encoding
718 than the others
719 cc load cache control hint
720 cd load and clear cache control hint
721 cC store cache control hint
722 co ordered access
723
724 cp branch link and push completer
725 cP branch pop completer
726 cl branch link completer
727 cg branch gate completer
728
729 cw read/write completer for PROBE
730 cW wide completer for MFCTL
731 cL local processor completer for cache control
732 cZ System Control Completer (to support LPA, LHA, etc.)
733
734 ci correction completer for DCOR
735 ca add completer
736 cy 32 bit add carry completer
737 cY 64 bit add carry completer
738 cv signed overflow trap completer
739 ct trap on condition completer for ADDI, SUB
740 cT trap on condition completer for UADDCM
741 cb 32 bit borrow completer for SUB
742 cB 64 bit borrow completer for SUB
743
744 ch left/right half completer
745 cH signed/unsigned saturation completer
746 cS signed/unsigned completer at 21
747 cz zero/sign extension completer.
748 c* permutation completer
749
750Condition operands all have '?' as the prefix:
751
752 ?f Floating point compare conditions (encoded as 5 bits at 31)
753
754 ?a add conditions
755 ?A 64 bit add conditions
756 ?@ add branch conditions followed by nullify
757 ?d non-negated add branch conditions
758 ?D negated add branch conditions
759 ?w wide mode non-negated add branch conditions
760 ?W wide mode negated add branch conditions
761
762 ?s compare/subtract conditions
763 ?S 64 bit compare/subtract conditions
764 ?t non-negated compare and branch conditions
765 ?n 32 bit compare and branch conditions followed by nullify
766 ?N 64 bit compare and branch conditions followed by nullify
767 ?Q 64 bit compare and branch conditions for CMPIB instruction
768
769 ?l logical conditions
770 ?L 64 bit logical conditions
771
772 ?b branch on bit conditions
773 ?B 64 bit branch on bit conditions
774
775 ?x shift/extract/deposit conditions
776 ?X 64 bit shift/extract/deposit conditions
777 ?y shift/extract/deposit conditions followed by nullify for conditional
778 branches
779
780 ?u unit conditions
781 ?U 64 bit unit conditions
782
783Floating point registers all have 'f' as a prefix:
784
785 ft target register at 31
786 fT target register with L/R halves at 31
787 fa operand 1 register at 10
788 fA operand 1 register with L/R halves at 10
789 fX Same as fA, except prints a space before register during disasm
790 fb operand 2 register at 15
791 fB operand 2 register with L/R halves at 15
792 fC operand 3 register with L/R halves at 16:18,21:23
793 fe Like fT, but encoding is different.
794 fE Same as fe, except prints a space before register during disasm.
795 fx target register at 15 (only for PA 2.0 long format FLDD/FSTD).
796
797Float registers for fmpyadd and fmpysub:
798
799 fi mult operand 1 register at 10
800 fj mult operand 2 register at 15
801 fk mult target register at 20
802 fl add/sub operand register at 25
803 fm add/sub target register at 31
804
805*/
806
807
808#if 0
809/* List of characters not to put a space after. Note that
810 "," is included, as the "spopN" operations use literal
811 commas in their completer sections. */
812static const char *const completer_chars = ",CcY<>?!@+&U~FfGHINnOoZMadu|/=0123%e$m}";
813#endif
814
815/* The order of the opcodes in this table is significant:
816
817 * The assembler requires that all instances of the same mnemonic be
818 consecutive. If they aren't, the assembler will bomb at runtime.
819
820 * Immediate fields use pa_get_absolute_expression to parse the
821 string. It will generate a "bad expression" error if passed
822 a register name. Thus, register index variants of an opcode
823 need to precede immediate variants.
824
825 * The disassembler does not care about the order of the opcodes
826 except in cases where implicit addressing is used.
827
828 Here are the rules for ordering the opcodes of a mnemonic:
829
830 1) Opcodes with FLAG_STRICT should precede opcodes without
831 FLAG_STRICT.
832
833 2) Opcodes with FLAG_STRICT should be ordered as follows:
834 register index opcodes, short immediate opcodes, and finally
835 long immediate opcodes. When both pa10 and pa11 variants
836 of the same opcode are available, the pa10 opcode should
837 come first for correct architectural promotion.
838
839 3) When implicit addressing is available for an opcode, the
840 implicit opcode should precede the explicit opcode.
841
842 4) Opcodes without FLAG_STRICT should be ordered as follows:
843 register index opcodes, long immediate opcodes, and finally
844 short immediate opcodes. */
845
846static const struct pa_opcode pa_opcodes[] =
847{
848
849/* Pseudo-instructions. */
850
851{ "ldi", 0x34000000, 0xffe00000, "l,x", pa20w, 0},/* ldo val(r0),r */
852{ "ldi", 0x34000000, 0xffe0c000, "j,x", pa10, 0},/* ldo val(r0),r */
853
854{ "cmpib", 0xec000000, 0xfc000000, "?Qn5,b,w", pa20, FLAG_STRICT},
855{ "cmpib", 0x84000000, 0xf4000000, "?nn5,b,w", pa10, FLAG_STRICT},
856{ "comib", 0x84000000, 0xfc000000, "?nn5,b,w", pa10, 0}, /* comib{tf}*/
857/* This entry is for the disassembler only. It will never be used by
858 assembler. */
859{ "comib", 0x8c000000, 0xfc000000, "?nn5,b,w", pa10, 0}, /* comib{tf}*/
860{ "cmpb", 0x9c000000, 0xdc000000, "?Nnx,b,w", pa20, FLAG_STRICT},
861{ "cmpb", 0x80000000, 0xf4000000, "?nnx,b,w", pa10, FLAG_STRICT},
862{ "comb", 0x80000000, 0xfc000000, "?nnx,b,w", pa10, 0}, /* comb{tf} */
863/* This entry is for the disassembler only. It will never be used by
864 assembler. */
865{ "comb", 0x88000000, 0xfc000000, "?nnx,b,w", pa10, 0}, /* comb{tf} */
866{ "addb", 0xa0000000, 0xf4000000, "?Wnx,b,w", pa20w, FLAG_STRICT},
867{ "addb", 0xa0000000, 0xfc000000, "?@nx,b,w", pa10, 0}, /* addb{tf} */
868/* This entry is for the disassembler only. It will never be used by
869 assembler. */
870{ "addb", 0xa8000000, 0xfc000000, "?@nx,b,w", pa10, 0},
871{ "addib", 0xa4000000, 0xf4000000, "?Wn5,b,w", pa20w, FLAG_STRICT},
872{ "addib", 0xa4000000, 0xfc000000, "?@n5,b,w", pa10, 0}, /* addib{tf}*/
873/* This entry is for the disassembler only. It will never be used by
874 assembler. */
875{ "addib", 0xac000000, 0xfc000000, "?@n5,b,w", pa10, 0}, /* addib{tf}*/
876{ "nop", 0x08000240, 0xffffffff, "", pa10, 0}, /* or 0,0,0 */
877{ "copy", 0x08000240, 0xffe0ffe0, "x,t", pa10, 0}, /* or r,0,t */
878{ "mtsar", 0x01601840, 0xffe0ffff, "x", pa10, 0}, /* mtctl r,cr11 */
879
880/* Loads and Stores for integer registers. */
881
882{ "ldd", 0x0c0000c0, 0xfc00d3c0, "cxccx(b),t", pa20, FLAG_STRICT},
883{ "ldd", 0x0c0000c0, 0xfc0013c0, "cxccx(s,b),t", pa20, FLAG_STRICT},
884{ "ldd", 0x0c0010e0, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
885{ "ldd", 0x0c0010e0, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
886{ "ldd", 0x0c0010c0, 0xfc00d3c0, "cmcc5(b),t", pa20, FLAG_STRICT},
887{ "ldd", 0x0c0010c0, 0xfc0013c0, "cmcc5(s,b),t", pa20, FLAG_STRICT},
888{ "ldd", 0x50000000, 0xfc000002, "cq&(b),x", pa20w, FLAG_STRICT},
889{ "ldd", 0x50000000, 0xfc00c002, "cq#(b),x", pa20, FLAG_STRICT},
890{ "ldd", 0x50000000, 0xfc000002, "cq#(s,b),x", pa20, FLAG_STRICT},
891{ "ldw", 0x0c000080, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
892{ "ldw", 0x0c000080, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
893{ "ldw", 0x0c000080, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
894{ "ldw", 0x0c000080, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
895{ "ldw", 0x0c0010a0, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
896{ "ldw", 0x0c0010a0, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
897{ "ldw", 0x0c001080, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
898{ "ldw", 0x0c001080, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
899{ "ldw", 0x0c001080, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
900{ "ldw", 0x0c001080, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
901{ "ldw", 0x4c000000, 0xfc000000, "ce<(b),x", pa20w, FLAG_STRICT},
902{ "ldw", 0x5c000004, 0xfc000006, "ce>(b),x", pa20w, FLAG_STRICT},
903{ "ldw", 0x48000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
904{ "ldw", 0x5c000004, 0xfc00c006, "ceK(b),x", pa20, FLAG_STRICT},
905{ "ldw", 0x5c000004, 0xfc000006, "ceK(s,b),x", pa20, FLAG_STRICT},
906{ "ldw", 0x4c000000, 0xfc00c000, "ceJ(b),x", pa10, FLAG_STRICT},
907{ "ldw", 0x4c000000, 0xfc000000, "ceJ(s,b),x", pa10, FLAG_STRICT},
908{ "ldw", 0x48000000, 0xfc00c000, "j(b),x", pa10, 0},
909{ "ldw", 0x48000000, 0xfc000000, "j(s,b),x", pa10, 0},
910{ "ldh", 0x0c000040, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
911{ "ldh", 0x0c000040, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
912{ "ldh", 0x0c000040, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
913{ "ldh", 0x0c000040, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
914{ "ldh", 0x0c001060, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
915{ "ldh", 0x0c001060, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
916{ "ldh", 0x0c001040, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
917{ "ldh", 0x0c001040, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
918{ "ldh", 0x0c001040, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
919{ "ldh", 0x0c001040, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
920{ "ldh", 0x44000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
921{ "ldh", 0x44000000, 0xfc00c000, "j(b),x", pa10, 0},
922{ "ldh", 0x44000000, 0xfc000000, "j(s,b),x", pa10, 0},
923{ "ldb", 0x0c000000, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
924{ "ldb", 0x0c000000, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
925{ "ldb", 0x0c000000, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
926{ "ldb", 0x0c000000, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
927{ "ldb", 0x0c001020, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
928{ "ldb", 0x0c001020, 0xfc1f33e0, "cocc@(s,b),t", pa20, FLAG_STRICT},
929{ "ldb", 0x0c001000, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
930{ "ldb", 0x0c001000, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
931{ "ldb", 0x0c001000, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
932{ "ldb", 0x0c001000, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
933{ "ldb", 0x40000000, 0xfc000000, "l(b),x", pa20w, FLAG_STRICT},
934{ "ldb", 0x40000000, 0xfc00c000, "j(b),x", pa10, 0},
935{ "ldb", 0x40000000, 0xfc000000, "j(s,b),x", pa10, 0},
936{ "std", 0x0c0012e0, 0xfc00f3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
937{ "std", 0x0c0012e0, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
938{ "std", 0x0c0012c0, 0xfc00d3c0, "cmcCx,V(b)", pa20, FLAG_STRICT},
939{ "std", 0x0c0012c0, 0xfc0013c0, "cmcCx,V(s,b)", pa20, FLAG_STRICT},
940{ "std", 0x70000000, 0xfc000002, "cqx,&(b)", pa20w, FLAG_STRICT},
941{ "std", 0x70000000, 0xfc00c002, "cqx,#(b)", pa20, FLAG_STRICT},
942{ "std", 0x70000000, 0xfc000002, "cqx,#(s,b)", pa20, FLAG_STRICT},
943{ "stw", 0x0c0012a0, 0xfc00f3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
944{ "stw", 0x0c0012a0, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
945{ "stw", 0x0c001280, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
946{ "stw", 0x0c001280, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
947{ "stw", 0x0c001280, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
948{ "stw", 0x0c001280, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
949{ "stw", 0x6c000000, 0xfc000000, "cex,<(b)", pa20w, FLAG_STRICT},
950{ "stw", 0x7c000004, 0xfc000006, "cex,>(b)", pa20w, FLAG_STRICT},
951{ "stw", 0x68000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
952{ "stw", 0x7c000004, 0xfc00c006, "cex,K(b)", pa20, FLAG_STRICT},
953{ "stw", 0x7c000004, 0xfc000006, "cex,K(s,b)", pa20, FLAG_STRICT},
954{ "stw", 0x6c000000, 0xfc00c000, "cex,J(b)", pa10, FLAG_STRICT},
955{ "stw", 0x6c000000, 0xfc000000, "cex,J(s,b)", pa10, FLAG_STRICT},
956{ "stw", 0x68000000, 0xfc00c000, "x,j(b)", pa10, 0},
957{ "stw", 0x68000000, 0xfc000000, "x,j(s,b)", pa10, 0},
958{ "sth", 0x0c001260, 0xfc00f3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
959{ "sth", 0x0c001260, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
960{ "sth", 0x0c001240, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
961{ "sth", 0x0c001240, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
962{ "sth", 0x0c001240, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
963{ "sth", 0x0c001240, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
964{ "sth", 0x64000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
965{ "sth", 0x64000000, 0xfc00c000, "x,j(b)", pa10, 0},
966{ "sth", 0x64000000, 0xfc000000, "x,j(s,b)", pa10, 0},
967{ "stb", 0x0c001220, 0xfc00f3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
968{ "stb", 0x0c001220, 0xfc0033ff, "cocCx,@(s,b)", pa20, FLAG_STRICT},
969{ "stb", 0x0c001200, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
970{ "stb", 0x0c001200, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
971{ "stb", 0x0c001200, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
972{ "stb", 0x0c001200, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
973{ "stb", 0x60000000, 0xfc000000, "x,l(b)", pa20w, FLAG_STRICT},
974{ "stb", 0x60000000, 0xfc00c000, "x,j(b)", pa10, 0},
975{ "stb", 0x60000000, 0xfc000000, "x,j(s,b)", pa10, 0},
976{ "ldwm", 0x4c000000, 0xfc00c000, "j(b),x", pa10, 0},
977{ "ldwm", 0x4c000000, 0xfc000000, "j(s,b),x", pa10, 0},
978{ "stwm", 0x6c000000, 0xfc00c000, "x,j(b)", pa10, 0},
979{ "stwm", 0x6c000000, 0xfc000000, "x,j(s,b)", pa10, 0},
980{ "ldwx", 0x0c000080, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
981{ "ldwx", 0x0c000080, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
982{ "ldwx", 0x0c000080, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
983{ "ldwx", 0x0c000080, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
984{ "ldwx", 0x0c000080, 0xfc00dfc0, "cXx(b),t", pa10, 0},
985{ "ldwx", 0x0c000080, 0xfc001fc0, "cXx(s,b),t", pa10, 0},
986{ "ldhx", 0x0c000040, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
987{ "ldhx", 0x0c000040, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
988{ "ldhx", 0x0c000040, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
989{ "ldhx", 0x0c000040, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
990{ "ldhx", 0x0c000040, 0xfc00dfc0, "cXx(b),t", pa10, 0},
991{ "ldhx", 0x0c000040, 0xfc001fc0, "cXx(s,b),t", pa10, 0},
992{ "ldbx", 0x0c000000, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
993{ "ldbx", 0x0c000000, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
994{ "ldbx", 0x0c000000, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
995{ "ldbx", 0x0c000000, 0xfc0013c0, "cxccx(s,b),t", pa11, FLAG_STRICT},
996{ "ldbx", 0x0c000000, 0xfc00dfc0, "cXx(b),t", pa10, 0},
997{ "ldbx", 0x0c000000, 0xfc001fc0, "cXx(s,b),t", pa10, 0},
998{ "ldwa", 0x0c000180, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
999{ "ldwa", 0x0c000180, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
1000{ "ldwa", 0x0c0011a0, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
1001{ "ldwa", 0x0c001180, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1002{ "ldwa", 0x0c001180, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
1003{ "ldcw", 0x0c0001c0, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
1004{ "ldcw", 0x0c0001c0, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
1005{ "ldcw", 0x0c0001c0, 0xfc00d3c0, "cxcdx(b),t", pa11, FLAG_STRICT},
1006{ "ldcw", 0x0c0001c0, 0xfc0013c0, "cxcdx(s,b),t", pa11, FLAG_STRICT},
1007{ "ldcw", 0x0c0011c0, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1008{ "ldcw", 0x0c0011c0, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
1009{ "ldcw", 0x0c0011c0, 0xfc00d3c0, "cmcd5(b),t", pa11, FLAG_STRICT},
1010{ "ldcw", 0x0c0011c0, 0xfc0013c0, "cmcd5(s,b),t", pa11, FLAG_STRICT},
1011{ "stwa", 0x0c0013a0, 0xfc00d3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
1012{ "stwa", 0x0c001380, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
1013{ "stwa", 0x0c001380, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
1014{ "stby", 0x0c001300, 0xfc00dfc0, "cAx,V(b)", pa10, FLAG_STRICT},
1015{ "stby", 0x0c001300, 0xfc001fc0, "cAx,V(s,b)", pa10, FLAG_STRICT},
1016{ "stby", 0x0c001300, 0xfc00d3c0, "cscCx,V(b)", pa11, FLAG_STRICT},
1017{ "stby", 0x0c001300, 0xfc0013c0, "cscCx,V(s,b)", pa11, FLAG_STRICT},
1018{ "ldda", 0x0c000100, 0xfc00d3c0, "cxccx(b),t", pa20, FLAG_STRICT},
1019{ "ldda", 0x0c001120, 0xfc1ff3e0, "cocc@(b),t", pa20, FLAG_STRICT},
1020{ "ldda", 0x0c001100, 0xfc00d3c0, "cmcc5(b),t", pa20, FLAG_STRICT},
1021{ "ldcd", 0x0c000140, 0xfc00d3c0, "cxcdx(b),t", pa20, FLAG_STRICT},
1022{ "ldcd", 0x0c000140, 0xfc0013c0, "cxcdx(s,b),t", pa20, FLAG_STRICT},
1023{ "ldcd", 0x0c001140, 0xfc00d3c0, "cmcd5(b),t", pa20, FLAG_STRICT},
1024{ "ldcd", 0x0c001140, 0xfc0013c0, "cmcd5(s,b),t", pa20, FLAG_STRICT},
1025{ "stda", 0x0c0013e0, 0xfc00f3ff, "cocCx,@(b)", pa20, FLAG_STRICT},
1026{ "stda", 0x0c0013c0, 0xfc00d3c0, "cmcCx,V(b)", pa20, FLAG_STRICT},
1027{ "ldwax", 0x0c000180, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
1028{ "ldwax", 0x0c000180, 0xfc00d3c0, "cxccx(b),t", pa11, FLAG_STRICT},
1029{ "ldwax", 0x0c000180, 0xfc00dfc0, "cXx(b),t", pa10, 0},
1030{ "ldcwx", 0x0c0001c0, 0xfc00dfc0, "cXx(b),t", pa10, FLAG_STRICT},
1031{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cXx(s,b),t", pa10, FLAG_STRICT},
1032{ "ldcwx", 0x0c0001c0, 0xfc00d3c0, "cxcdx(b),t", pa11, FLAG_STRICT},
1033{ "ldcwx", 0x0c0001c0, 0xfc0013c0, "cxcdx(s,b),t", pa11, FLAG_STRICT},
1034{ "ldcwx", 0x0c0001c0, 0xfc00dfc0, "cXx(b),t", pa10, 0},
1035{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cXx(s,b),t", pa10, 0},
1036{ "ldws", 0x0c001080, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1037{ "ldws", 0x0c001080, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
1038{ "ldws", 0x0c001080, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
1039{ "ldws", 0x0c001080, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
1040{ "ldws", 0x0c001080, 0xfc00dfc0, "cM5(b),t", pa10, 0},
1041{ "ldws", 0x0c001080, 0xfc001fc0, "cM5(s,b),t", pa10, 0},
1042{ "ldhs", 0x0c001040, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1043{ "ldhs", 0x0c001040, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
1044{ "ldhs", 0x0c001040, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
1045{ "ldhs", 0x0c001040, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
1046{ "ldhs", 0x0c001040, 0xfc00dfc0, "cM5(b),t", pa10, 0},
1047{ "ldhs", 0x0c001040, 0xfc001fc0, "cM5(s,b),t", pa10, 0},
1048{ "ldbs", 0x0c001000, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1049{ "ldbs", 0x0c001000, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
1050{ "ldbs", 0x0c001000, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
1051{ "ldbs", 0x0c001000, 0xfc0013c0, "cmcc5(s,b),t", pa11, FLAG_STRICT},
1052{ "ldbs", 0x0c001000, 0xfc00dfc0, "cM5(b),t", pa10, 0},
1053{ "ldbs", 0x0c001000, 0xfc001fc0, "cM5(s,b),t", pa10, 0},
1054{ "ldwas", 0x0c001180, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1055{ "ldwas", 0x0c001180, 0xfc00d3c0, "cmcc5(b),t", pa11, FLAG_STRICT},
1056{ "ldwas", 0x0c001180, 0xfc00dfc0, "cM5(b),t", pa10, 0},
1057{ "ldcws", 0x0c0011c0, 0xfc00dfc0, "cM5(b),t", pa10, FLAG_STRICT},
1058{ "ldcws", 0x0c0011c0, 0xfc001fc0, "cM5(s,b),t", pa10, FLAG_STRICT},
1059{ "ldcws", 0x0c0011c0, 0xfc00d3c0, "cmcd5(b),t", pa11, FLAG_STRICT},
1060{ "ldcws", 0x0c0011c0, 0xfc0013c0, "cmcd5(s,b),t", pa11, FLAG_STRICT},
1061{ "ldcws", 0x0c0011c0, 0xfc00dfc0, "cM5(b),t", pa10, 0},
1062{ "ldcws", 0x0c0011c0, 0xfc001fc0, "cM5(s,b),t", pa10, 0},
1063{ "stws", 0x0c001280, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
1064{ "stws", 0x0c001280, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
1065{ "stws", 0x0c001280, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
1066{ "stws", 0x0c001280, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
1067{ "stws", 0x0c001280, 0xfc00dfc0, "cMx,V(b)", pa10, 0},
1068{ "stws", 0x0c001280, 0xfc001fc0, "cMx,V(s,b)", pa10, 0},
1069{ "sths", 0x0c001240, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
1070{ "sths", 0x0c001240, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
1071{ "sths", 0x0c001240, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
1072{ "sths", 0x0c001240, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
1073{ "sths", 0x0c001240, 0xfc00dfc0, "cMx,V(b)", pa10, 0},
1074{ "sths", 0x0c001240, 0xfc001fc0, "cMx,V(s,b)", pa10, 0},
1075{ "stbs", 0x0c001200, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
1076{ "stbs", 0x0c001200, 0xfc001fc0, "cMx,V(s,b)", pa10, FLAG_STRICT},
1077{ "stbs", 0x0c001200, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
1078{ "stbs", 0x0c001200, 0xfc0013c0, "cmcCx,V(s,b)", pa11, FLAG_STRICT},
1079{ "stbs", 0x0c001200, 0xfc00dfc0, "cMx,V(b)", pa10, 0},
1080{ "stbs", 0x0c001200, 0xfc001fc0, "cMx,V(s,b)", pa10, 0},
1081{ "stwas", 0x0c001380, 0xfc00dfc0, "cMx,V(b)", pa10, FLAG_STRICT},
1082{ "stwas", 0x0c001380, 0xfc00d3c0, "cmcCx,V(b)", pa11, FLAG_STRICT},
1083{ "stwas", 0x0c001380, 0xfc00dfc0, "cMx,V(b)", pa10, 0},
1084{ "stdby", 0x0c001340, 0xfc00d3c0, "cscCx,V(b)", pa20, FLAG_STRICT},
1085{ "stdby", 0x0c001340, 0xfc0013c0, "cscCx,V(s,b)", pa20, FLAG_STRICT},
1086{ "stbys", 0x0c001300, 0xfc00dfc0, "cAx,V(b)", pa10, FLAG_STRICT},
1087{ "stbys", 0x0c001300, 0xfc001fc0, "cAx,V(s,b)", pa10, FLAG_STRICT},
1088{ "stbys", 0x0c001300, 0xfc00d3c0, "cscCx,V(b)", pa11, FLAG_STRICT},
1089{ "stbys", 0x0c001300, 0xfc0013c0, "cscCx,V(s,b)", pa11, FLAG_STRICT},
1090{ "stbys", 0x0c001300, 0xfc00dfc0, "cAx,V(b)", pa10, 0},
1091{ "stbys", 0x0c001300, 0xfc001fc0, "cAx,V(s,b)", pa10, 0},
1092
1093/* Immediate instructions. */
1094{ "ldo", 0x34000000, 0xfc000000, "l(b),x", pa20w, 0},
1095{ "ldo", 0x34000000, 0xfc00c000, "j(b),x", pa10, 0},
1096{ "ldil", 0x20000000, 0xfc000000, "k,b", pa10, 0},
1097{ "addil", 0x28000000, 0xfc000000, "k,b,Z", pa10, 0},
1098{ "addil", 0x28000000, 0xfc000000, "k,b", pa10, 0},
1099
1100/* Branching instructions. */
1101{ "b", 0xe8008000, 0xfc00e000, "cpnXL", pa20, FLAG_STRICT},
1102{ "b", 0xe800a000, 0xfc00e000, "clnXL", pa20, FLAG_STRICT},
1103{ "b", 0xe8000000, 0xfc00e000, "clnW,b", pa10, FLAG_STRICT},
1104{ "b", 0xe8002000, 0xfc00e000, "cgnW,b", pa10, FLAG_STRICT},
1105{ "b", 0xe8000000, 0xffe0e000, "nW", pa10, 0}, /* b,l foo,r0 */
1106{ "bl", 0xe8000000, 0xfc00e000, "nW,b", pa10, 0},
1107{ "gate", 0xe8002000, 0xfc00e000, "nW,b", pa10, 0},
1108{ "blr", 0xe8004000, 0xfc00e001, "nx,b", pa10, 0},
1109{ "bv", 0xe800c000, 0xfc00fffd, "nx(b)", pa10, 0},
1110{ "bv", 0xe800c000, 0xfc00fffd, "n(b)", pa10, 0},
1111{ "bve", 0xe800f001, 0xfc1ffffd, "cpn(b)L", pa20, FLAG_STRICT},
1112{ "bve", 0xe800f000, 0xfc1ffffd, "cln(b)L", pa20, FLAG_STRICT},
1113{ "bve", 0xe800d001, 0xfc1ffffd, "cPn(b)", pa20, FLAG_STRICT},
1114{ "bve", 0xe800d000, 0xfc1ffffd, "n(b)", pa20, FLAG_STRICT},
1115{ "be", 0xe4000000, 0xfc000000, "clnz(S,b),Y", pa10, FLAG_STRICT},
1116{ "be", 0xe4000000, 0xfc000000, "clnz(b),Y", pa10, FLAG_STRICT},
1117{ "be", 0xe0000000, 0xfc000000, "nz(S,b)", pa10, 0},
1118{ "be", 0xe0000000, 0xfc000000, "nz(b)", pa10, 0},
1119{ "ble", 0xe4000000, 0xfc000000, "nz(S,b)", pa10, 0},
1120{ "movb", 0xc8000000, 0xfc000000, "?ynx,b,w", pa10, 0},
1121{ "movib", 0xcc000000, 0xfc000000, "?yn5,b,w", pa10, 0},
1122{ "combt", 0x80000000, 0xfc000000, "?tnx,b,w", pa10, 0},
1123{ "combf", 0x88000000, 0xfc000000, "?tnx,b,w", pa10, 0},
1124{ "comibt", 0x84000000, 0xfc000000, "?tn5,b,w", pa10, 0},
1125{ "comibf", 0x8c000000, 0xfc000000, "?tn5,b,w", pa10, 0},
1126{ "addbt", 0xa0000000, 0xfc000000, "?dnx,b,w", pa10, 0},
1127{ "addbf", 0xa8000000, 0xfc000000, "?dnx,b,w", pa10, 0},
1128{ "addibt", 0xa4000000, 0xfc000000, "?dn5,b,w", pa10, 0},
1129{ "addibf", 0xac000000, 0xfc000000, "?dn5,b,w", pa10, 0},
1130{ "bb", 0xc0004000, 0xffe06000, "?bnx,!,w", pa10, FLAG_STRICT},
1131{ "bb", 0xc0006000, 0xffe06000, "?Bnx,!,w", pa20, FLAG_STRICT},
1132{ "bb", 0xc4004000, 0xfc006000, "?bnx,Q,w", pa10, FLAG_STRICT},
1133{ "bb", 0xc4004000, 0xfc004000, "?Bnx,B,w", pa20, FLAG_STRICT},
1134{ "bvb", 0xc0004000, 0xffe04000, "?bnx,w", pa10, 0},
1135{ "clrbts", 0xe8004005, 0xffffffff, "", pa20, FLAG_STRICT},
1136{ "popbts", 0xe8004005, 0xfffff007, "$", pa20, FLAG_STRICT},
1137{ "pushnom", 0xe8004001, 0xffffffff, "", pa20, FLAG_STRICT},
1138{ "pushbts", 0xe8004001, 0xffe0ffff, "x", pa20, FLAG_STRICT},
1139
1140/* Computation Instructions. */
1141
1142{ "cmpclr", 0x080008a0, 0xfc000fe0, "?Sx,b,t", pa20, FLAG_STRICT},
1143{ "cmpclr", 0x08000880, 0xfc000fe0, "?sx,b,t", pa10, FLAG_STRICT},
1144{ "comclr", 0x08000880, 0xfc000fe0, "?sx,b,t", pa10, 0},
1145{ "or", 0x08000260, 0xfc000fe0, "?Lx,b,t", pa20, FLAG_STRICT},
1146{ "or", 0x08000240, 0xfc000fe0, "?lx,b,t", pa10, 0},
1147{ "xor", 0x080002a0, 0xfc000fe0, "?Lx,b,t", pa20, FLAG_STRICT},
1148{ "xor", 0x08000280, 0xfc000fe0, "?lx,b,t", pa10, 0},
1149{ "and", 0x08000220, 0xfc000fe0, "?Lx,b,t", pa20, FLAG_STRICT},
1150{ "and", 0x08000200, 0xfc000fe0, "?lx,b,t", pa10, 0},
1151{ "andcm", 0x08000020, 0xfc000fe0, "?Lx,b,t", pa20, FLAG_STRICT},
1152{ "andcm", 0x08000000, 0xfc000fe0, "?lx,b,t", pa10, 0},
1153{ "uxor", 0x080003a0, 0xfc000fe0, "?Ux,b,t", pa20, FLAG_STRICT},
1154{ "uxor", 0x08000380, 0xfc000fe0, "?ux,b,t", pa10, 0},
1155{ "uaddcm", 0x080009a0, 0xfc000fa0, "cT?Ux,b,t", pa20, FLAG_STRICT},
1156{ "uaddcm", 0x08000980, 0xfc000fa0, "cT?ux,b,t", pa10, FLAG_STRICT},
1157{ "uaddcm", 0x08000980, 0xfc000fe0, "?ux,b,t", pa10, 0},
1158{ "uaddcmt", 0x080009c0, 0xfc000fe0, "?ux,b,t", pa10, 0},
1159{ "dcor", 0x08000ba0, 0xfc1f0fa0, "ci?Ub,t", pa20, FLAG_STRICT},
1160{ "dcor", 0x08000b80, 0xfc1f0fa0, "ci?ub,t", pa10, FLAG_STRICT},
1161{ "dcor", 0x08000b80, 0xfc1f0fe0, "?ub,t", pa10, 0},
1162{ "idcor", 0x08000bc0, 0xfc1f0fe0, "?ub,t", pa10, 0},
1163{ "addi", 0xb0000000, 0xfc000000, "ct?ai,b,x", pa10, FLAG_STRICT},
1164{ "addi", 0xb4000000, 0xfc000000, "cv?ai,b,x", pa10, FLAG_STRICT},
1165{ "addi", 0xb4000000, 0xfc000800, "?ai,b,x", pa10, 0},
1166{ "addio", 0xb4000800, 0xfc000800, "?ai,b,x", pa10, 0},
1167{ "addit", 0xb0000000, 0xfc000800, "?ai,b,x", pa10, 0},
1168{ "addito", 0xb0000800, 0xfc000800, "?ai,b,x", pa10, 0},
1169{ "add", 0x08000720, 0xfc0007e0, "cY?Ax,b,t", pa20, FLAG_STRICT},
1170{ "add", 0x08000700, 0xfc0007e0, "cy?ax,b,t", pa10, FLAG_STRICT},
1171{ "add", 0x08000220, 0xfc0003e0, "ca?Ax,b,t", pa20, FLAG_STRICT},
1172{ "add", 0x08000200, 0xfc0003e0, "ca?ax,b,t", pa10, FLAG_STRICT},
1173{ "add", 0x08000600, 0xfc000fe0, "?ax,b,t", pa10, 0},
1174{ "addl", 0x08000a00, 0xfc000fe0, "?ax,b,t", pa10, 0},
1175{ "addo", 0x08000e00, 0xfc000fe0, "?ax,b,t", pa10, 0},
1176{ "addc", 0x08000700, 0xfc000fe0, "?ax,b,t", pa10, 0},
1177{ "addco", 0x08000f00, 0xfc000fe0, "?ax,b,t", pa10, 0},
1178{ "sub", 0x080004e0, 0xfc0007e0, "ct?Sx,b,t", pa20, FLAG_STRICT},
1179{ "sub", 0x080004c0, 0xfc0007e0, "ct?sx,b,t", pa10, FLAG_STRICT},
1180{ "sub", 0x08000520, 0xfc0007e0, "cB?Sx,b,t", pa20, FLAG_STRICT},
1181{ "sub", 0x08000500, 0xfc0007e0, "cb?sx,b,t", pa10, FLAG_STRICT},
1182{ "sub", 0x08000420, 0xfc0007e0, "cv?Sx,b,t", pa20, FLAG_STRICT},
1183{ "sub", 0x08000400, 0xfc0007e0, "cv?sx,b,t", pa10, FLAG_STRICT},
1184{ "sub", 0x08000400, 0xfc000fe0, "?sx,b,t", pa10, 0},
1185{ "subo", 0x08000c00, 0xfc000fe0, "?sx,b,t", pa10, 0},
1186{ "subb", 0x08000500, 0xfc000fe0, "?sx,b,t", pa10, 0},
1187{ "subbo", 0x08000d00, 0xfc000fe0, "?sx,b,t", pa10, 0},
1188{ "subt", 0x080004c0, 0xfc000fe0, "?sx,b,t", pa10, 0},
1189{ "subto", 0x08000cc0, 0xfc000fe0, "?sx,b,t", pa10, 0},
1190{ "ds", 0x08000440, 0xfc000fe0, "?sx,b,t", pa10, 0},
1191{ "subi", 0x94000000, 0xfc000000, "cv?si,b,x", pa10, FLAG_STRICT},
1192{ "subi", 0x94000000, 0xfc000800, "?si,b,x", pa10, 0},
1193{ "subio", 0x94000800, 0xfc000800, "?si,b,x", pa10, 0},
1194{ "cmpiclr", 0x90000800, 0xfc000800, "?Si,b,x", pa20, FLAG_STRICT},
1195{ "cmpiclr", 0x90000000, 0xfc000800, "?si,b,x", pa10, FLAG_STRICT},
1196{ "comiclr", 0x90000000, 0xfc000800, "?si,b,x", pa10, 0},
1197{ "shladd", 0x08000220, 0xfc000320, "ca?Ax,.,b,t", pa20, FLAG_STRICT},
1198{ "shladd", 0x08000200, 0xfc000320, "ca?ax,.,b,t", pa10, FLAG_STRICT},
1199{ "sh1add", 0x08000640, 0xfc000fe0, "?ax,b,t", pa10, 0},
1200{ "sh1addl", 0x08000a40, 0xfc000fe0, "?ax,b,t", pa10, 0},
1201{ "sh1addo", 0x08000e40, 0xfc000fe0, "?ax,b,t", pa10, 0},
1202{ "sh2add", 0x08000680, 0xfc000fe0, "?ax,b,t", pa10, 0},
1203{ "sh2addl", 0x08000a80, 0xfc000fe0, "?ax,b,t", pa10, 0},
1204{ "sh2addo", 0x08000e80, 0xfc000fe0, "?ax,b,t", pa10, 0},
1205{ "sh3add", 0x080006c0, 0xfc000fe0, "?ax,b,t", pa10, 0},
1206{ "sh3addl", 0x08000ac0, 0xfc000fe0, "?ax,b,t", pa10, 0},
1207{ "sh3addo", 0x08000ec0, 0xfc000fe0, "?ax,b,t", pa10, 0},
1208
1209/* Subword Operation Instructions. */
1210
1211{ "hadd", 0x08000300, 0xfc00ff20, "cHx,b,t", pa20, FLAG_STRICT},
1212{ "havg", 0x080002c0, 0xfc00ffe0, "x,b,t", pa20, FLAG_STRICT},
1213{ "hshl", 0xf8008800, 0xffe0fc20, "x,*,t", pa20, FLAG_STRICT},
1214{ "hshladd", 0x08000700, 0xfc00ff20, "x,.,b,t", pa20, FLAG_STRICT},
1215{ "hshr", 0xf800c800, 0xfc1ff820, "cSb,*,t", pa20, FLAG_STRICT},
1216{ "hshradd", 0x08000500, 0xfc00ff20, "x,.,b,t", pa20, FLAG_STRICT},
1217{ "hsub", 0x08000100, 0xfc00ff20, "cHx,b,t", pa20, FLAG_STRICT},
1218{ "mixh", 0xf8008400, 0xfc009fe0, "chx,b,t", pa20, FLAG_STRICT},
1219{ "mixw", 0xf8008000, 0xfc009fe0, "chx,b,t", pa20, FLAG_STRICT},
1220{ "permh", 0xf8000000, 0xfc009020, "c*a,t", pa20, FLAG_STRICT},
1221
1222
1223/* Extract and Deposit Instructions. */
1224
1225{ "shrpd", 0xd0000200, 0xfc001fe0, "?Xx,b,!,t", pa20, FLAG_STRICT},
1226{ "shrpd", 0xd0000400, 0xfc001400, "?Xx,b,~,t", pa20, FLAG_STRICT},
1227{ "shrpw", 0xd0000000, 0xfc001fe0, "?xx,b,!,t", pa10, FLAG_STRICT},
1228{ "shrpw", 0xd0000800, 0xfc001c00, "?xx,b,p,t", pa10, FLAG_STRICT},
1229{ "vshd", 0xd0000000, 0xfc001fe0, "?xx,b,t", pa10, 0},
1230{ "shd", 0xd0000800, 0xfc001c00, "?xx,b,p,t", pa10, 0},
1231{ "extrd", 0xd0001200, 0xfc001ae0, "cS?Xb,!,%,x", pa20, FLAG_STRICT},
1232{ "extrd", 0xd8000000, 0xfc000000, "cS?Xb,q,|,x", pa20, FLAG_STRICT},
1233{ "extrw", 0xd0001000, 0xfc001be0, "cS?xb,!,T,x", pa10, FLAG_STRICT},
1234{ "extrw", 0xd0001800, 0xfc001800, "cS?xb,P,T,x", pa10, FLAG_STRICT},
1235{ "vextru", 0xd0001000, 0xfc001fe0, "?xb,T,x", pa10, 0},
1236{ "vextrs", 0xd0001400, 0xfc001fe0, "?xb,T,x", pa10, 0},
1237{ "extru", 0xd0001800, 0xfc001c00, "?xb,P,T,x", pa10, 0},
1238{ "extrs", 0xd0001c00, 0xfc001c00, "?xb,P,T,x", pa10, 0},
1239{ "depd", 0xd4000200, 0xfc001ae0, "cz?Xx,!,%,b", pa20, FLAG_STRICT},
1240{ "depd", 0xf0000000, 0xfc000000, "cz?Xx,~,|,b", pa20, FLAG_STRICT},
1241{ "depdi", 0xd4001200, 0xfc001ae0, "cz?X5,!,%,b", pa20, FLAG_STRICT},
1242{ "depdi", 0xf4000000, 0xfc000000, "cz?X5,~,|,b", pa20, FLAG_STRICT},
1243{ "depw", 0xd4000000, 0xfc001be0, "cz?xx,!,T,b", pa10, FLAG_STRICT},
1244{ "depw", 0xd4000800, 0xfc001800, "cz?xx,p,T,b", pa10, FLAG_STRICT},
1245{ "depwi", 0xd4001000, 0xfc001be0, "cz?x5,!,T,b", pa10, FLAG_STRICT},
1246{ "depwi", 0xd4001800, 0xfc001800, "cz?x5,p,T,b", pa10, FLAG_STRICT},
1247{ "zvdep", 0xd4000000, 0xfc001fe0, "?xx,T,b", pa10, 0},
1248{ "vdep", 0xd4000400, 0xfc001fe0, "?xx,T,b", pa10, 0},
1249{ "zdep", 0xd4000800, 0xfc001c00, "?xx,p,T,b", pa10, 0},
1250{ "dep", 0xd4000c00, 0xfc001c00, "?xx,p,T,b", pa10, 0},
1251{ "zvdepi", 0xd4001000, 0xfc001fe0, "?x5,T,b", pa10, 0},
1252{ "vdepi", 0xd4001400, 0xfc001fe0, "?x5,T,b", pa10, 0},
1253{ "zdepi", 0xd4001800, 0xfc001c00, "?x5,p,T,b", pa10, 0},
1254{ "depi", 0xd4001c00, 0xfc001c00, "?x5,p,T,b", pa10, 0},
1255
1256/* System Control Instructions. */
1257
1258{ "break", 0x00000000, 0xfc001fe0, "r,A", pa10, 0},
1259{ "rfi", 0x00000c00, 0xffffff1f, "cr", pa10, FLAG_STRICT},
1260{ "rfi", 0x00000c00, 0xffffffff, "", pa10, 0},
1261{ "rfir", 0x00000ca0, 0xffffffff, "", pa11, 0},
1262{ "ssm", 0x00000d60, 0xfc00ffe0, "U,t", pa20, FLAG_STRICT},
1263{ "ssm", 0x00000d60, 0xffe0ffe0, "R,t", pa10, 0},
1264{ "rsm", 0x00000e60, 0xfc00ffe0, "U,t", pa20, FLAG_STRICT},
1265{ "rsm", 0x00000e60, 0xffe0ffe0, "R,t", pa10, 0},
1266{ "mtsm", 0x00001860, 0xffe0ffff, "x", pa10, 0},
1267{ "ldsid", 0x000010a0, 0xfc1fffe0, "(b),t", pa10, 0},
1268{ "ldsid", 0x000010a0, 0xfc1f3fe0, "(s,b),t", pa10, 0},
1269{ "mtsp", 0x00001820, 0xffe01fff, "x,S", pa10, 0},
1270{ "mtctl", 0x00001840, 0xfc00ffff, "x,^", pa10, 0},
1271{ "mtsarcm", 0x016018C0, 0xffe0ffff, "x", pa20, FLAG_STRICT},
1272{ "mfia", 0x000014A0, 0xffffffe0, "t", pa20, FLAG_STRICT},
1273{ "mfsp", 0x000004a0, 0xffff1fe0, "S,t", pa10, 0},
1274{ "mfctl", 0x016048a0, 0xffffffe0, "cW!,t", pa20, FLAG_STRICT},
1275{ "mfctl", 0x000008a0, 0xfc1fffe0, "^,t", pa10, 0},
1276{ "sync", 0x00000400, 0xffffffff, "", pa10, 0},
1277{ "syncdma", 0x00100400, 0xffffffff, "", pa10, 0},
1278{ "probe", 0x04001180, 0xfc00ffa0, "cw(b),x,t", pa10, FLAG_STRICT},
1279{ "probe", 0x04001180, 0xfc003fa0, "cw(s,b),x,t", pa10, FLAG_STRICT},
1280{ "probei", 0x04003180, 0xfc00ffa0, "cw(b),R,t", pa10, FLAG_STRICT},
1281{ "probei", 0x04003180, 0xfc003fa0, "cw(s,b),R,t", pa10, FLAG_STRICT},
1282{ "prober", 0x04001180, 0xfc00ffe0, "(b),x,t", pa10, 0},
1283{ "prober", 0x04001180, 0xfc003fe0, "(s,b),x,t", pa10, 0},
1284{ "proberi", 0x04003180, 0xfc00ffe0, "(b),R,t", pa10, 0},
1285{ "proberi", 0x04003180, 0xfc003fe0, "(s,b),R,t", pa10, 0},
1286{ "probew", 0x040011c0, 0xfc00ffe0, "(b),x,t", pa10, 0},
1287{ "probew", 0x040011c0, 0xfc003fe0, "(s,b),x,t", pa10, 0},
1288{ "probewi", 0x040031c0, 0xfc00ffe0, "(b),R,t", pa10, 0},
1289{ "probewi", 0x040031c0, 0xfc003fe0, "(s,b),R,t", pa10, 0},
1290{ "lpa", 0x04001340, 0xfc00ffc0, "cZx(b),t", pa10, 0},
1291{ "lpa", 0x04001340, 0xfc003fc0, "cZx(s,b),t", pa10, 0},
1292{ "lci", 0x04001300, 0xfc00ffe0, "x(b),t", pa11, 0},
1293{ "lci", 0x04001300, 0xfc003fe0, "x(s,b),t", pa11, 0},
1294{ "pdtlb", 0x04001600, 0xfc00ffdf, "cLcZx(b)", pa20, FLAG_STRICT},
1295{ "pdtlb", 0x04001600, 0xfc003fdf, "cLcZx(s,b)", pa20, FLAG_STRICT},
1296{ "pdtlb", 0x04001600, 0xfc1fffdf, "cLcZ@(b)", pa20, FLAG_STRICT},
1297{ "pdtlb", 0x04001600, 0xfc1f3fdf, "cLcZ@(s,b)", pa20, FLAG_STRICT},
1298{ "pdtlb", 0x04001200, 0xfc00ffdf, "cZx(b)", pa10, 0},
1299{ "pdtlb", 0x04001200, 0xfc003fdf, "cZx(s,b)", pa10, 0},
1300{ "pitlb", 0x04000600, 0xfc001fdf, "cLcZx(S,b)", pa20, FLAG_STRICT},
1301{ "pitlb", 0x04000600, 0xfc1f1fdf, "cLcZ@(S,b)", pa20, FLAG_STRICT},
1302{ "pitlb", 0x04000200, 0xfc001fdf, "cZx(S,b)", pa10, 0},
1303{ "pdtlbe", 0x04001240, 0xfc00ffdf, "cZx(b)", pa10, 0},
1304{ "pdtlbe", 0x04001240, 0xfc003fdf, "cZx(s,b)", pa10, 0},
1305{ "pitlbe", 0x04000240, 0xfc001fdf, "cZx(S,b)", pa10, 0},
1306{ "idtlba", 0x04001040, 0xfc00ffff, "x,(b)", pa10, 0},
1307{ "idtlba", 0x04001040, 0xfc003fff, "x,(s,b)", pa10, 0},
1308{ "iitlba", 0x04000040, 0xfc001fff, "x,(S,b)", pa10, 0},
1309{ "idtlbp", 0x04001000, 0xfc00ffff, "x,(b)", pa10, 0},
1310{ "idtlbp", 0x04001000, 0xfc003fff, "x,(s,b)", pa10, 0},
1311{ "iitlbp", 0x04000000, 0xfc001fff, "x,(S,b)", pa10, 0},
1312{ "pdc", 0x04001380, 0xfc00ffdf, "cZx(b)", pa10, 0},
1313{ "pdc", 0x04001380, 0xfc003fdf, "cZx(s,b)", pa10, 0},
1314{ "fdc", 0x04001280, 0xfc00ffdf, "cZx(b)", pa10, FLAG_STRICT},
1315{ "fdc", 0x04001280, 0xfc003fdf, "cZx(s,b)", pa10, FLAG_STRICT},
1316{ "fdc", 0x04003280, 0xfc00ffff, "5(b)", pa20, FLAG_STRICT},
1317{ "fdc", 0x04003280, 0xfc003fff, "5(s,b)", pa20, FLAG_STRICT},
1318{ "fdc", 0x04001280, 0xfc00ffdf, "cZx(b)", pa10, 0},
1319{ "fdc", 0x04001280, 0xfc003fdf, "cZx(s,b)", pa10, 0},
1320{ "fic", 0x040013c0, 0xfc00dfdf, "cZx(b)", pa20, FLAG_STRICT},
1321{ "fic", 0x04000280, 0xfc001fdf, "cZx(S,b)", pa10, 0},
1322{ "fdce", 0x040012c0, 0xfc00ffdf, "cZx(b)", pa10, 0},
1323{ "fdce", 0x040012c0, 0xfc003fdf, "cZx(s,b)", pa10, 0},
1324{ "fice", 0x040002c0, 0xfc001fdf, "cZx(S,b)", pa10, 0},
1325{ "diag", 0x14000000, 0xfc000000, "D", pa10, 0},
1326{ "idtlbt", 0x04001800, 0xfc00ffff, "x,b", pa20, FLAG_STRICT},
1327{ "iitlbt", 0x04000800, 0xfc00ffff, "x,b", pa20, FLAG_STRICT},
1328
1329/* These may be specific to certain versions of the PA. Joel claimed
1330 they were 72000 (7200?) specific. However, I'm almost certain the
1331 mtcpu/mfcpu were undocumented, but available in the older 700 machines. */
1332{ "mtcpu", 0x14001600, 0xfc00ffff, "x,^", pa10, 0},
1333{ "mfcpu", 0x14001A00, 0xfc00ffff, "^,x", pa10, 0},
1334{ "tocen", 0x14403600, 0xffffffff, "", pa10, 0},
1335{ "tocdis", 0x14401620, 0xffffffff, "", pa10, 0},
1336{ "shdwgr", 0x14402600, 0xffffffff, "", pa10, 0},
1337{ "grshdw", 0x14400620, 0xffffffff, "", pa10, 0},
1338
1339/* gfw and gfr are not in the HP PA 1.1 manual, but they are in either
1340 the Timex FPU or the Mustang ERS (not sure which) manual. */
1341{ "gfw", 0x04001680, 0xfc00ffdf, "cZx(b)", pa11, 0},
1342{ "gfw", 0x04001680, 0xfc003fdf, "cZx(s,b)", pa11, 0},
1343{ "gfr", 0x04001a80, 0xfc00ffdf, "cZx(b)", pa11, 0},
1344{ "gfr", 0x04001a80, 0xfc003fdf, "cZx(s,b)", pa11, 0},
1345
1346/* Floating Point Coprocessor Instructions. */
1347
1348{ "fldw", 0x24000000, 0xfc00df80, "cXx(b),fT", pa10, FLAG_STRICT},
1349{ "fldw", 0x24000000, 0xfc001f80, "cXx(s,b),fT", pa10, FLAG_STRICT},
1350{ "fldw", 0x24000000, 0xfc00d380, "cxccx(b),fT", pa11, FLAG_STRICT},
1351{ "fldw", 0x24000000, 0xfc001380, "cxccx(s,b),fT", pa11, FLAG_STRICT},
1352{ "fldw", 0x24001020, 0xfc1ff3a0, "cocc@(b),fT", pa20, FLAG_STRICT},
1353{ "fldw", 0x24001020, 0xfc1f33a0, "cocc@(s,b),fT", pa20, FLAG_STRICT},
1354{ "fldw", 0x24001000, 0xfc00df80, "cM5(b),fT", pa10, FLAG_STRICT},
1355{ "fldw", 0x24001000, 0xfc001f80, "cM5(s,b),fT", pa10, FLAG_STRICT},
1356{ "fldw", 0x24001000, 0xfc00d380, "cmcc5(b),fT", pa11, FLAG_STRICT},
1357{ "fldw", 0x24001000, 0xfc001380, "cmcc5(s,b),fT", pa11, FLAG_STRICT},
1358{ "fldw", 0x5c000000, 0xfc000004, "y(b),fe", pa20w, FLAG_STRICT},
1359{ "fldw", 0x58000000, 0xfc000000, "cJy(b),fe", pa20w, FLAG_STRICT},
1360{ "fldw", 0x5c000000, 0xfc00c004, "d(b),fe", pa20, FLAG_STRICT},
1361{ "fldw", 0x5c000000, 0xfc000004, "d(s,b),fe", pa20, FLAG_STRICT},
1362{ "fldw", 0x58000000, 0xfc00c000, "cJd(b),fe", pa20, FLAG_STRICT},
1363{ "fldw", 0x58000000, 0xfc000000, "cJd(s,b),fe", pa20, FLAG_STRICT},
1364{ "fldd", 0x2c000000, 0xfc00dfc0, "cXx(b),ft", pa10, FLAG_STRICT},
1365{ "fldd", 0x2c000000, 0xfc001fc0, "cXx(s,b),ft", pa10, FLAG_STRICT},
1366{ "fldd", 0x2c000000, 0xfc00d3c0, "cxccx(b),ft", pa11, FLAG_STRICT},
1367{ "fldd", 0x2c000000, 0xfc0013c0, "cxccx(s,b),ft", pa11, FLAG_STRICT},
1368{ "fldd", 0x2c001020, 0xfc1ff3e0, "cocc@(b),ft", pa20, FLAG_STRICT},
1369{ "fldd", 0x2c001020, 0xfc1f33e0, "cocc@(s,b),ft", pa20, FLAG_STRICT},
1370{ "fldd", 0x2c001000, 0xfc00dfc0, "cM5(b),ft", pa10, FLAG_STRICT},
1371{ "fldd", 0x2c001000, 0xfc001fc0, "cM5(s,b),ft", pa10, FLAG_STRICT},
1372{ "fldd", 0x2c001000, 0xfc00d3c0, "cmcc5(b),ft", pa11, FLAG_STRICT},
1373{ "fldd", 0x2c001000, 0xfc0013c0, "cmcc5(s,b),ft", pa11, FLAG_STRICT},
1374{ "fldd", 0x50000002, 0xfc000002, "cq&(b),fx", pa20w, FLAG_STRICT},
1375{ "fldd", 0x50000002, 0xfc00c002, "cq#(b),fx", pa20, FLAG_STRICT},
1376{ "fldd", 0x50000002, 0xfc000002, "cq#(s,b),fx", pa20, FLAG_STRICT},
1377{ "fstw", 0x24000200, 0xfc00df80, "cXfT,x(b)", pa10, FLAG_STRICT},
1378{ "fstw", 0x24000200, 0xfc001f80, "cXfT,x(s,b)", pa10, FLAG_STRICT},
1379{ "fstw", 0x24000200, 0xfc00d380, "cxcCfT,x(b)", pa11, FLAG_STRICT},
1380{ "fstw", 0x24000200, 0xfc001380, "cxcCfT,x(s,b)", pa11, FLAG_STRICT},
1381{ "fstw", 0x24001220, 0xfc1ff3a0, "cocCfT,@(b)", pa20, FLAG_STRICT},
1382{ "fstw", 0x24001220, 0xfc1f33a0, "cocCfT,@(s,b)", pa20, FLAG_STRICT},
1383{ "fstw", 0x24001200, 0xfc00df80, "cMfT,5(b)", pa10, FLAG_STRICT},
1384{ "fstw", 0x24001200, 0xfc001f80, "cMfT,5(s,b)", pa10, FLAG_STRICT},
1385{ "fstw", 0x24001200, 0xfc00df80, "cMfT,5(b)", pa10, FLAG_STRICT},
1386{ "fstw", 0x24001200, 0xfc001f80, "cMfT,5(s,b)", pa10, FLAG_STRICT},
1387{ "fstw", 0x7c000000, 0xfc000004, "fE,y(b)", pa20w, FLAG_STRICT},
1388{ "fstw", 0x78000000, 0xfc000000, "cJfE,y(b)", pa20w, FLAG_STRICT},
1389{ "fstw", 0x7c000000, 0xfc00c004, "fE,d(b)", pa20, FLAG_STRICT},
1390{ "fstw", 0x7c000000, 0xfc000004, "fE,d(s,b)", pa20, FLAG_STRICT},
1391{ "fstw", 0x78000000, 0xfc00c000, "cJfE,d(b)", pa20, FLAG_STRICT},
1392{ "fstw", 0x78000000, 0xfc000000, "cJfE,d(s,b)", pa20, FLAG_STRICT},
1393{ "fstd", 0x2c000200, 0xfc00dfc0, "cXft,x(b)", pa10, FLAG_STRICT},
1394{ "fstd", 0x2c000200, 0xfc001fc0, "cXft,x(s,b)", pa10, FLAG_STRICT},
1395{ "fstd", 0x2c000200, 0xfc00d3c0, "cxcCft,x(b)", pa11, FLAG_STRICT},
1396{ "fstd", 0x2c000200, 0xfc0013c0, "cxcCft,x(s,b)", pa11, FLAG_STRICT},
1397{ "fstd", 0x2c001220, 0xfc1ff3e0, "cocCft,@(b)", pa20, FLAG_STRICT},
1398{ "fstd", 0x2c001220, 0xfc1f33e0, "cocCft,@(s,b)", pa20, FLAG_STRICT},
1399{ "fstd", 0x2c001200, 0xfc00dfc0, "cMft,5(b)", pa10, FLAG_STRICT},
1400{ "fstd", 0x2c001200, 0xfc001fc0, "cMft,5(s,b)", pa10, FLAG_STRICT},
1401{ "fstd", 0x2c001200, 0xfc00d3c0, "cmcCft,5(b)", pa11, FLAG_STRICT},
1402{ "fstd", 0x2c001200, 0xfc0013c0, "cmcCft,5(s,b)", pa11, FLAG_STRICT},
1403{ "fstd", 0x70000002, 0xfc000002, "cqfx,&(b)", pa20w, FLAG_STRICT},
1404{ "fstd", 0x70000002, 0xfc00c002, "cqfx,#(b)", pa20, FLAG_STRICT},
1405{ "fstd", 0x70000002, 0xfc000002, "cqfx,#(s,b)", pa20, FLAG_STRICT},
1406{ "fldwx", 0x24000000, 0xfc00df80, "cXx(b),fT", pa10, FLAG_STRICT},
1407{ "fldwx", 0x24000000, 0xfc001f80, "cXx(s,b),fT", pa10, FLAG_STRICT},
1408{ "fldwx", 0x24000000, 0xfc00d380, "cxccx(b),fT", pa11, FLAG_STRICT},
1409{ "fldwx", 0x24000000, 0xfc001380, "cxccx(s,b),fT", pa11, FLAG_STRICT},
1410{ "fldwx", 0x24000000, 0xfc00df80, "cXx(b),fT", pa10, 0},
1411{ "fldwx", 0x24000000, 0xfc001f80, "cXx(s,b),fT", pa10, 0},
1412{ "flddx", 0x2c000000, 0xfc00dfc0, "cXx(b),ft", pa10, FLAG_STRICT},
1413{ "flddx", 0x2c000000, 0xfc001fc0, "cXx(s,b),ft", pa10, FLAG_STRICT},
1414{ "flddx", 0x2c000000, 0xfc00d3c0, "cxccx(b),ft", pa11, FLAG_STRICT},
1415{ "flddx", 0x2c000000, 0xfc0013c0, "cxccx(s,b),ft", pa11, FLAG_STRICT},
1416{ "flddx", 0x2c000000, 0xfc00dfc0, "cXx(b),ft", pa10, 0},
1417{ "flddx", 0x2c000000, 0xfc001fc0, "cXx(s,b),ft", pa10, 0},
1418{ "fstwx", 0x24000200, 0xfc00df80, "cxfT,x(b)", pa10, FLAG_STRICT},
1419{ "fstwx", 0x24000200, 0xfc001f80, "cxfT,x(s,b)", pa10, FLAG_STRICT},
1420{ "fstwx", 0x24000200, 0xfc00d380, "cxcCfT,x(b)", pa11, FLAG_STRICT},
1421{ "fstwx", 0x24000200, 0xfc001380, "cxcCfT,x(s,b)", pa11, FLAG_STRICT},
1422{ "fstwx", 0x24000200, 0xfc00df80, "cxfT,x(b)", pa10, 0},
1423{ "fstwx", 0x24000200, 0xfc001f80, "cxfT,x(s,b)", pa10, 0},
1424{ "fstdx", 0x2c000200, 0xfc00dfc0, "cxft,x(b)", pa10, FLAG_STRICT},
1425{ "fstdx", 0x2c000200, 0xfc001fc0, "cxft,x(s,b)", pa10, FLAG_STRICT},
1426{ "fstdx", 0x2c000200, 0xfc00d3c0, "cxcCft,x(b)", pa11, FLAG_STRICT},
1427{ "fstdx", 0x2c000200, 0xfc0013c0, "cxcCft,x(s,b)", pa11, FLAG_STRICT},
1428{ "fstdx", 0x2c000200, 0xfc00dfc0, "cxft,x(b)", pa10, 0},
1429{ "fstdx", 0x2c000200, 0xfc001fc0, "cxft,x(s,b)", pa10, 0},
1430{ "fstqx", 0x3c000200, 0xfc00dfc0, "cxft,x(b)", pa10, 0},
1431{ "fstqx", 0x3c000200, 0xfc001fc0, "cxft,x(s,b)", pa10, 0},
1432{ "fldws", 0x24001000, 0xfc00df80, "cm5(b),fT", pa10, FLAG_STRICT},
1433{ "fldws", 0x24001000, 0xfc001f80, "cm5(s,b),fT", pa10, FLAG_STRICT},
1434{ "fldws", 0x24001000, 0xfc00d380, "cmcc5(b),fT", pa11, FLAG_STRICT},
1435{ "fldws", 0x24001000, 0xfc001380, "cmcc5(s,b),fT", pa11, FLAG_STRICT},
1436{ "fldws", 0x24001000, 0xfc00df80, "cm5(b),fT", pa10, 0},
1437{ "fldws", 0x24001000, 0xfc001f80, "cm5(s,b),fT", pa10, 0},
1438{ "fldds", 0x2c001000, 0xfc00dfc0, "cm5(b),ft", pa10, FLAG_STRICT},
1439{ "fldds", 0x2c001000, 0xfc001fc0, "cm5(s,b),ft", pa10, FLAG_STRICT},
1440{ "fldds", 0x2c001000, 0xfc00d3c0, "cmcc5(b),ft", pa11, FLAG_STRICT},
1441{ "fldds", 0x2c001000, 0xfc0013c0, "cmcc5(s,b),ft", pa11, FLAG_STRICT},
1442{ "fldds", 0x2c001000, 0xfc00dfc0, "cm5(b),ft", pa10, 0},
1443{ "fldds", 0x2c001000, 0xfc001fc0, "cm5(s,b),ft", pa10, 0},
1444{ "fstws", 0x24001200, 0xfc00df80, "cmfT,5(b)", pa10, FLAG_STRICT},
1445{ "fstws", 0x24001200, 0xfc001f80, "cmfT,5(s,b)", pa10, FLAG_STRICT},
1446{ "fstws", 0x24001200, 0xfc00d380, "cmcCfT,5(b)", pa11, FLAG_STRICT},
1447{ "fstws", 0x24001200, 0xfc001380, "cmcCfT,5(s,b)", pa11, FLAG_STRICT},
1448{ "fstws", 0x24001200, 0xfc00df80, "cmfT,5(b)", pa10, 0},
1449{ "fstws", 0x24001200, 0xfc001f80, "cmfT,5(s,b)", pa10, 0},
1450{ "fstds", 0x2c001200, 0xfc00dfc0, "cmft,5(b)", pa10, FLAG_STRICT},
1451{ "fstds", 0x2c001200, 0xfc001fc0, "cmft,5(s,b)", pa10, FLAG_STRICT},
1452{ "fstds", 0x2c001200, 0xfc00d3c0, "cmcCft,5(b)", pa11, FLAG_STRICT},
1453{ "fstds", 0x2c001200, 0xfc0013c0, "cmcCft,5(s,b)", pa11, FLAG_STRICT},
1454{ "fstds", 0x2c001200, 0xfc00dfc0, "cmft,5(b)", pa10, 0},
1455{ "fstds", 0x2c001200, 0xfc001fc0, "cmft,5(s,b)", pa10, 0},
1456{ "fstqs", 0x3c001200, 0xfc00dfc0, "cmft,5(b)", pa10, 0},
1457{ "fstqs", 0x3c001200, 0xfc001fc0, "cmft,5(s,b)", pa10, 0},
1458{ "fadd", 0x30000600, 0xfc00e7e0, "Ffa,fb,fT", pa10, 0},
1459{ "fadd", 0x38000600, 0xfc00e720, "IfA,fB,fT", pa10, 0},
1460{ "fsub", 0x30002600, 0xfc00e7e0, "Ffa,fb,fT", pa10, 0},
1461{ "fsub", 0x38002600, 0xfc00e720, "IfA,fB,fT", pa10, 0},
1462{ "fmpy", 0x30004600, 0xfc00e7e0, "Ffa,fb,fT", pa10, 0},
1463{ "fmpy", 0x38004600, 0xfc00e720, "IfA,fB,fT", pa10, 0},
1464{ "fdiv", 0x30006600, 0xfc00e7e0, "Ffa,fb,fT", pa10, 0},
1465{ "fdiv", 0x38006600, 0xfc00e720, "IfA,fB,fT", pa10, 0},
1466{ "fsqrt", 0x30008000, 0xfc1fe7e0, "Ffa,fT", pa10, 0},
1467{ "fsqrt", 0x38008000, 0xfc1fe720, "FfA,fT", pa10, 0},
1468{ "fabs", 0x30006000, 0xfc1fe7e0, "Ffa,fT", pa10, 0},
1469{ "fabs", 0x38006000, 0xfc1fe720, "FfA,fT", pa10, 0},
1470{ "frem", 0x30008600, 0xfc00e7e0, "Ffa,fb,fT", pa10, 0},
1471{ "frem", 0x38008600, 0xfc00e720, "FfA,fB,fT", pa10, 0},
1472{ "frnd", 0x3000a000, 0xfc1fe7e0, "Ffa,fT", pa10, 0},
1473{ "frnd", 0x3800a000, 0xfc1fe720, "FfA,fT", pa10, 0},
1474{ "fcpy", 0x30004000, 0xfc1fe7e0, "Ffa,fT", pa10, 0},
1475{ "fcpy", 0x38004000, 0xfc1fe720, "FfA,fT", pa10, 0},
1476{ "fcnvff", 0x30000200, 0xfc1f87e0, "FGfa,fT", pa10, 0},
1477{ "fcnvff", 0x38000200, 0xfc1f8720, "FGfA,fT", pa10, 0},
1478{ "fcnvxf", 0x30008200, 0xfc1f87e0, "FGfa,fT", pa10, 0},
1479{ "fcnvxf", 0x38008200, 0xfc1f8720, "FGfA,fT", pa10, 0},
1480{ "fcnvfx", 0x30010200, 0xfc1f87e0, "FGfa,fT", pa10, 0},
1481{ "fcnvfx", 0x38010200, 0xfc1f8720, "FGfA,fT", pa10, 0},
1482{ "fcnvfxt", 0x30018200, 0xfc1f87e0, "FGfa,fT", pa10, 0},
1483{ "fcnvfxt", 0x38018200, 0xfc1f8720, "FGfA,fT", pa10, 0},
1484{ "fmpyfadd", 0xb8000000, 0xfc000020, "IfA,fB,fC,fT", pa20, FLAG_STRICT},
1485{ "fmpynfadd", 0xb8000020, 0xfc000020, "IfA,fB,fC,fT", pa20, FLAG_STRICT},
1486{ "fneg", 0x3000c000, 0xfc1fe7e0, "Ffa,fT", pa20, FLAG_STRICT},
1487{ "fneg", 0x3800c000, 0xfc1fe720, "IfA,fT", pa20, FLAG_STRICT},
1488{ "fnegabs", 0x3000e000, 0xfc1fe7e0, "Ffa,fT", pa20, FLAG_STRICT},
1489{ "fnegabs", 0x3800e000, 0xfc1fe720, "IfA,fT", pa20, FLAG_STRICT},
1490{ "fcnv", 0x30000200, 0xfc1c0720, "{_fa,fT", pa20, FLAG_STRICT},
1491{ "fcnv", 0x38000200, 0xfc1c0720, "FGfA,fT", pa20, FLAG_STRICT},
1492{ "fcmp", 0x30000400, 0xfc00e7e0, "F?ffa,fb", pa10, FLAG_STRICT},
1493{ "fcmp", 0x38000400, 0xfc00e720, "I?ffA,fB", pa10, FLAG_STRICT},
1494{ "fcmp", 0x30000400, 0xfc0007e0, "F?ffa,fb,h", pa20, FLAG_STRICT},
1495{ "fcmp", 0x38000400, 0xfc000720, "I?ffA,fB,h", pa20, FLAG_STRICT},
1496{ "fcmp", 0x30000400, 0xfc00e7e0, "F?ffa,fb", pa10, 0},
1497{ "fcmp", 0x38000400, 0xfc00e720, "I?ffA,fB", pa10, 0},
1498{ "xmpyu", 0x38004700, 0xfc00e720, "fX,fB,fT", pa11, 0},
1499{ "fmpyadd", 0x18000000, 0xfc000000, "Hfi,fj,fk,fl,fm", pa11, 0},
1500{ "fmpysub", 0x98000000, 0xfc000000, "Hfi,fj,fk,fl,fm", pa11, 0},
1501{ "ftest", 0x30002420, 0xffffffff, "", pa10, FLAG_STRICT},
1502{ "ftest", 0x30002420, 0xffffffe0, ",=", pa20, FLAG_STRICT},
1503{ "ftest", 0x30000420, 0xffff1fff, "m", pa20, FLAG_STRICT},
1504{ "fid", 0x30000000, 0xffffffff, "", pa11, 0},
1505
1506/* Performance Monitor Instructions. */
1507
1508{ "pmdis", 0x30000280, 0xffffffdf, "N", pa20, FLAG_STRICT},
1509{ "pmenb", 0x30000680, 0xffffffff, "", pa20, FLAG_STRICT},
1510
1511/* Assist Instructions. */
1512
1513{ "spop0", 0x10000000, 0xfc000600, "v,ON", pa10, 0},
1514{ "spop1", 0x10000200, 0xfc000600, "v,oNt", pa10, 0},
1515{ "spop2", 0x10000400, 0xfc000600, "v,1Nb", pa10, 0},
1516{ "spop3", 0x10000600, 0xfc000600, "v,0Nx,b", pa10, 0},
1517{ "copr", 0x30000000, 0xfc000000, "u,2N", pa10, 0},
1518{ "cldw", 0x24000000, 0xfc00de00, "ucXx(b),t", pa10, FLAG_STRICT},
1519{ "cldw", 0x24000000, 0xfc001e00, "ucXx(s,b),t", pa10, FLAG_STRICT},
1520{ "cldw", 0x24000000, 0xfc00d200, "ucxccx(b),t", pa11, FLAG_STRICT},
1521{ "cldw", 0x24000000, 0xfc001200, "ucxccx(s,b),t", pa11, FLAG_STRICT},
1522{ "cldw", 0x24001000, 0xfc00d200, "ucocc@(b),t", pa20, FLAG_STRICT},
1523{ "cldw", 0x24001000, 0xfc001200, "ucocc@(s,b),t", pa20, FLAG_STRICT},
1524{ "cldw", 0x24001000, 0xfc00de00, "ucM5(b),t", pa10, FLAG_STRICT},
1525{ "cldw", 0x24001000, 0xfc001e00, "ucM5(s,b),t", pa10, FLAG_STRICT},
1526{ "cldw", 0x24001000, 0xfc00d200, "ucmcc5(b),t", pa11, FLAG_STRICT},
1527{ "cldw", 0x24001000, 0xfc001200, "ucmcc5(s,b),t", pa11, FLAG_STRICT},
1528{ "cldd", 0x2c000000, 0xfc00de00, "ucXx(b),t", pa10, FLAG_STRICT},
1529{ "cldd", 0x2c000000, 0xfc001e00, "ucXx(s,b),t", pa10, FLAG_STRICT},
1530{ "cldd", 0x2c000000, 0xfc00d200, "ucxccx(b),t", pa11, FLAG_STRICT},
1531{ "cldd", 0x2c000000, 0xfc001200, "ucxccx(s,b),t", pa11, FLAG_STRICT},
1532{ "cldd", 0x2c001000, 0xfc00d200, "ucocc@(b),t", pa20, FLAG_STRICT},
1533{ "cldd", 0x2c001000, 0xfc001200, "ucocc@(s,b),t", pa20, FLAG_STRICT},
1534{ "cldd", 0x2c001000, 0xfc00de00, "ucM5(b),t", pa10, FLAG_STRICT},
1535{ "cldd", 0x2c001000, 0xfc001e00, "ucM5(s,b),t", pa10, FLAG_STRICT},
1536{ "cldd", 0x2c001000, 0xfc00d200, "ucmcc5(b),t", pa11, FLAG_STRICT},
1537{ "cldd", 0x2c001000, 0xfc001200, "ucmcc5(s,b),t", pa11, FLAG_STRICT},
1538{ "cstw", 0x24000200, 0xfc00de00, "ucXt,x(b)", pa10, FLAG_STRICT},
1539{ "cstw", 0x24000200, 0xfc001e00, "ucXt,x(s,b)", pa10, FLAG_STRICT},
1540{ "cstw", 0x24000200, 0xfc00d200, "ucxcCt,x(b)", pa11, FLAG_STRICT},
1541{ "cstw", 0x24000200, 0xfc001200, "ucxcCt,x(s,b)", pa11, FLAG_STRICT},
1542{ "cstw", 0x24001200, 0xfc00d200, "ucocCt,@(b)", pa20, FLAG_STRICT},
1543{ "cstw", 0x24001200, 0xfc001200, "ucocCt,@(s,b)", pa20, FLAG_STRICT},
1544{ "cstw", 0x24001200, 0xfc00de00, "ucMt,5(b)", pa10, FLAG_STRICT},
1545{ "cstw", 0x24001200, 0xfc001e00, "ucMt,5(s,b)", pa10, FLAG_STRICT},
1546{ "cstw", 0x24001200, 0xfc00d200, "ucmcCt,5(b)", pa11, FLAG_STRICT},
1547{ "cstw", 0x24001200, 0xfc001200, "ucmcCt,5(s,b)", pa11, FLAG_STRICT},
1548{ "cstd", 0x2c000200, 0xfc00de00, "ucXt,x(b)", pa10, FLAG_STRICT},
1549{ "cstd", 0x2c000200, 0xfc001e00, "ucXt,x(s,b)", pa10, FLAG_STRICT},
1550{ "cstd", 0x2c000200, 0xfc00d200, "ucxcCt,x(b)", pa11, FLAG_STRICT},
1551{ "cstd", 0x2c000200, 0xfc001200, "ucxcCt,x(s,b)", pa11, FLAG_STRICT},
1552{ "cstd", 0x2c001200, 0xfc00d200, "ucocCt,@(b)", pa20, FLAG_STRICT},
1553{ "cstd", 0x2c001200, 0xfc001200, "ucocCt,@(s,b)", pa20, FLAG_STRICT},
1554{ "cstd", 0x2c001200, 0xfc00de00, "ucMt,5(b)", pa10, FLAG_STRICT},
1555{ "cstd", 0x2c001200, 0xfc001e00, "ucMt,5(s,b)", pa10, FLAG_STRICT},
1556{ "cstd", 0x2c001200, 0xfc00d200, "ucmcCt,5(b)", pa11, FLAG_STRICT},
1557{ "cstd", 0x2c001200, 0xfc001200, "ucmcCt,5(s,b)", pa11, FLAG_STRICT},
1558{ "cldwx", 0x24000000, 0xfc00de00, "ucXx(b),t", pa10, FLAG_STRICT},
1559{ "cldwx", 0x24000000, 0xfc001e00, "ucXx(s,b),t", pa10, FLAG_STRICT},
1560{ "cldwx", 0x24000000, 0xfc00d200, "ucxccx(b),t", pa11, FLAG_STRICT},
1561{ "cldwx", 0x24000000, 0xfc001200, "ucxccx(s,b),t", pa11, FLAG_STRICT},
1562{ "cldwx", 0x24000000, 0xfc00de00, "ucXx(b),t", pa10, 0},
1563{ "cldwx", 0x24000000, 0xfc001e00, "ucXx(s,b),t", pa10, 0},
1564{ "clddx", 0x2c000000, 0xfc00de00, "ucXx(b),t", pa10, FLAG_STRICT},
1565{ "clddx", 0x2c000000, 0xfc001e00, "ucXx(s,b),t", pa10, FLAG_STRICT},
1566{ "clddx", 0x2c000000, 0xfc00d200, "ucxccx(b),t", pa11, FLAG_STRICT},
1567{ "clddx", 0x2c000000, 0xfc001200, "ucxccx(s,b),t", pa11, FLAG_STRICT},
1568{ "clddx", 0x2c000000, 0xfc00de00, "ucXx(b),t", pa10, 0},
1569{ "clddx", 0x2c000000, 0xfc001e00, "ucXx(s,b),t", pa10, 0},
1570{ "cstwx", 0x24000200, 0xfc00de00, "ucXt,x(b)", pa10, FLAG_STRICT},
1571{ "cstwx", 0x24000200, 0xfc001e00, "ucXt,x(s,b)", pa10, FLAG_STRICT},
1572{ "cstwx", 0x24000200, 0xfc00d200, "ucxcCt,x(b)", pa11, FLAG_STRICT},
1573{ "cstwx", 0x24000200, 0xfc001200, "ucxcCt,x(s,b)", pa11, FLAG_STRICT},
1574{ "cstwx", 0x24000200, 0xfc00de00, "ucXt,x(b)", pa10, 0},
1575{ "cstwx", 0x24000200, 0xfc001e00, "ucXt,x(s,b)", pa10, 0},
1576{ "cstdx", 0x2c000200, 0xfc00de00, "ucXt,x(b)", pa10, FLAG_STRICT},
1577{ "cstdx", 0x2c000200, 0xfc001e00, "ucXt,x(s,b)", pa10, FLAG_STRICT},
1578{ "cstdx", 0x2c000200, 0xfc00d200, "ucxcCt,x(b)", pa11, FLAG_STRICT},
1579{ "cstdx", 0x2c000200, 0xfc001200, "ucxcCt,x(s,b)", pa11, FLAG_STRICT},
1580{ "cstdx", 0x2c000200, 0xfc00de00, "ucXt,x(b)", pa10, 0},
1581{ "cstdx", 0x2c000200, 0xfc001e00, "ucXt,x(s,b)", pa10, 0},
1582{ "cldws", 0x24001000, 0xfc00de00, "ucM5(b),t", pa10, FLAG_STRICT},
1583{ "cldws", 0x24001000, 0xfc001e00, "ucM5(s,b),t", pa10, FLAG_STRICT},
1584{ "cldws", 0x24001000, 0xfc00d200, "ucmcc5(b),t", pa11, FLAG_STRICT},
1585{ "cldws", 0x24001000, 0xfc001200, "ucmcc5(s,b),t", pa11, FLAG_STRICT},
1586{ "cldws", 0x24001000, 0xfc00de00, "ucM5(b),t", pa10, 0},
1587{ "cldws", 0x24001000, 0xfc001e00, "ucM5(s,b),t", pa10, 0},
1588{ "cldds", 0x2c001000, 0xfc00de00, "ucM5(b),t", pa10, FLAG_STRICT},
1589{ "cldds", 0x2c001000, 0xfc001e00, "ucM5(s,b),t", pa10, FLAG_STRICT},
1590{ "cldds", 0x2c001000, 0xfc00d200, "ucmcc5(b),t", pa11, FLAG_STRICT},
1591{ "cldds", 0x2c001000, 0xfc001200, "ucmcc5(s,b),t", pa11, FLAG_STRICT},
1592{ "cldds", 0x2c001000, 0xfc00de00, "ucM5(b),t", pa10, 0},
1593{ "cldds", 0x2c001000, 0xfc001e00, "ucM5(s,b),t", pa10, 0},
1594{ "cstws", 0x24001200, 0xfc00de00, "ucMt,5(b)", pa10, FLAG_STRICT},
1595{ "cstws", 0x24001200, 0xfc001e00, "ucMt,5(s,b)", pa10, FLAG_STRICT},
1596{ "cstws", 0x24001200, 0xfc00d200, "ucmcCt,5(b)", pa11, FLAG_STRICT},
1597{ "cstws", 0x24001200, 0xfc001200, "ucmcCt,5(s,b)", pa11, FLAG_STRICT},
1598{ "cstws", 0x24001200, 0xfc00de00, "ucMt,5(b)", pa10, 0},
1599{ "cstws", 0x24001200, 0xfc001e00, "ucMt,5(s,b)", pa10, 0},
1600{ "cstds", 0x2c001200, 0xfc00de00, "ucMt,5(b)", pa10, FLAG_STRICT},
1601{ "cstds", 0x2c001200, 0xfc001e00, "ucMt,5(s,b)", pa10, FLAG_STRICT},
1602{ "cstds", 0x2c001200, 0xfc00d200, "ucmcCt,5(b)", pa11, FLAG_STRICT},
1603{ "cstds", 0x2c001200, 0xfc001200, "ucmcCt,5(s,b)", pa11, FLAG_STRICT},
1604{ "cstds", 0x2c001200, 0xfc00de00, "ucMt,5(b)", pa10, 0},
1605{ "cstds", 0x2c001200, 0xfc001e00, "ucMt,5(s,b)", pa10, 0},
1606
1607/* More pseudo instructions which must follow the main table. */
1608{ "call", 0xe800f000, 0xfc1ffffd, "n(b)", pa20, FLAG_STRICT},
1609{ "call", 0xe800a000, 0xffe0e000, "nW", pa10, FLAG_STRICT},
1610{ "ret", 0xe840d000, 0xfffffffd, "n", pa20, FLAG_STRICT},
1611
Helge Deller1a724692024-02-02 11:08:57 +01001612/* Opcodes assigned to QEMU, used by SeaBIOS firmware and Linux kernel */
1613{ "HALT QEMU", 0xfffdead0, 0xfffffffd, "n", pa10, FLAG_STRICT},
1614{ "RESET QEMU", 0xfffdead1, 0xfffffffd, "n", pa10, FLAG_STRICT},
1615{ "RESTORE SHR",0xfffdead2, 0xfffffffd, "n", pa10, FLAG_STRICT},
Richard Henderson429b31a2016-09-29 10:55:53 -07001616};
1617
1618#define NUMOPCODES ((sizeof pa_opcodes)/(sizeof pa_opcodes[0]))
1619
1620/* SKV 12/18/92. Added some denotations for various operands. */
1621
1622#define PA_IMM11_AT_31 'i'
1623#define PA_IMM14_AT_31 'j'
1624#define PA_IMM21_AT_31 'k'
1625#define PA_DISP12 'w'
1626#define PA_DISP17 'W'
1627
1628#define N_HPPA_OPERAND_FORMATS 5
1629
1630/* Integer register names, indexed by the numbers which appear in the
1631 opcodes. */
1632static const char *const reg_names[] =
1633{
1634 "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
1635 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
1636 "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
1637 "sp", "r31"
1638};
1639
1640/* Floating point register names, indexed by the numbers which appear in the
1641 opcodes. */
1642static const char *const fp_reg_names[] =
1643{
1644 "fpsr", "fpe2", "fpe4", "fpe6",
1645 "fr4", "fr5", "fr6", "fr7", "fr8",
1646 "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
1647 "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
1648 "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"
1649};
1650
1651typedef unsigned int CORE_ADDR;
1652
1653/* Get at various relevant fields of an instruction word. */
1654
1655#define MASK_5 0x1f
1656#define MASK_10 0x3ff
1657#define MASK_11 0x7ff
1658#define MASK_14 0x3fff
1659#define MASK_16 0xffff
1660#define MASK_21 0x1fffff
1661
1662/* These macros get bit fields using HP's numbering (MSB = 0). */
1663
1664#define GET_FIELD(X, FROM, TO) \
1665 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
1666
1667#define GET_BIT(X, WHICH) \
1668 GET_FIELD (X, WHICH, WHICH)
1669
1670/* Some of these have been converted to 2-d arrays because they
1671 consume less storage this way. If the maintenance becomes a
1672 problem, convert them back to const 1-d pointer arrays. */
1673static const char *const control_reg[] =
1674{
1675 "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
1676 "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
1677 "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
1678 "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
1679 "tr4", "tr5", "tr6", "tr7"
1680};
1681
1682static const char *const compare_cond_names[] =
1683{
1684 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
1685 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
1686};
1687static const char *const compare_cond_64_names[] =
1688{
1689 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
1690 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
1691};
1692static const char *const cmpib_cond_64_names[] =
1693{
1694 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
1695};
1696static const char *const add_cond_names[] =
1697{
1698 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
1699 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
1700};
1701static const char *const add_cond_64_names[] =
1702{
1703 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
1704 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
1705};
1706static const char *const wide_add_cond_names[] =
1707{
1708 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
1709 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
1710};
1711static const char *const logical_cond_names[] =
1712{
1713 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
1714 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
1715static const char *const logical_cond_64_names[] =
1716{
1717 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
1718 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
1719static const char *const unit_cond_names[] =
1720{
1721 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
1722 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
1723};
1724static const char *const unit_cond_64_names[] =
1725{
1726 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
1727 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
1728};
1729static const char *const shift_cond_names[] =
1730{
1731 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
1732};
1733static const char *const shift_cond_64_names[] =
1734{
1735 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
1736};
1737static const char *const bb_cond_64_names[] =
1738{
1739 ",*<", ",*>="
1740};
1741static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
1742static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
1743static const char *const short_bytes_compl_names[] =
1744{
1745 "", ",b,m", ",e", ",e,m"
1746};
1747static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
1748static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
1749static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
1750static const char *const float_comp_names[] =
1751{
1752 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
1753 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
1754 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
1755 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
1756};
1757static const char *const signed_unsigned_names[] = {",u", ",s"};
1758static const char *const mix_half_names[] = {",l", ",r"};
1759static const char *const saturation_names[] = {",us", ",ss", 0, ""};
1760static const char *const read_write_names[] = {",r", ",w"};
1761static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
1762
1763/* For a bunch of different instructions form an index into a
1764 completer name table. */
1765#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
1766 GET_FIELD (insn, 18, 18) << 1)
1767
1768#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
1769 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
1770
1771/* Utility function to print registers. Put these first, so gcc's function
1772 inlining can do its stuff. */
1773
1774#define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
1775
1776static void
1777fput_reg (unsigned reg, disassemble_info *info)
1778{
1779 (*info->fprintf_func) (info->stream, "%s", reg ? reg_names[reg] : "r0");
1780}
1781
1782static void
1783fput_fp_reg (unsigned reg, disassemble_info *info)
1784{
1785 (*info->fprintf_func) (info->stream, "%s", reg ? fp_reg_names[reg] : "fr0");
1786}
1787
1788static void
1789fput_fp_reg_r (unsigned reg, disassemble_info *info)
1790{
1791 /* Special case floating point exception registers. */
1792 if (reg < 4)
1793 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
1794 else
Peter Maydell6815a8a2017-03-03 15:50:28 +00001795 (*info->fprintf_func) (info->stream, "%sR", fp_reg_names[reg]);
Richard Henderson429b31a2016-09-29 10:55:53 -07001796}
1797
1798static void
1799fput_creg (unsigned reg, disassemble_info *info)
1800{
1801 (*info->fprintf_func) (info->stream, "%s", control_reg[reg]);
1802}
1803
1804/* Print constants with sign. */
1805
1806static void
1807fput_const (unsigned num, disassemble_info *info)
1808{
1809 if ((int) num < 0)
1810 (*info->fprintf_func) (info->stream, "-%x", - (int) num);
1811 else
1812 (*info->fprintf_func) (info->stream, "%x", num);
1813}
1814
1815/* Routines to extract various sized constants out of hppa
1816 instructions. */
1817
1818/* Extract a 3-bit space register number from a be, ble, mtsp or mfsp. */
1819static int
1820extract_3 (unsigned word)
1821{
1822 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
1823}
1824
1825static int
1826extract_5_load (unsigned word)
1827{
1828 return low_sign_extend (word >> 16 & MASK_5, 5);
1829}
1830
1831/* Extract the immediate field from a st{bhw}s instruction. */
1832
1833static int
1834extract_5_store (unsigned word)
1835{
1836 return low_sign_extend (word & MASK_5, 5);
1837}
1838
1839/* Extract the immediate field from a break instruction. */
1840
1841static unsigned
1842extract_5r_store (unsigned word)
1843{
1844 return (word & MASK_5);
1845}
1846
1847/* Extract the immediate field from a {sr}sm instruction. */
1848
1849static unsigned
1850extract_5R_store (unsigned word)
1851{
1852 return (word >> 16 & MASK_5);
1853}
1854
1855/* Extract the 10 bit immediate field from a {sr}sm instruction. */
1856
1857static unsigned
1858extract_10U_store (unsigned word)
1859{
1860 return (word >> 16 & MASK_10);
1861}
1862
1863/* Extract the immediate field from a bb instruction. */
1864
1865static unsigned
1866extract_5Q_store (unsigned word)
1867{
1868 return (word >> 21 & MASK_5);
1869}
1870
1871/* Extract an 11 bit immediate field. */
1872
1873static int
1874extract_11 (unsigned word)
1875{
1876 return low_sign_extend (word & MASK_11, 11);
1877}
1878
1879/* Extract a 14 bit immediate field. */
1880
1881static int
1882extract_14 (unsigned word)
1883{
1884 return low_sign_extend (word & MASK_14, 14);
1885}
1886
1887/* Extract a 16 bit immediate field (PA2.0 wide only). */
1888
1889static int
1890extract_16 (unsigned word)
1891{
1892 int m15, m0, m1;
1893
1894 m0 = GET_BIT (word, 16);
1895 m1 = GET_BIT (word, 17);
1896 m15 = GET_BIT (word, 31);
1897 word = (word >> 1) & 0x1fff;
1898 word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
1899 return sign_extend (word, 16);
1900}
1901
1902/* Extract a 21 bit constant. */
1903
1904static int
1905extract_21 (unsigned word)
1906{
1907 int val;
1908
1909 word &= MASK_21;
1910 word <<= 11;
1911 val = GET_FIELD (word, 20, 20);
1912 val <<= 11;
1913 val |= GET_FIELD (word, 9, 19);
1914 val <<= 2;
1915 val |= GET_FIELD (word, 5, 6);
1916 val <<= 5;
1917 val |= GET_FIELD (word, 0, 4);
1918 val <<= 2;
1919 val |= GET_FIELD (word, 7, 8);
1920 return sign_extend (val, 21) << 11;
1921}
1922
1923/* Extract a 12 bit constant from branch instructions. */
1924
1925static int
1926extract_12 (unsigned word)
1927{
1928 return sign_extend (GET_FIELD (word, 19, 28)
1929 | GET_FIELD (word, 29, 29) << 10
1930 | (word & 0x1) << 11, 12) << 2;
1931}
1932
1933/* Extract a 17 bit constant from branch instructions, returning the
1934 19 bit signed value. */
1935
1936static int
1937extract_17 (unsigned word)
1938{
1939 return sign_extend (GET_FIELD (word, 19, 28)
1940 | GET_FIELD (word, 29, 29) << 10
1941 | GET_FIELD (word, 11, 15) << 11
1942 | (word & 0x1) << 16, 17) << 2;
1943}
1944
1945static int
1946extract_22 (unsigned word)
1947{
1948 return sign_extend (GET_FIELD (word, 19, 28)
1949 | GET_FIELD (word, 29, 29) << 10
1950 | GET_FIELD (word, 11, 15) << 11
1951 | GET_FIELD (word, 6, 10) << 16
1952 | (word & 0x1) << 21, 22) << 2;
1953}
1954
1955/* Print one instruction. */
1956
1957int
1958print_insn_hppa (bfd_vma memaddr, disassemble_info *info)
1959{
1960 bfd_byte buffer[4];
1961 unsigned int insn, i;
1962
1963 {
1964 int status =
1965 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
1966 if (status != 0)
1967 {
1968 (*info->memory_error_func) (status, memaddr, info);
1969 return -1;
1970 }
1971 }
1972
1973 insn = bfd_getb32 (buffer);
1974
Alex Bennée7cff1542024-03-05 12:10:03 +00001975 if (info->show_opcodes) {
1976 info->fprintf_func(info->stream, " %02x %02x %02x %02x ",
1977 (insn >> 24) & 0xff, (insn >> 16) & 0xff,
1978 (insn >> 8) & 0xff, insn & 0xff);
1979 }
Helge Deller2f926bf2023-11-17 11:26:02 +01001980
Richard Henderson429b31a2016-09-29 10:55:53 -07001981 for (i = 0; i < NUMOPCODES; ++i)
1982 {
1983 const struct pa_opcode *opcode = &pa_opcodes[i];
1984
1985 if ((insn & opcode->mask) == opcode->match)
1986 {
1987 const char *s;
1988#ifndef BFD64
1989 if (opcode->arch == pa20w)
1990 continue;
1991#endif
1992 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1993
1994 if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
1995 (*info->fprintf_func) (info->stream, " ");
1996 for (s = opcode->args; *s != '\0'; ++s)
1997 {
1998 switch (*s)
1999 {
2000 case 'x':
2001 fput_reg (GET_FIELD (insn, 11, 15), info);
2002 break;
2003 case 'a':
2004 case 'b':
2005 fput_reg (GET_FIELD (insn, 6, 10), info);
2006 break;
2007 case '^':
2008 fput_creg (GET_FIELD (insn, 6, 10), info);
2009 break;
2010 case 't':
2011 fput_reg (GET_FIELD (insn, 27, 31), info);
2012 break;
2013
2014 /* Handle floating point registers. */
2015 case 'f':
2016 switch (*++s)
2017 {
2018 case 't':
2019 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
2020 break;
2021 case 'T':
2022 if (GET_FIELD (insn, 25, 25))
2023 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
2024 else
2025 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
2026 break;
2027 case 'a':
2028 if (GET_FIELD (insn, 25, 25))
2029 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
2030 else
2031 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
2032 break;
2033
zhaolichang2dbb1302020-09-17 15:50:27 +08002034 /* 'fA' will not generate a space before the register
Richard Henderson429b31a2016-09-29 10:55:53 -07002035 name. Normally that is fine. Except that it
2036 causes problems with xmpyu which has no FP format
2037 completer. */
2038 case 'X':
2039 fputs_filtered (" ", info);
2040 /* FALLTHRU */
2041
2042 case 'A':
2043 if (GET_FIELD (insn, 24, 24))
2044 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
2045 else
2046 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
2047 break;
2048 case 'b':
2049 if (GET_FIELD (insn, 25, 25))
2050 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
2051 else
2052 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
2053 break;
2054 case 'B':
2055 if (GET_FIELD (insn, 19, 19))
2056 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
2057 else
2058 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
2059 break;
2060 case 'C':
2061 {
2062 int reg = GET_FIELD (insn, 21, 22);
2063 reg |= GET_FIELD (insn, 16, 18) << 2;
2064 if (GET_FIELD (insn, 23, 23) != 0)
2065 fput_fp_reg_r (reg, info);
2066 else
2067 fput_fp_reg (reg, info);
2068 break;
2069 }
2070 case 'i':
2071 {
2072 int reg = GET_FIELD (insn, 6, 10);
2073
2074 reg |= (GET_FIELD (insn, 26, 26) << 4);
2075 fput_fp_reg (reg, info);
2076 break;
2077 }
2078 case 'j':
2079 {
2080 int reg = GET_FIELD (insn, 11, 15);
2081
2082 reg |= (GET_FIELD (insn, 26, 26) << 4);
2083 fput_fp_reg (reg, info);
2084 break;
2085 }
2086 case 'k':
2087 {
2088 int reg = GET_FIELD (insn, 27, 31);
2089
2090 reg |= (GET_FIELD (insn, 26, 26) << 4);
2091 fput_fp_reg (reg, info);
2092 break;
2093 }
2094 case 'l':
2095 {
2096 int reg = GET_FIELD (insn, 21, 25);
2097
2098 reg |= (GET_FIELD (insn, 26, 26) << 4);
2099 fput_fp_reg (reg, info);
2100 break;
2101 }
2102 case 'm':
2103 {
2104 int reg = GET_FIELD (insn, 16, 20);
2105
2106 reg |= (GET_FIELD (insn, 26, 26) << 4);
2107 fput_fp_reg (reg, info);
2108 break;
2109 }
2110
2111 /* 'fe' will not generate a space before the register
2112 name. Normally that is fine. Except that it
2113 causes problems with fstw fe,y(b) which has no FP
2114 format completer. */
2115 case 'E':
2116 fputs_filtered (" ", info);
2117 /* FALLTHRU */
2118
2119 case 'e':
2120 if (GET_FIELD (insn, 30, 30))
2121 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
2122 else
2123 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
2124 break;
2125 case 'x':
2126 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
2127 break;
2128 }
2129 break;
2130
2131 case '5':
2132 fput_const (extract_5_load (insn), info);
2133 break;
2134 case 's':
2135 {
2136 int space = GET_FIELD (insn, 16, 17);
2137 /* Zero means implicit addressing, not use of sr0. */
2138 if (space != 0)
2139 (*info->fprintf_func) (info->stream, "sr%d", space);
2140 }
2141 break;
2142
2143 case 'S':
2144 (*info->fprintf_func) (info->stream, "sr%d",
2145 extract_3 (insn));
2146 break;
2147
2148 /* Handle completers. */
2149 case 'c':
2150 switch (*++s)
2151 {
2152 case 'x':
2153 (*info->fprintf_func)
2154 (info->stream, "%s",
2155 index_compl_names[GET_COMPL (insn)]);
2156 break;
2157 case 'X':
2158 (*info->fprintf_func)
2159 (info->stream, "%s ",
2160 index_compl_names[GET_COMPL (insn)]);
2161 break;
2162 case 'm':
2163 (*info->fprintf_func)
2164 (info->stream, "%s",
2165 short_ldst_compl_names[GET_COMPL (insn)]);
2166 break;
2167 case 'M':
2168 (*info->fprintf_func)
2169 (info->stream, "%s ",
2170 short_ldst_compl_names[GET_COMPL (insn)]);
2171 break;
2172 case 'A':
2173 (*info->fprintf_func)
2174 (info->stream, "%s ",
2175 short_bytes_compl_names[GET_COMPL (insn)]);
2176 break;
2177 case 's':
2178 (*info->fprintf_func)
2179 (info->stream, "%s",
2180 short_bytes_compl_names[GET_COMPL (insn)]);
2181 break;
2182 case 'c':
2183 case 'C':
2184 switch (GET_FIELD (insn, 20, 21))
2185 {
2186 case 1:
2187 (*info->fprintf_func) (info->stream, ",bc ");
2188 break;
2189 case 2:
2190 (*info->fprintf_func) (info->stream, ",sl ");
2191 break;
2192 default:
2193 (*info->fprintf_func) (info->stream, " ");
2194 }
2195 break;
2196 case 'd':
2197 switch (GET_FIELD (insn, 20, 21))
2198 {
2199 case 1:
2200 (*info->fprintf_func) (info->stream, ",co ");
2201 break;
2202 default:
2203 (*info->fprintf_func) (info->stream, " ");
2204 }
2205 break;
2206 case 'o':
2207 (*info->fprintf_func) (info->stream, ",o");
2208 break;
2209 case 'g':
2210 (*info->fprintf_func) (info->stream, ",gate");
2211 break;
2212 case 'p':
2213 (*info->fprintf_func) (info->stream, ",l,push");
2214 break;
2215 case 'P':
2216 (*info->fprintf_func) (info->stream, ",pop");
2217 break;
2218 case 'l':
2219 case 'L':
2220 (*info->fprintf_func) (info->stream, ",l");
2221 break;
2222 case 'w':
2223 (*info->fprintf_func)
2224 (info->stream, "%s ",
2225 read_write_names[GET_FIELD (insn, 25, 25)]);
2226 break;
2227 case 'W':
2228 (*info->fprintf_func) (info->stream, ",w ");
2229 break;
2230 case 'r':
2231 if (GET_FIELD (insn, 23, 26) == 5)
2232 (*info->fprintf_func) (info->stream, ",r");
2233 break;
2234 case 'Z':
2235 if (GET_FIELD (insn, 26, 26))
2236 (*info->fprintf_func) (info->stream, ",m ");
2237 else
2238 (*info->fprintf_func) (info->stream, " ");
2239 break;
2240 case 'i':
2241 if (GET_FIELD (insn, 25, 25))
2242 (*info->fprintf_func) (info->stream, ",i");
2243 break;
2244 case 'z':
2245 if (!GET_FIELD (insn, 21, 21))
2246 (*info->fprintf_func) (info->stream, ",z");
2247 break;
2248 case 'a':
2249 (*info->fprintf_func)
2250 (info->stream, "%s",
2251 add_compl_names[GET_FIELD (insn, 20, 21)]);
2252 break;
2253 case 'Y':
2254 (*info->fprintf_func)
2255 (info->stream, ",dc%s",
2256 add_compl_names[GET_FIELD (insn, 20, 21)]);
2257 break;
2258 case 'y':
2259 (*info->fprintf_func)
2260 (info->stream, ",c%s",
2261 add_compl_names[GET_FIELD (insn, 20, 21)]);
2262 break;
2263 case 'v':
2264 if (GET_FIELD (insn, 20, 20))
2265 (*info->fprintf_func) (info->stream, ",tsv");
2266 break;
2267 case 't':
2268 (*info->fprintf_func) (info->stream, ",tc");
2269 if (GET_FIELD (insn, 20, 20))
2270 (*info->fprintf_func) (info->stream, ",tsv");
2271 break;
2272 case 'B':
2273 (*info->fprintf_func) (info->stream, ",db");
2274 if (GET_FIELD (insn, 20, 20))
2275 (*info->fprintf_func) (info->stream, ",tsv");
2276 break;
2277 case 'b':
2278 (*info->fprintf_func) (info->stream, ",b");
2279 if (GET_FIELD (insn, 20, 20))
2280 (*info->fprintf_func) (info->stream, ",tsv");
2281 break;
2282 case 'T':
2283 if (GET_FIELD (insn, 25, 25))
2284 (*info->fprintf_func) (info->stream, ",tc");
2285 break;
2286 case 'S':
2287 /* EXTRD/W has a following condition. */
2288 if (*(s + 1) == '?')
2289 (*info->fprintf_func)
2290 (info->stream, "%s",
2291 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
2292 else
2293 (*info->fprintf_func)
2294 (info->stream, "%s ",
2295 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
2296 break;
2297 case 'h':
2298 (*info->fprintf_func)
2299 (info->stream, "%s",
2300 mix_half_names[GET_FIELD (insn, 17, 17)]);
2301 break;
2302 case 'H':
2303 (*info->fprintf_func)
2304 (info->stream, "%s ",
2305 saturation_names[GET_FIELD (insn, 24, 25)]);
2306 break;
2307 case '*':
2308 (*info->fprintf_func)
2309 (info->stream, ",%d%d%d%d ",
2310 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
2311 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
2312 break;
2313
2314 case 'q':
2315 {
2316 int m, a;
2317
2318 m = GET_FIELD (insn, 28, 28);
2319 a = GET_FIELD (insn, 29, 29);
2320
2321 if (m && !a)
2322 fputs_filtered (",ma ", info);
2323 else if (m && a)
2324 fputs_filtered (",mb ", info);
2325 else
2326 fputs_filtered (" ", info);
2327 break;
2328 }
2329
2330 case 'J':
2331 {
2332 int opc = GET_FIELD (insn, 0, 5);
2333
2334 if (opc == 0x16 || opc == 0x1e)
2335 {
2336 if (GET_FIELD (insn, 29, 29) == 0)
2337 fputs_filtered (",ma ", info);
2338 else
2339 fputs_filtered (",mb ", info);
2340 }
2341 else
2342 fputs_filtered (" ", info);
2343 break;
2344 }
2345
2346 case 'e':
2347 {
2348 int opc = GET_FIELD (insn, 0, 5);
2349
2350 if (opc == 0x13 || opc == 0x1b)
2351 {
2352 if (GET_FIELD (insn, 18, 18) == 1)
2353 fputs_filtered (",mb ", info);
2354 else
2355 fputs_filtered (",ma ", info);
2356 }
2357 else if (opc == 0x17 || opc == 0x1f)
2358 {
2359 if (GET_FIELD (insn, 31, 31) == 1)
2360 fputs_filtered (",ma ", info);
2361 else
2362 fputs_filtered (",mb ", info);
2363 }
2364 else
2365 fputs_filtered (" ", info);
2366
2367 break;
2368 }
2369 }
2370 break;
2371
2372 /* Handle conditions. */
2373 case '?':
2374 {
2375 s++;
2376 switch (*s)
2377 {
2378 case 'f':
2379 (*info->fprintf_func)
2380 (info->stream, "%s ",
2381 float_comp_names[GET_FIELD (insn, 27, 31)]);
2382 break;
2383
2384 /* These four conditions are for the set of instructions
2385 which distinguish true/false conditions by opcode
2386 rather than by the 'f' bit (sigh): comb, comib,
2387 addb, addib. */
2388 case 't':
2389 fputs_filtered
2390 (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
2391 break;
2392 case 'n':
2393 fputs_filtered
2394 (compare_cond_names[GET_FIELD (insn, 16, 18)
2395 + GET_FIELD (insn, 4, 4) * 8],
2396 info);
2397 break;
2398 case 'N':
2399 fputs_filtered
2400 (compare_cond_64_names[GET_FIELD (insn, 16, 18)
2401 + GET_FIELD (insn, 2, 2) * 8],
2402 info);
2403 break;
2404 case 'Q':
2405 fputs_filtered
2406 (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
2407 info);
2408 break;
2409 case '@':
2410 fputs_filtered
2411 (add_cond_names[GET_FIELD (insn, 16, 18)
2412 + GET_FIELD (insn, 4, 4) * 8],
2413 info);
2414 break;
2415 case 's':
2416 (*info->fprintf_func)
2417 (info->stream, "%s ",
2418 compare_cond_names[GET_COND (insn)]);
2419 break;
2420 case 'S':
2421 (*info->fprintf_func)
2422 (info->stream, "%s ",
2423 compare_cond_64_names[GET_COND (insn)]);
2424 break;
2425 case 'a':
2426 (*info->fprintf_func)
2427 (info->stream, "%s ",
2428 add_cond_names[GET_COND (insn)]);
2429 break;
2430 case 'A':
2431 (*info->fprintf_func)
2432 (info->stream, "%s ",
2433 add_cond_64_names[GET_COND (insn)]);
2434 break;
2435 case 'd':
2436 (*info->fprintf_func)
2437 (info->stream, "%s",
2438 add_cond_names[GET_FIELD (insn, 16, 18)]);
2439 break;
2440
2441 case 'W':
2442 (*info->fprintf_func)
2443 (info->stream, "%s",
2444 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
2445 GET_FIELD (insn, 4, 4) * 8]);
2446 break;
2447
2448 case 'l':
2449 (*info->fprintf_func)
2450 (info->stream, "%s ",
2451 logical_cond_names[GET_COND (insn)]);
2452 break;
2453 case 'L':
2454 (*info->fprintf_func)
2455 (info->stream, "%s ",
2456 logical_cond_64_names[GET_COND (insn)]);
2457 break;
2458 case 'u':
2459 (*info->fprintf_func)
2460 (info->stream, "%s ",
2461 unit_cond_names[GET_COND (insn)]);
2462 break;
2463 case 'U':
2464 (*info->fprintf_func)
2465 (info->stream, "%s ",
2466 unit_cond_64_names[GET_COND (insn)]);
2467 break;
2468 case 'y':
2469 case 'x':
2470 case 'b':
2471 (*info->fprintf_func)
2472 (info->stream, "%s",
2473 shift_cond_names[GET_FIELD (insn, 16, 18)]);
2474
2475 /* If the next character in args is 'n', it will handle
2476 putting out the space. */
2477 if (s[1] != 'n')
2478 (*info->fprintf_func) (info->stream, " ");
2479 break;
2480 case 'X':
2481 (*info->fprintf_func)
2482 (info->stream, "%s ",
2483 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
2484 break;
2485 case 'B':
2486 (*info->fprintf_func)
2487 (info->stream, "%s",
2488 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
2489
2490 /* If the next character in args is 'n', it will handle
2491 putting out the space. */
2492 if (s[1] != 'n')
2493 (*info->fprintf_func) (info->stream, " ");
2494 break;
2495 }
2496 break;
2497 }
2498
2499 case 'V':
2500 fput_const (extract_5_store (insn), info);
2501 break;
2502 case 'r':
2503 fput_const (extract_5r_store (insn), info);
2504 break;
2505 case 'R':
2506 fput_const (extract_5R_store (insn), info);
2507 break;
2508 case 'U':
2509 fput_const (extract_10U_store (insn), info);
2510 break;
2511 case 'B':
2512 case 'Q':
2513 fput_const (extract_5Q_store (insn), info);
2514 break;
2515 case 'i':
2516 fput_const (extract_11 (insn), info);
2517 break;
2518 case 'j':
2519 fput_const (extract_14 (insn), info);
2520 break;
2521 case 'k':
2522 fputs_filtered ("L%", info);
2523 fput_const (extract_21 (insn), info);
2524 break;
2525 case '<':
2526 case 'l':
2527 /* 16-bit long disp., PA2.0 wide only. */
2528 fput_const (extract_16 (insn), info);
2529 break;
2530 case 'n':
2531 if (insn & 0x2)
2532 (*info->fprintf_func) (info->stream, ",n ");
2533 else
2534 (*info->fprintf_func) (info->stream, " ");
2535 break;
2536 case 'N':
2537 if ((insn & 0x20) && s[1])
2538 (*info->fprintf_func) (info->stream, ",n ");
2539 else if (insn & 0x20)
2540 (*info->fprintf_func) (info->stream, ",n");
2541 else if (s[1])
2542 (*info->fprintf_func) (info->stream, " ");
2543 break;
2544 case 'w':
2545 (*info->print_address_func)
2546 (memaddr + 8 + extract_12 (insn), info);
2547 break;
2548 case 'W':
2549 /* 17 bit PC-relative branch. */
2550 (*info->print_address_func)
2551 ((memaddr + 8 + extract_17 (insn)), info);
2552 break;
2553 case 'z':
2554 /* 17 bit displacement. This is an offset from a register
2555 so it gets disasssembled as just a number, not any sort
2556 of address. */
2557 fput_const (extract_17 (insn), info);
2558 break;
2559
2560 case 'Z':
2561 /* addil %r1 implicit output. */
2562 fputs_filtered ("r1", info);
2563 break;
2564
2565 case 'Y':
2566 /* be,l %sr0,%r31 implicit output. */
2567 fputs_filtered ("sr0,r31", info);
2568 break;
2569
2570 case '@':
2571 (*info->fprintf_func) (info->stream, "0");
2572 break;
2573
2574 case '.':
2575 (*info->fprintf_func) (info->stream, "%d",
2576 GET_FIELD (insn, 24, 25));
2577 break;
2578 case '*':
2579 (*info->fprintf_func) (info->stream, "%d",
2580 GET_FIELD (insn, 22, 25));
2581 break;
2582 case '!':
2583 fputs_filtered ("sar", info);
2584 break;
2585 case 'p':
2586 (*info->fprintf_func) (info->stream, "%d",
2587 31 - GET_FIELD (insn, 22, 26));
2588 break;
2589 case '~':
2590 {
2591 int num;
2592 num = GET_FIELD (insn, 20, 20) << 5;
2593 num |= GET_FIELD (insn, 22, 26);
2594 (*info->fprintf_func) (info->stream, "%d", 63 - num);
2595 break;
2596 }
2597 case 'P':
2598 (*info->fprintf_func) (info->stream, "%d",
2599 GET_FIELD (insn, 22, 26));
2600 break;
2601 case 'q':
2602 {
2603 int num;
2604 num = GET_FIELD (insn, 20, 20) << 5;
2605 num |= GET_FIELD (insn, 22, 26);
2606 (*info->fprintf_func) (info->stream, "%d", num);
2607 break;
2608 }
2609 case 'T':
2610 (*info->fprintf_func) (info->stream, "%d",
2611 32 - GET_FIELD (insn, 27, 31));
2612 break;
2613 case '%':
2614 {
2615 int num;
2616 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
2617 num -= GET_FIELD (insn, 27, 31);
2618 (*info->fprintf_func) (info->stream, "%d", num);
2619 break;
2620 }
2621 case '|':
2622 {
2623 int num;
2624 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
2625 num -= GET_FIELD (insn, 27, 31);
2626 (*info->fprintf_func) (info->stream, "%d", num);
2627 break;
2628 }
2629 case '$':
2630 fput_const (GET_FIELD (insn, 20, 28), info);
2631 break;
2632 case 'A':
2633 fput_const (GET_FIELD (insn, 6, 18), info);
2634 break;
2635 case 'D':
2636 fput_const (GET_FIELD (insn, 6, 31), info);
2637 break;
2638 case 'v':
2639 (*info->fprintf_func) (info->stream, ",%d",
2640 GET_FIELD (insn, 23, 25));
2641 break;
2642 case 'O':
2643 fput_const ((GET_FIELD (insn, 6,20) << 5 |
2644 GET_FIELD (insn, 27, 31)), info);
2645 break;
2646 case 'o':
2647 fput_const (GET_FIELD (insn, 6, 20), info);
2648 break;
2649 case '2':
2650 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
2651 GET_FIELD (insn, 27, 31)), info);
2652 break;
2653 case '1':
2654 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
2655 GET_FIELD (insn, 27, 31)), info);
2656 break;
2657 case '0':
2658 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
2659 GET_FIELD (insn, 27, 31)), info);
2660 break;
2661 case 'u':
2662 (*info->fprintf_func) (info->stream, ",%d",
2663 GET_FIELD (insn, 23, 25));
2664 break;
2665 case 'F':
2666 /* If no destination completer and not before a completer
2667 for fcmp, need a space here. */
2668 if (s[1] == 'G' || s[1] == '?')
2669 fputs_filtered
2670 (float_format_names[GET_FIELD (insn, 19, 20)], info);
2671 else
2672 (*info->fprintf_func)
2673 (info->stream, "%s ",
2674 float_format_names[GET_FIELD (insn, 19, 20)]);
2675 break;
2676 case 'G':
2677 (*info->fprintf_func)
2678 (info->stream, "%s ",
2679 float_format_names[GET_FIELD (insn, 17, 18)]);
2680 break;
2681 case 'H':
2682 if (GET_FIELD (insn, 26, 26) == 1)
2683 (*info->fprintf_func) (info->stream, "%s ",
2684 float_format_names[0]);
2685 else
2686 (*info->fprintf_func) (info->stream, "%s ",
2687 float_format_names[1]);
2688 break;
2689 case 'I':
2690 /* If no destination completer and not before a completer
2691 for fcmp, need a space here. */
2692 if (s[1] == '?')
2693 fputs_filtered
2694 (float_format_names[GET_FIELD (insn, 20, 20)], info);
2695 else
2696 (*info->fprintf_func)
2697 (info->stream, "%s ",
2698 float_format_names[GET_FIELD (insn, 20, 20)]);
2699 break;
2700
2701 case 'J':
2702 fput_const (extract_14 (insn), info);
2703 break;
2704
2705 case '#':
2706 {
2707 int sign = GET_FIELD (insn, 31, 31);
2708 int imm10 = GET_FIELD (insn, 18, 27);
2709 int disp;
2710
2711 if (sign)
2712 disp = (-1 << 10) | imm10;
2713 else
2714 disp = imm10;
2715
2716 disp <<= 3;
2717 fput_const (disp, info);
2718 break;
2719 }
2720 case 'K':
2721 case 'd':
2722 {
2723 int sign = GET_FIELD (insn, 31, 31);
2724 int imm11 = GET_FIELD (insn, 18, 28);
2725 int disp;
2726
2727 if (sign)
2728 disp = (-1 << 11) | imm11;
2729 else
2730 disp = imm11;
2731
2732 disp <<= 2;
2733 fput_const (disp, info);
2734 break;
2735 }
2736
2737 case '>':
2738 case 'y':
2739 {
2740 /* 16-bit long disp., PA2.0 wide only. */
2741 int disp = extract_16 (insn);
2742 disp &= ~3;
2743 fput_const (disp, info);
2744 break;
2745 }
2746
2747 case '&':
2748 {
2749 /* 16-bit long disp., PA2.0 wide only. */
2750 int disp = extract_16 (insn);
2751 disp &= ~7;
2752 fput_const (disp, info);
2753 break;
2754 }
2755
2756 case '_':
2757 break; /* Dealt with by '{' */
2758
2759 case '{':
2760 {
2761 int sub = GET_FIELD (insn, 14, 16);
2762 int df = GET_FIELD (insn, 17, 18);
2763 int sf = GET_FIELD (insn, 19, 20);
2764 const char * const * source = float_format_names;
2765 const char * const * dest = float_format_names;
2766 const char *t = "";
2767
2768 if (sub == 4)
2769 {
2770 fputs_filtered (",UND ", info);
2771 break;
2772 }
2773 if ((sub & 3) == 3)
2774 t = ",t";
2775 if ((sub & 3) == 1)
2776 source = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
2777 if (sub & 2)
2778 dest = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
2779
2780 (*info->fprintf_func) (info->stream, "%s%s%s ",
2781 t, source[sf], dest[df]);
2782 break;
2783 }
2784
2785 case 'm':
2786 {
2787 int y = GET_FIELD (insn, 16, 18);
2788
2789 if (y != 1)
2790 fput_const ((y ^ 1) - 1, info);
2791 }
2792 break;
2793
2794 case 'h':
2795 {
2796 int cbit;
2797
2798 cbit = GET_FIELD (insn, 16, 18);
2799
2800 if (cbit > 0)
2801 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
2802 break;
2803 }
2804
2805 case '=':
2806 {
2807 int cond = GET_FIELD (insn, 27, 31);
2808
2809 switch (cond)
2810 {
2811 case 0: fputs_filtered (" ", info); break;
2812 case 1: fputs_filtered ("acc ", info); break;
2813 case 2: fputs_filtered ("rej ", info); break;
2814 case 5: fputs_filtered ("acc8 ", info); break;
2815 case 6: fputs_filtered ("rej8 ", info); break;
2816 case 9: fputs_filtered ("acc6 ", info); break;
2817 case 13: fputs_filtered ("acc4 ", info); break;
2818 case 17: fputs_filtered ("acc2 ", info); break;
2819 default: break;
2820 }
2821 break;
2822 }
2823
2824 case 'X':
2825 (*info->print_address_func)
2826 (memaddr + 8 + extract_22 (insn), info);
2827 break;
2828 case 'L':
2829 fputs_filtered (",rp", info);
2830 break;
2831 default:
2832 (*info->fprintf_func) (info->stream, "%c", *s);
2833 break;
2834 }
2835 }
2836 return sizeof (insn);
2837 }
2838 }
Helge Deller2f926bf2023-11-17 11:26:02 +01002839 info->fprintf_func(info->stream, "<unknown>");
Richard Henderson429b31a2016-09-29 10:55:53 -07002840 return sizeof (insn);
2841}