Commit f54b3f920f12fb4fb41e259f793a853860a7d2ec

Authored by aurel32
1 parent 339dea27

HPPA (PA-RISC) host support

(Stuart Brady)


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