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,6 +128,11 @@ ifeq ($(ARCH),alpha)
128 CFLAGS+=-msmall-data 128 CFLAGS+=-msmall-data
129 endif 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 ifeq ($(ARCH),ia64) 136 ifeq ($(ARCH),ia64)
132 CFLAGS+=-mno-sdata 137 CFLAGS+=-mno-sdata
133 OP_CFLAGS+=-mno-sdata 138 OP_CFLAGS+=-mno-sdata
@@ -267,6 +272,9 @@ endif @@ -267,6 +272,9 @@ endif
267 ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4) 272 ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
268 LIBOBJS+=sh4-dis.o 273 LIBOBJS+=sh4-dis.o
269 endif 274 endif
  275 +ifeq ($(findstring hppa, $(TARGET_BASE_ARCH) $(ARCH)),hppa)
  276 +LIBOBJS+=hppa-dis.o
  277 +endif
270 ifeq ($(findstring s390, $(TARGET_ARCH) $(ARCH)),s390) 278 ifeq ($(findstring s390, $(TARGET_ARCH) $(ARCH)),s390)
271 LIBOBJS+=s390-dis.o 279 LIBOBJS+=s390-dis.o
272 endif 280 endif
configure
@@ -50,6 +50,9 @@ case "$cpu" in @@ -50,6 +50,9 @@ case "$cpu" in
50 cris) 50 cris)
51 cpu="cris" 51 cpu="cris"
52 ;; 52 ;;
  53 + parisc|parisc64)
  54 + cpu="hppa"
  55 + ;;
53 ia64) 56 ia64)
54 cpu="ia64" 57 cpu="ia64"
55 ;; 58 ;;
@@ -576,6 +579,7 @@ else @@ -576,6 +579,7 @@ else
576 579
577 # if cross compiling, cannot launch a program, so make a static guess 580 # if cross compiling, cannot launch a program, so make a static guess
578 if test "$cpu" = "armv4b" \ 581 if test "$cpu" = "armv4b" \
  582 + -o "$cpu" = "hppa" \
579 -o "$cpu" = "m68k" \ 583 -o "$cpu" = "m68k" \
580 -o "$cpu" = "mips" \ 584 -o "$cpu" = "mips" \
581 -o "$cpu" = "mips64" \ 585 -o "$cpu" = "mips64" \
@@ -865,6 +869,9 @@ elif test "$cpu" = "armv4l" ; then @@ -865,6 +869,9 @@ elif test "$cpu" = "armv4l" ; then
865 elif test "$cpu" = "cris" ; then 869 elif test "$cpu" = "cris" ; then
866 echo "ARCH=cris" >> $config_mak 870 echo "ARCH=cris" >> $config_mak
867 echo "#define HOST_CRIS 1" >> $config_h 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 elif test "$cpu" = "ia64" ; then 875 elif test "$cpu" = "ia64" ; then
869 echo "ARCH=ia64" >> $config_mak 876 echo "ARCH=ia64" >> $config_mak
870 echo "#define HOST_IA64 1" >> $config_h 877 echo "#define HOST_IA64 1" >> $config_h
cpu-all.h
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 #ifndef CPU_ALL_H 20 #ifndef CPU_ALL_H
21 #define CPU_ALL_H 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 #define WORDS_ALIGNED 24 #define WORDS_ALIGNED
25 #endif 25 #endif
26 26
@@ -952,6 +952,15 @@ static inline int64_t cpu_get_real_ticks(void) @@ -952,6 +952,15 @@ static inline int64_t cpu_get_real_ticks(void)
952 return val; 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 #elif defined(__ia64) 964 #elif defined(__ia64)
956 965
957 static inline int64_t cpu_get_real_ticks(void) 966 static inline int64_t cpu_get_real_ticks(void)
cpu-exec.c
@@ -657,6 +657,17 @@ int cpu_exec(CPUState *env1) @@ -657,6 +657,17 @@ int cpu_exec(CPUState *env1)
657 "o0", "o1", "o2", "o3", "o4", "o5", 657 "o0", "o1", "o2", "o3", "o4", "o5",
658 "l0", "l1", "l2", "l3", "l4", "l5", 658 "l0", "l1", "l2", "l3", "l4", "l5",
659 "l6", "l7"); 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 #elif defined(__arm__) 671 #elif defined(__arm__)
661 asm volatile ("mov pc, %0\n\t" 672 asm volatile ("mov pc, %0\n\t"
662 ".global exec_loop\n\t" 673 ".global exec_loop\n\t"
@@ -1488,6 +1499,24 @@ int cpu_signal_handler(int host_signum, void *pinfo, @@ -1488,6 +1499,24 @@ int cpu_signal_handler(int host_signum, void *pinfo,
1488 is_write, &uc->uc_sigmask, puc); 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 #else 1520 #else
1492 1521
1493 #error host CPU specific signal handler needed 1522 #error host CPU specific signal handler needed
dis-asm.h
@@ -157,6 +157,10 @@ enum bfd_architecture @@ -157,6 +157,10 @@ enum bfd_architecture
157 #define bfd_mach_ppc_7400 7400 157 #define bfd_mach_ppc_7400 7400
158 bfd_arch_rs6000, /* IBM RS/6000 */ 158 bfd_arch_rs6000, /* IBM RS/6000 */
159 bfd_arch_hppa, /* HP PA RISC */ 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 bfd_arch_d10v, /* Mitsubishi D10V */ 164 bfd_arch_d10v, /* Mitsubishi D10V */
161 bfd_arch_z8k, /* Zilog Z8000 */ 165 bfd_arch_z8k, /* Zilog Z8000 */
162 #define bfd_mach_z8001 1 166 #define bfd_mach_z8001 1
@@ -279,6 +279,8 @@ void disas(FILE *out, void *code, unsigned long size) @@ -279,6 +279,8 @@ void disas(FILE *out, void *code, unsigned long size)
279 print_insn = print_insn_m68k; 279 print_insn = print_insn_m68k;
280 #elif defined(__s390__) 280 #elif defined(__s390__)
281 print_insn = print_insn_s390; 281 print_insn = print_insn_s390;
  282 +#elif defined(__hppa__)
  283 + print_insn = print_insn_hppa;
282 #else 284 #else
283 fprintf(out, "0x%lx: Asm output not supported on this arch\n", 285 fprintf(out, "0x%lx: Asm output not supported on this arch\n",
284 (long) code); 286 (long) code);
dyngen-exec.h
@@ -124,6 +124,11 @@ extern int printf(const char *, ...); @@ -124,6 +124,11 @@ extern int printf(const char *, ...);
124 #define AREG1 "r4" 124 #define AREG1 "r4"
125 #define AREG2 "r5" 125 #define AREG2 "r5"
126 #define AREG3 "r6" 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 #elif defined(__mips__) 132 #elif defined(__mips__)
128 #define AREG0 "fp" 133 #define AREG0 "fp"
129 #define AREG1 "s0" 134 #define AREG1 "s0"
@@ -279,6 +284,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; @@ -279,6 +284,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
279 #elif defined(__mips__) 284 #elif defined(__mips__)
280 #define EXIT_TB() asm volatile ("jr $ra") 285 #define EXIT_TB() asm volatile ("jr $ra")
281 #define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at") 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 #else 289 #else
283 #error unsupported CPU 290 #error unsupported CPU
284 #endif 291 #endif
dyngen.c
@@ -117,6 +117,13 @@ @@ -117,6 +117,13 @@
117 #define elf_check_arch(x) ((x) == EM_68K) 117 #define elf_check_arch(x) ((x) == EM_68K)
118 #define ELF_USES_RELOCA 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 #elif defined(HOST_MIPS) 127 #elif defined(HOST_MIPS)
121 128
122 #define ELF_CLASS ELFCLASS32 129 #define ELF_CLASS ELFCLASS32
@@ -1223,7 +1230,7 @@ int get_reloc_expr(char *name, int name_size, const char *sym_name) @@ -1223,7 +1230,7 @@ int get_reloc_expr(char *name, int name_size, const char *sym_name)
1223 snprintf(name, name_size, "param%s", p); 1230 snprintf(name, name_size, "param%s", p);
1224 return 1; 1231 return 1;
1225 } else { 1232 } else {
1226 -#ifdef HOST_SPARC 1233 +#if defined(HOST_SPARC) || defined(HOST_HPPA)
1227 if (sym_name[0] == '.') 1234 if (sym_name[0] == '.')
1228 snprintf(name, name_size, 1235 snprintf(name, name_size,
1229 "(long)(&__dot_%s)", 1236 "(long)(&__dot_%s)",
@@ -1661,6 +1668,43 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1661,6 +1668,43 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1661 error("rts expected at the end of %s", name); 1668 error("rts expected at the end of %s", name);
1662 copy_size = p - p_start; 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 #elif defined(HOST_MIPS) || defined(HOST_MIPS64) 1708 #elif defined(HOST_MIPS) || defined(HOST_MIPS64)
1665 { 1709 {
1666 #define INSN_RETURN 0x03e00008 1710 #define INSN_RETURN 0x03e00008
@@ -1746,7 +1790,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1746,7 +1790,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1746 !strstart(sym_name, "__op_param", NULL) && 1790 !strstart(sym_name, "__op_param", NULL) &&
1747 !strstart(sym_name, "__op_jmp", NULL) && 1791 !strstart(sym_name, "__op_jmp", NULL) &&
1748 !strstart(sym_name, "__op_gen_label", NULL)) { 1792 !strstart(sym_name, "__op_gen_label", NULL)) {
1749 -#if defined(HOST_SPARC) 1793 +#if defined(HOST_SPARC) || defined(HOST_HPPA)
1750 if (sym_name[0] == '.') { 1794 if (sym_name[0] == '.') {
1751 fprintf(outfile, 1795 fprintf(outfile,
1752 "extern char __dot_%s __asm__(\"%s\");\n", 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,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 fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", 1825 fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n",
1778 name, (int)(start_offset - offset), copy_size); 1826 name, (int)(start_offset - offset), copy_size);
  1827 +#endif
1779 1828
1780 /* emit code offset information */ 1829 /* emit code offset information */
1781 { 1830 {
@@ -2581,6 +2630,82 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -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 #elif defined(HOST_MIPS) || defined(HOST_MIPS64) 2709 #elif defined(HOST_MIPS) || defined(HOST_MIPS64)
2585 { 2710 {
2586 for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) { 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,8 +47,9 @@ const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX
47 const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX }; 47 const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
48 48
49 static void patch_reloc(uint8_t *code_ptr, int type, 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 switch(type) { 53 switch(type) {
53 case R_386_32: 54 case R_386_32:
54 *(uint32_t *)code_ptr = value; 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,8 +88,9 @@ static const int tcg_target_call_oarg_regs[2] = {
88 }; 88 };
89 89
90 static void patch_reloc(uint8_t *code_ptr, int type, 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 switch (type) { 94 switch (type) {
94 case R_SPARC_32: 95 case R_SPARC_32:
95 if (value != (uint32_t)value) 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,10 +465,55 @@ static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
465 #endif 465 #endif
466 466
467 #ifndef CONFIG_NO_DYNGEN_OP 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 const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr) 509 const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr)
469 { 510 {
470 uint8_t *gen_code_ptr; 511 uint8_t *gen_code_ptr;
471 512
  513 +#ifdef __hppa__
  514 + struct hppa_branch_stub *hppa_stubs = NULL;
  515 +#endif
  516 +
472 gen_code_ptr = s->code_ptr; 517 gen_code_ptr = s->code_ptr;
473 switch(opc) { 518 switch(opc) {
474 519
@@ -478,6 +523,11 @@ const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr) @@ -478,6 +523,11 @@ const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr)
478 default: 523 default:
479 tcg_abort(); 524 tcg_abort();
480 } 525 }
  526 +
  527 +#ifdef __hppa__
  528 + hppa_process_stubs(hppa_stubs, &gen_code_ptr);
  529 +#endif
  530 +
481 s->code_ptr = gen_code_ptr; 531 s->code_ptr = gen_code_ptr;
482 return opparam_ptr; 532 return opparam_ptr;
483 } 533 }
tcg/tcg.c
@@ -53,7 +53,7 @@ @@ -53,7 +53,7 @@
53 53
54 54
55 static void patch_reloc(uint8_t *code_ptr, int type, 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 TCGOpDef tcg_op_defs[] = { 58 TCGOpDef tcg_op_defs[] = {
59 #define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size }, 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,7 +100,7 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
100 /* FIXME: This may break relocations on RISC targets that 100 /* FIXME: This may break relocations on RISC targets that
101 modify instruction fields in place. The caller may not have 101 modify instruction fields in place. The caller may not have
102 written the initial value. */ 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 } else { 104 } else {
105 /* add a new relocation entry */ 105 /* add a new relocation entry */
106 r = tcg_malloc(sizeof(TCGRelocation)); 106 r = tcg_malloc(sizeof(TCGRelocation));
@@ -123,7 +123,7 @@ static void tcg_out_label(TCGContext *s, int label_index, @@ -123,7 +123,7 @@ static void tcg_out_label(TCGContext *s, int label_index,
123 tcg_abort(); 123 tcg_abort();
124 r = l->u.first_reloc; 124 r = l->u.first_reloc;
125 while (r != NULL) { 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 r = r->next; 127 r = r->next;
128 } 128 }
129 l->has_value = 1; 129 l->has_value = 1;
@@ -1442,7 +1442,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, @@ -1442,7 +1442,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1442 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; 1442 int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1443 TCGArg arg, func_arg; 1443 TCGArg arg, func_arg;
1444 TCGTemp *ts; 1444 TCGTemp *ts;
1445 - tcg_target_long stack_offset, call_stack_size; 1445 + tcg_target_long stack_offset, call_stack_size, func_addr;
1446 int const_func_arg; 1446 int const_func_arg;
1447 TCGRegSet allocated_regs; 1447 TCGRegSet allocated_regs;
1448 const TCGArgConstraint *arg_ct; 1448 const TCGArgConstraint *arg_ct;
@@ -1464,7 +1464,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, @@ -1464,7 +1464,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1464 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); 1464 call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
1465 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 1465 call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
1466 ~(TCG_TARGET_STACK_ALIGN - 1); 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 tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size); 1470 tcg_out_addi(s, TCG_REG_CALL_STACK, -call_stack_size);
  1471 +#endif
1468 1472
1469 stack_offset = 0; 1473 stack_offset = 0;
1470 for(i = nb_regs; i < nb_params; i++) { 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,7 +1491,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1487 } else { 1491 } else {
1488 tcg_abort(); 1492 tcg_abort();
1489 } 1493 }
  1494 +#ifdef TCG_TARGET_STACK_GROWSUP
  1495 + stack_offset -= sizeof(tcg_target_long);
  1496 +#else
1490 stack_offset += sizeof(tcg_target_long); 1497 stack_offset += sizeof(tcg_target_long);
  1498 +#endif
1491 } 1499 }
1492 1500
1493 /* assign input registers */ 1501 /* assign input registers */
@@ -1516,6 +1524,10 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, @@ -1516,6 +1524,10 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1516 func_arg = args[nb_oargs + nb_iargs - 1]; 1524 func_arg = args[nb_oargs + nb_iargs - 1];
1517 arg_ct = &def->args_ct[0]; 1525 arg_ct = &def->args_ct[0];
1518 ts = &s->temps[func_arg]; 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 const_func_arg = 0; 1531 const_func_arg = 0;
1520 if (ts->val_type == TEMP_VAL_MEM) { 1532 if (ts->val_type == TEMP_VAL_MEM) {
1521 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 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,12 +1541,12 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1529 } 1541 }
1530 func_arg = reg; 1542 func_arg = reg;
1531 } else if (ts->val_type == TEMP_VAL_CONST) { 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 const_func_arg = 1; 1545 const_func_arg = 1;
1534 - func_arg = ts->val; 1546 + func_arg = func_addr;
1535 } else { 1547 } else {
1536 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 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 func_arg = reg; 1550 func_arg = reg;
1539 } 1551 }
1540 } else { 1552 } else {
@@ -1574,7 +1586,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, @@ -1574,7 +1586,11 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1574 1586
1575 tcg_out_op(s, opc, &func_arg, &const_func_arg); 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 tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size); 1592 tcg_out_addi(s, TCG_REG_CALL_STACK, call_stack_size);
  1593 +#endif
1578 1594
1579 /* assign output registers and emit moves if needed */ 1595 /* assign output registers and emit moves if needed */
1580 for(i = 0; i < nb_oargs; i++) { 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,8 +74,9 @@ const int tcg_target_call_oarg_regs[2] = {
74 }; 74 };
75 75
76 static void patch_reloc(uint8_t *code_ptr, int type, 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 switch(type) { 80 switch(type) {
80 case R_X86_64_32: 81 case R_X86_64_32:
81 if (value != (uint32_t)value) 82 if (value != (uint32_t)value)