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