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