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