diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-09-17 16:24:48 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-09-17 16:24:48 +0100 |
commit | 4f2058ded4feb2fa815b33b57b305c81d5016307 (patch) | |
tree | 7be54b2c17c07c8e97573ed018e805014143f52a | |
parent | 5ee53d1593dfc071275b13b1228c70bb88f4aaee (diff) | |
parent | 89b2e37e6506d92b00ac478e7953be6ddd7a86a9 (diff) |
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20170917' into staging
tcg queued patches
# gpg: Signature made Sun 17 Sep 2017 16:03:28 BST
# gpg: using RSA key 0x64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* remotes/rth/tags/pull-tcg-20170917:
tcg/mips: Fully convert tcg_target_op_def
tcg/sparc: Fully convert tcg_target_op_def
tcg/ppc: Fully convert tcg_target_op_def
tcg/arm: Fully convert tcg_target_op_def
tcg/aarch64: Fully convert tcg_target_op_def
tcg: Fix types in tcg_regset_{set,reset}_reg
tcg: Remove tcg_regset_set32
tcg: Remove tcg_regset_{or,and,andnot,not}
tcg: Remove tcg_regset_set
tcg: Remove tcg_regset_clear
tcg: Add tcg_op_supported
accel/tcg: move USER code to user-exec.c
accel/tcg: move atomic_template.h to accel/tcg/
accel/tcg: move tcg-runtime to accel/tcg/
accel/tcg: move user-exec to accel/tcg/
accel/tcg: move softmmu_template.h to accel/tcg/
tcg/ppc: disable atomic write check on ppc32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | Makefile.target | 6 | ||||
-rw-r--r-- | accel/tcg/Makefile.objs | 4 | ||||
-rw-r--r-- | accel/tcg/atomic_template.h (renamed from atomic_template.h) | 0 | ||||
-rw-r--r-- | accel/tcg/softmmu_template.h (renamed from softmmu_template.h) | 0 | ||||
-rw-r--r-- | accel/tcg/tcg-runtime.c (renamed from tcg/tcg-runtime.c) | 54 | ||||
-rw-r--r-- | accel/tcg/tcg-runtime.h (renamed from tcg/tcg-runtime.h) | 0 | ||||
-rw-r--r-- | accel/tcg/user-exec-stub.c (renamed from user-exec-stub.c) | 0 | ||||
-rw-r--r-- | accel/tcg/user-exec.c (renamed from user-exec.c) | 52 | ||||
-rw-r--r-- | tcg/aarch64/tcg-target.inc.c | 319 | ||||
-rw-r--r-- | tcg/arm/tcg-target.inc.c | 211 | ||||
-rw-r--r-- | tcg/i386/tcg-target.inc.c | 30 | ||||
-rw-r--r-- | tcg/mips/tcg-target.inc.c | 371 | ||||
-rw-r--r-- | tcg/ppc/tcg-target.inc.c | 366 | ||||
-rw-r--r-- | tcg/s390/tcg-target.inc.c | 22 | ||||
-rw-r--r-- | tcg/sparc/tcg-target.inc.c | 291 | ||||
-rw-r--r-- | tcg/tcg.c | 242 | ||||
-rw-r--r-- | tcg/tcg.h | 15 | ||||
-rw-r--r-- | tcg/tci/tcg-target.inc.c | 13 |
19 files changed, 1160 insertions, 840 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2c333aba21..4bd1797330 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -86,7 +86,6 @@ M: Richard Henderson <rth@twiddle.net> S: Maintained F: cpus.c F: exec.c -F: softmmu_template.h F: accel/tcg/ F: include/exec/cpu*.h F: include/exec/exec-all.h @@ -1604,8 +1603,7 @@ Overall M: Riku Voipio <riku.voipio@iki.fi> S: Maintained F: thunk.c -F: user-exec.c -F: user-exec-stub.c +F: accel/tcg/user-exec*.c BSD user S: Orphan diff --git a/Makefile.target b/Makefile.target index 7f42c45db8..6361f957fb 100644 --- a/Makefile.target +++ b/Makefile.target @@ -94,7 +94,7 @@ all: $(PROGS) stap obj-y += exec.o obj-y += accel/ obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o -obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/tcg-runtime.o +obj-$(CONFIG_TCG) += tcg/tcg-common.o obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-y += fpu/softfloat.o @@ -119,7 +119,7 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \ -I$(SRC_PATH)/linux-user obj-y += linux-user/ -obj-y += gdbstub.o thunk.o user-exec.o user-exec-stub.o +obj-y += gdbstub.o thunk.o endif #CONFIG_LINUX_USER @@ -132,7 +132,7 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \ -I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR) obj-y += bsd-user/ -obj-y += gdbstub.o user-exec.o user-exec-stub.o +obj-y += gdbstub.o endif #CONFIG_BSD_USER diff --git a/accel/tcg/Makefile.objs b/accel/tcg/Makefile.objs index 22642e6f75..228cd84fa4 100644 --- a/accel/tcg/Makefile.objs +++ b/accel/tcg/Makefile.objs @@ -1,4 +1,8 @@ obj-$(CONFIG_SOFTMMU) += tcg-all.o obj-$(CONFIG_SOFTMMU) += cputlb.o +obj-y += tcg-runtime.o obj-y += cpu-exec.o cpu-exec-common.o translate-all.o obj-y += translator.o + +obj-$(CONFIG_USER_ONLY) += user-exec.o +obj-$(call lnot,$(CONFIG_SOFTMMU)) += user-exec-stub.o diff --git a/atomic_template.h b/accel/tcg/atomic_template.h index b400b2a3d3..b400b2a3d3 100644 --- a/atomic_template.h +++ b/accel/tcg/atomic_template.h diff --git a/softmmu_template.h b/accel/tcg/softmmu_template.h index d7563292a5..d7563292a5 100644 --- a/softmmu_template.h +++ b/accel/tcg/softmmu_template.h diff --git a/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c index 3e23649dd7..aafb171294 100644 --- a/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c @@ -178,57 +178,3 @@ void HELPER(exit_atomic)(CPUArchState *env) { cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); } - -#ifndef CONFIG_SOFTMMU -/* The softmmu versions of these helpers are in cputlb.c. */ - -/* Do not allow unaligned operations to proceed. Return the host address. */ -static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr, - int size, uintptr_t retaddr) -{ - /* Enforce qemu required alignment. */ - if (unlikely(addr & (size - 1))) { - cpu_loop_exit_atomic(ENV_GET_CPU(env), retaddr); - } - return g2h(addr); -} - -/* Macro to call the above, with local variables from the use context. */ -#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC()) - -#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END)) -#define EXTRA_ARGS - -#define DATA_SIZE 1 -#include "atomic_template.h" - -#define DATA_SIZE 2 -#include "atomic_template.h" - -#define DATA_SIZE 4 -#include "atomic_template.h" - -#ifdef CONFIG_ATOMIC64 -#define DATA_SIZE 8 -#include "atomic_template.h" -#endif - -/* The following is only callable from other helpers, and matches up - with the softmmu version. */ - -#ifdef CONFIG_ATOMIC128 - -#undef EXTRA_ARGS -#undef ATOMIC_NAME -#undef ATOMIC_MMU_LOOKUP - -#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr -#define ATOMIC_NAME(X) \ - HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu)) -#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr) - -#define DATA_SIZE 16 -#include "atomic_template.h" -#endif /* CONFIG_ATOMIC128 */ - -#endif /* !CONFIG_SOFTMMU */ diff --git a/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h index c41d38a557..c41d38a557 100644 --- a/tcg/tcg-runtime.h +++ b/accel/tcg/tcg-runtime.h diff --git a/user-exec-stub.c b/accel/tcg/user-exec-stub.c index dbcf1ade9c..dbcf1ade9c 100644 --- a/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c diff --git a/user-exec.c b/accel/tcg/user-exec.c index 2a975eaf69..492ea0826c 100644 --- a/user-exec.c +++ b/accel/tcg/user-exec.c @@ -24,6 +24,7 @@ #include "qemu/bitops.h" #include "exec/cpu_ldst.h" #include "translate-all.h" +#include "exec/helper-proto.h" #undef EAX #undef ECX @@ -573,3 +574,54 @@ int cpu_signal_handler(int host_signum, void *pinfo, #error host CPU specific signal handler needed #endif + +/* The softmmu versions of these helpers are in cputlb.c. */ + +/* Do not allow unaligned operations to proceed. Return the host address. */ +static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr, + int size, uintptr_t retaddr) +{ + /* Enforce qemu required alignment. */ + if (unlikely(addr & (size - 1))) { + cpu_loop_exit_atomic(ENV_GET_CPU(env), retaddr); + } + return g2h(addr); +} + +/* Macro to call the above, with local variables from the use context. */ +#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC()) + +#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END)) +#define EXTRA_ARGS + +#define DATA_SIZE 1 +#include "atomic_template.h" + +#define DATA_SIZE 2 +#include "atomic_template.h" + +#define DATA_SIZE 4 +#include "atomic_template.h" + +#ifdef CONFIG_ATOMIC64 +#define DATA_SIZE 8 +#include "atomic_template.h" +#endif + +/* The following is only callable from other helpers, and matches up + with the softmmu version. */ + +#ifdef CONFIG_ATOMIC128 + +#undef EXTRA_ARGS +#undef ATOMIC_NAME +#undef ATOMIC_MMU_LOOKUP + +#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr +#define ATOMIC_NAME(X) \ + HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu)) +#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr) + +#define DATA_SIZE 16 +#include "atomic_template.h" +#endif /* CONFIG_ATOMIC128 */ diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c index c2f3812214..150530f30e 100644 --- a/tcg/aarch64/tcg-target.inc.c +++ b/tcg/aarch64/tcg-target.inc.c @@ -121,11 +121,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, switch (*ct_str++) { case 'r': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1); + ct->u.regs = 0xffffffffu; break; case 'l': /* qemu_ld / qemu_st address, data_reg */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1); + ct->u.regs = 0xffffffffu; #ifdef CONFIG_SOFTMMU /* x0 and x1 will be overwritten when reading the tlb entry, and x2, and x3 for helper args, better to avoid using them. */ @@ -1786,161 +1786,182 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, #undef REG0 } -static const TCGTargetOpDef aarch64_op_defs[] = { - { INDEX_op_exit_tb, { } }, - { INDEX_op_goto_tb, { } }, - { INDEX_op_br, { } }, - { INDEX_op_goto_ptr, { "r" } }, - - { INDEX_op_ld8u_i32, { "r", "r" } }, - { INDEX_op_ld8s_i32, { "r", "r" } }, - { INDEX_op_ld16u_i32, { "r", "r" } }, - { INDEX_op_ld16s_i32, { "r", "r" } }, - { INDEX_op_ld_i32, { "r", "r" } }, - { INDEX_op_ld8u_i64, { "r", "r" } }, - { INDEX_op_ld8s_i64, { "r", "r" } }, - { INDEX_op_ld16u_i64, { "r", "r" } }, - { INDEX_op_ld16s_i64, { "r", "r" } }, - { INDEX_op_ld32u_i64, { "r", "r" } }, - { INDEX_op_ld32s_i64, { "r", "r" } }, - { INDEX_op_ld_i64, { "r", "r" } }, - - { INDEX_op_st8_i32, { "rZ", "r" } }, - { INDEX_op_st16_i32, { "rZ", "r" } }, - { INDEX_op_st_i32, { "rZ", "r" } }, - { INDEX_op_st8_i64, { "rZ", "r" } }, - { INDEX_op_st16_i64, { "rZ", "r" } }, - { INDEX_op_st32_i64, { "rZ", "r" } }, - { INDEX_op_st_i64, { "rZ", "r" } }, - - { INDEX_op_add_i32, { "r", "r", "rA" } }, - { INDEX_op_add_i64, { "r", "r", "rA" } }, - { INDEX_op_sub_i32, { "r", "r", "rA" } }, - { INDEX_op_sub_i64, { "r", "r", "rA" } }, - { INDEX_op_mul_i32, { "r", "r", "r" } }, - { INDEX_op_mul_i64, { "r", "r", "r" } }, - { INDEX_op_div_i32, { "r", "r", "r" } }, - { INDEX_op_div_i64, { "r", "r", "r" } }, - { INDEX_op_divu_i32, { "r", "r", "r" } }, - { INDEX_op_divu_i64, { "r", "r", "r" } }, - { INDEX_op_rem_i32, { "r", "r", "r" } }, - { INDEX_op_rem_i64, { "r", "r", "r" } }, - { INDEX_op_remu_i32, { "r", "r", "r" } }, - { INDEX_op_remu_i64, { "r", "r", "r" } }, - { INDEX_op_and_i32, { "r", "r", "rL" } }, - { INDEX_op_and_i64, { "r", "r", "rL" } }, - { INDEX_op_or_i32, { "r", "r", "rL" } }, - { INDEX_op_or_i64, { "r", "r", "rL" } }, - { INDEX_op_xor_i32, { "r", "r", "rL" } }, - { INDEX_op_xor_i64, { "r", "r", "rL" } }, - { INDEX_op_andc_i32, { "r", "r", "rL" } }, - { INDEX_op_andc_i64, { "r", "r", "rL" } }, - { INDEX_op_orc_i32, { "r", "r", "rL" } }, - { INDEX_op_orc_i64, { "r", "r", "rL" } }, - { INDEX_op_eqv_i32, { "r", "r", "rL" } }, - { INDEX_op_eqv_i64, { "r", "r", "rL" } }, - - { INDEX_op_neg_i32, { "r", "r" } }, - { INDEX_op_neg_i64, { "r", "r" } }, - { INDEX_op_not_i32, { "r", "r" } }, - { INDEX_op_not_i64, { "r", "r" } }, - - { INDEX_op_shl_i32, { "r", "r", "ri" } }, - { INDEX_op_shr_i32, { "r", "r", "ri" } }, - { INDEX_op_sar_i32, { "r", "r", "ri" } }, - { INDEX_op_rotl_i32, { "r", "r", "ri" } }, - { INDEX_op_rotr_i32, { "r", "r", "ri" } }, - { INDEX_op_clz_i32, { "r", "r", "rAL" } }, - { INDEX_op_ctz_i32, { "r", "r", "rAL" } }, - { INDEX_op_shl_i64, { "r", "r", "ri" } }, - { INDEX_op_shr_i64, { "r", "r", "ri" } }, - { INDEX_op_sar_i64, { "r", "r", "ri" } }, - { INDEX_op_rotl_i64, { "r", "r", "ri" } }, - { INDEX_op_rotr_i64, { "r", "r", "ri" } }, - { INDEX_op_clz_i64, { "r", "r", "rAL" } }, - { INDEX_op_ctz_i64, { "r", "r", "rAL" } }, - - { INDEX_op_brcond_i32, { "r", "rA" } }, - { INDEX_op_brcond_i64, { "r", "rA" } }, - { INDEX_op_setcond_i32, { "r", "r", "rA" } }, - { INDEX_op_setcond_i64, { "r", "r", "rA" } }, - { INDEX_op_movcond_i32, { "r", "r", "rA", "rZ", "rZ" } }, - { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } }, - - { INDEX_op_qemu_ld_i32, { "r", "l" } }, - { INDEX_op_qemu_ld_i64, { "r", "l" } }, - { INDEX_op_qemu_st_i32, { "lZ", "l" } }, - { INDEX_op_qemu_st_i64, { "lZ", "l" } }, - - { INDEX_op_bswap16_i32, { "r", "r" } }, - { INDEX_op_bswap32_i32, { "r", "r" } }, - { INDEX_op_bswap16_i64, { "r", "r" } }, - { INDEX_op_bswap32_i64, { "r", "r" } }, - { INDEX_op_bswap64_i64, { "r", "r" } }, - - { INDEX_op_ext8s_i32, { "r", "r" } }, - { INDEX_op_ext16s_i32, { "r", "r" } }, - { INDEX_op_ext8u_i32, { "r", "r" } }, - { INDEX_op_ext16u_i32, { "r", "r" } }, - - { INDEX_op_ext8s_i64, { "r", "r" } }, - { INDEX_op_ext16s_i64, { "r", "r" } }, - { INDEX_op_ext32s_i64, { "r", "r" } }, - { INDEX_op_ext8u_i64, { "r", "r" } }, - { INDEX_op_ext16u_i64, { "r", "r" } }, - { INDEX_op_ext32u_i64, { "r", "r" } }, - { INDEX_op_ext_i32_i64, { "r", "r" } }, - { INDEX_op_extu_i32_i64, { "r", "r" } }, - - { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, - { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, - { INDEX_op_extract_i32, { "r", "r" } }, - { INDEX_op_extract_i64, { "r", "r" } }, - { INDEX_op_sextract_i32, { "r", "r" } }, - { INDEX_op_sextract_i64, { "r", "r" } }, - - { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, - { INDEX_op_add2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, - { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, - { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, - - { INDEX_op_muluh_i64, { "r", "r", "r" } }, - { INDEX_op_mulsh_i64, { "r", "r", "r" } }, - - { INDEX_op_mb, { } }, - { -1 }, -}; - static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) { - int i, n = ARRAY_SIZE(aarch64_op_defs); + static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; + static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; + static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } }; + static const TCGTargetOpDef r_rA = { .args_ct_str = { "r", "rA" } }; + static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } }; + static const TCGTargetOpDef lZ_l = { .args_ct_str = { "lZ", "l" } }; + static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } }; + static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } }; + static const TCGTargetOpDef r_r_rA = { .args_ct_str = { "r", "r", "rA" } }; + static const TCGTargetOpDef r_r_rL = { .args_ct_str = { "r", "r", "rL" } }; + static const TCGTargetOpDef r_r_rAL + = { .args_ct_str = { "r", "r", "rAL" } }; + static const TCGTargetOpDef dep + = { .args_ct_str = { "r", "0", "rZ" } }; + static const TCGTargetOpDef movc + = { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } }; + static const TCGTargetOpDef add2 + = { .args_ct_str = { "r", "r", "rZ", "rZ", "rA", "rMZ" } }; + + switch (op) { + case INDEX_op_goto_ptr: + return &r; - for (i = 0; i < n; ++i) { - if (aarch64_op_defs[i].op == op) { - return &aarch64_op_defs[i]; - } + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_ld8u_i64: + case INDEX_op_ld8s_i64: + case INDEX_op_ld16u_i64: + case INDEX_op_ld16s_i64: + case INDEX_op_ld32u_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld_i64: + case INDEX_op_neg_i32: + case INDEX_op_neg_i64: + case INDEX_op_not_i32: + case INDEX_op_not_i64: + case INDEX_op_bswap16_i32: + case INDEX_op_bswap32_i32: + case INDEX_op_bswap16_i64: + case INDEX_op_bswap32_i64: + case INDEX_op_bswap64_i64: + case INDEX_op_ext8s_i32: + case INDEX_op_ext16s_i32: + case INDEX_op_ext8u_i32: + case INDEX_op_ext16u_i32: + case INDEX_op_ext8s_i64: + case INDEX_op_ext16s_i64: + case INDEX_op_ext32s_i64: + case INDEX_op_ext8u_i64: + case INDEX_op_ext16u_i64: + case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + case INDEX_op_extract_i32: + case INDEX_op_extract_i64: + case INDEX_op_sextract_i32: + case INDEX_op_sextract_i64: + return &r_r; + + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + case INDEX_op_st8_i64: + case INDEX_op_st16_i64: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: + return &rZ_r; + + case INDEX_op_add_i32: + case INDEX_op_add_i64: + case INDEX_op_sub_i32: + case INDEX_op_sub_i64: + case INDEX_op_setcond_i32: + case INDEX_op_setcond_i64: + return &r_r_rA; + + case INDEX_op_mul_i32: + case INDEX_op_mul_i64: + case INDEX_op_div_i32: + case INDEX_op_div_i64: + case INDEX_op_divu_i32: + case INDEX_op_divu_i64: + case INDEX_op_rem_i32: + case INDEX_op_rem_i64: + case INDEX_op_remu_i32: + case INDEX_op_remu_i64: + case INDEX_op_muluh_i64: + case INDEX_op_mulsh_i64: + return &r_r_r; + + case INDEX_op_and_i32: + case INDEX_op_and_i64: + case INDEX_op_or_i32: + case INDEX_op_or_i64: + case INDEX_op_xor_i32: + case INDEX_op_xor_i64: + case INDEX_op_andc_i32: + case INDEX_op_andc_i64: + case INDEX_op_orc_i32: + case INDEX_op_orc_i64: + case INDEX_op_eqv_i32: + case INDEX_op_eqv_i64: + return &r_r_rL; + + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + case INDEX_op_rotl_i32: + case INDEX_op_rotr_i32: + case INDEX_op_shl_i64: + case INDEX_op_shr_i64: + case INDEX_op_sar_i64: + case INDEX_op_rotl_i64: + case INDEX_op_rotr_i64: + return &r_r_ri; + + case INDEX_op_clz_i32: + case INDEX_op_ctz_i32: + case INDEX_op_clz_i64: + case INDEX_op_ctz_i64: + return &r_r_rAL; + + case INDEX_op_brcond_i32: + case INDEX_op_brcond_i64: + return &r_rA; + + case INDEX_op_movcond_i32: + case INDEX_op_movcond_i64: + return &movc; + + case INDEX_op_qemu_ld_i32: + case INDEX_op_qemu_ld_i64: + return &r_l; + case INDEX_op_qemu_st_i32: + case INDEX_op_qemu_st_i64: + return &lZ_l; + + case INDEX_op_deposit_i32: + case INDEX_op_deposit_i64: + return &dep; + + case INDEX_op_add2_i32: + case INDEX_op_add2_i64: + case INDEX_op_sub2_i32: + case INDEX_op_sub2_i64: + return &add2; + + default: + return NULL; } - return NULL; } static void tcg_target_init(TCGContext *s) { - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); - - tcg_regset_set32(tcg_target_call_clobber_regs, 0, - (1 << TCG_REG_X0) | (1 << TCG_REG_X1) | - (1 << TCG_REG_X2) | (1 << TCG_REG_X3) | - (1 << TCG_REG_X4) | (1 << TCG_REG_X5) | - (1 << TCG_REG_X6) | (1 << TCG_REG_X7) | - (1 << TCG_REG_X8) | (1 << TCG_REG_X9) | - (1 << TCG_REG_X10) | (1 << TCG_REG_X11) | - (1 << TCG_REG_X12) | (1 << TCG_REG_X13) | - (1 << TCG_REG_X14) | (1 << TCG_REG_X15) | - (1 << TCG_REG_X16) | (1 << TCG_REG_X17) | - (1 << TCG_REG_X18) | (1 << TCG_REG_X30)); - - tcg_regset_clear(s->reserved_regs); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffffu; + tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffffu; + + tcg_target_call_clobber_regs = 0xfffffffu; + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X19); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X20); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X21); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X22); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X23); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X24); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X25); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X26); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X27); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X28); + tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X29); + + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP); tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c index db46aea38c..98a12535a5 100644 --- a/tcg/arm/tcg-target.inc.c +++ b/tcg/arm/tcg-target.inc.c @@ -264,13 +264,13 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, case 'r': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1); + ct->u.regs = 0xffff; break; /* qemu_ld address */ case 'l': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1); + ct->u.regs = 0xffff; #ifdef CONFIG_SOFTMMU /* r0-r2,lr will be overwritten when reading the tlb entry, so don't use these. */ @@ -284,7 +284,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, /* qemu_st address & data */ case 's': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1); + ct->u.regs = 0xffff; /* r0-r2 will be overwritten when reading the tlb entry (softmmu only) and r0-r1 doing the byte swapping, so don't use these. */ tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); @@ -2060,91 +2060,119 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } } -static const TCGTargetOpDef arm_op_defs[] = { - { INDEX_op_exit_tb, { } }, - { INDEX_op_goto_tb, { } }, - { INDEX_op_br, { } }, - { INDEX_op_goto_ptr, { "r" } }, - - { INDEX_op_ld8u_i32, { "r", "r" } }, - { INDEX_op_ld8s_i32, { "r", "r" } }, - { INDEX_op_ld16u_i32, { "r", "r" } }, - { INDEX_op_ld16s_i32, { "r", "r" } }, - { INDEX_op_ld_i32, { "r", "r" } }, - { INDEX_op_st8_i32, { "r", "r" } }, - { INDEX_op_st16_i32, { "r", "r" } }, - { INDEX_op_st_i32, { "r", "r" } }, - - /* TODO: "r", "r", "ri" */ - { INDEX_op_add_i32, { "r", "r", "rIN" } }, - { INDEX_op_sub_i32, { "r", "rI", "rIN" } }, - { INDEX_op_mul_i32, { "r", "r", "r" } }, - { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, - { INDEX_op_muls2_i32, { "r", "r", "r", "r" } }, - { INDEX_op_and_i32, { "r", "r", "rIK" } }, - { INDEX_op_andc_i32, { "r", "r", "rIK" } }, - { INDEX_op_or_i32, { "r", "r", "rI" } }, - { INDEX_op_xor_i32, { "r", "r", "rI" } }, - { INDEX_op_neg_i32, { "r", "r" } }, - { INDEX_op_not_i32, { "r", "r" } }, - - { INDEX_op_shl_i32, { "r", "r", "ri" } }, - { INDEX_op_shr_i32, { "r", "r", "ri" } }, - { INDEX_op_sar_i32, { "r", "r", "ri" } }, - { INDEX_op_rotl_i32, { "r", "r", "ri" } }, - { INDEX_op_rotr_i32, { "r", "r", "ri" } }, - { INDEX_op_clz_i32, { "r", "r", "rIK" } }, - { INDEX_op_ctz_i32, { "r", "r", "rIK" } }, - - { INDEX_op_brcond_i32, { "r", "rIN" } }, - { INDEX_op_setcond_i32, { "r", "r", "rIN" } }, - { INDEX_op_movcond_i32, { "r", "r", "rIN", "rIK", "0" } }, - - { INDEX_op_add2_i32, { "r", "r", "r", "r", "rIN", "rIK" } }, - { INDEX_op_sub2_i32, { "r", "r", "rI", "rI", "rIN", "rIK" } }, - { INDEX_op_brcond2_i32, { "r", "r", "rIN", "rIN" } }, - { INDEX_op_setcond2_i32, { "r", "r", "r", "rIN", "rIN" } }, - -#if TARGET_LONG_BITS == 32 - { INDEX_op_qemu_ld_i32, { "r", "l" } }, - { INDEX_op_qemu_ld_i64, { "r", "r", "l" } }, - { INDEX_op_qemu_st_i32, { "s", "s" } }, - { INDEX_op_qemu_st_i64, { "s", "s", "s" } }, -#else - { INDEX_op_qemu_ld_i32, { "r", "l", "l" } }, - { INDEX_op_qemu_ld_i64, { "r", "r", "l", "l" } }, - { INDEX_op_qemu_st_i32, { "s", "s", "s" } }, - { INDEX_op_qemu_st_i64, { "s", "s", "s", "s" } }, -#endif - - { INDEX_op_bswap16_i32, { "r", "r" } }, - { INDEX_op_bswap32_i32, { "r", "r" } }, - - { INDEX_op_ext8s_i32, { "r", "r" } }, - { INDEX_op_ext16s_i32, { "r", "r" } }, - { INDEX_op_ext16u_i32, { "r", "r" } }, +static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) +{ + static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; + static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; + static const TCGTargetOpDef s_s = { .args_ct_str = { "s", "s" } }; + static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } }; + static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } }; + static const TCGTargetOpDef r_r_l = { .args_ct_str = { "r", "r", "l" } }; + static const TCGTargetOpDef r_l_l = { .args_ct_str = { "r", "l", "l" } }; + static const TCGTargetOpDef s_s_s = { .args_ct_str = { "s", "s", "s" } }; + static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } }; + static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } }; + static const TCGTargetOpDef r_r_rIN + = { .args_ct_str = { "r", "r", "rIN" } }; + static const TCGTargetOpDef r_r_rIK + = { .args_ct_str = { "r", "r", "rIK" } }; + static const TCGTargetOpDef r_r_r_r + = { .args_ct_str = { "r", "r", "r", "r" } }; + static const TCGTargetOpDef r_r_l_l + = { .args_ct_str = { "r", "r", "l", "l" } }; + static const TCGTargetOpDef s_s_s_s + = { .args_ct_str = { "s", "s", "s", "s" } }; + static const TCGTargetOpDef br + = { .args_ct_str = { "r", "rIN" } }; + static const TCGTargetOpDef dep + = { .args_ct_str = { "r", "0", "rZ" } }; + static const TCGTargetOpDef movc + = { .args_ct_str = { "r", "r", "rIN", "rIK", "0" } }; + static const TCGTargetOpDef add2 + = { .args_ct_str = { "r", "r", "r", "r", "rIN", "rIK" } }; + static const TCGTargetOpDef sub2 + = { .args_ct_str = { "r", "r", "rI", "rI", "rIN", "rIK" } }; + static const TCGTargetOpDef br2 + = { .args_ct_str = { "r", "r", "rIN", "rIN" } }; + static const TCGTargetOpDef setc2 + = { .args_ct_str = { "r", "r", "r", "rIN", "rIN" } }; + + switch (op) { + case INDEX_op_goto_ptr: + return &r; - { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, - { INDEX_op_extract_i32, { "r", "r" } }, - { INDEX_op_sextract_i32, { "r", "r" } }, + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + case INDEX_op_neg_i32: + case INDEX_op_not_i32: + case INDEX_op_bswap16_i32: + case INDEX_op_bswap32_i32: + case INDEX_op_ext8s_i32: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16u_i32: + case INDEX_op_extract_i32: + case INDEX_op_sextract_i32: + return &r_r; - { INDEX_op_div_i32, { "r", "r", "r" } }, - { INDEX_op_divu_i32, { "r", "r", "r" } }, + case INDEX_op_add_i32: + case INDEX_op_sub_i32: + case INDEX_op_setcond_i32: + return &r_r_rIN; + case INDEX_op_and_i32: + case INDEX_op_andc_i32: + case INDEX_op_clz_i32: + case INDEX_op_ctz_i32: + return &r_r_rIK; + case INDEX_op_mul_i32: + case INDEX_op_div_i32: + case INDEX_op_divu_i32: + return &r_r_r; + case INDEX_op_mulu2_i32: + case INDEX_op_muls2_i32: + return &r_r_r_r; + case INDEX_op_or_i32: + case INDEX_op_xor_i32: + return &r_r_rI; + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + case INDEX_op_rotl_i32: + case INDEX_op_rotr_i32: + return &r_r_ri; - { INDEX_op_mb, { } }, - { -1 }, -}; + case INDEX_op_brcond_i32: + return &br; + case INDEX_op_deposit_i32: + return &dep; + case INDEX_op_movcond_i32: + return &movc; + case INDEX_op_add2_i32: + return &add2; + case INDEX_op_sub2_i32: + return &sub2; + case INDEX_op_brcond2_i32: + return &br2; + case INDEX_op_setcond2_i32: + return &setc2; -static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) -{ - int i, n = ARRAY_SIZE(arm_op_defs); + case INDEX_op_qemu_ld_i32: + return TARGET_LONG_BITS == 32 ? &r_l : &r_l_l; + case INDEX_op_qemu_ld_i64: + return TARGET_LONG_BITS == 32 ? &r_r_l : &r_r_l_l; + case INDEX_op_qemu_st_i32: + return TARGET_LONG_BITS == 32 ? &s_s : &s_s_s; + case INDEX_op_qemu_st_i64: + return TARGET_LONG_BITS == 32 ? &s_s_s : &s_s_s_s; - for (i = 0; i < n; ++i) { - if (arm_op_defs[i].op == op) { - return &arm_op_defs[i]; - } + default: + return NULL; } - return NULL; } static void tcg_target_init(TCGContext *s) @@ -2164,16 +2192,17 @@ static void tcg_target_init(TCGContext *s) } } - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); - tcg_regset_set32(tcg_target_call_clobber_regs, 0, - (1 << TCG_REG_R0) | - (1 << TCG_REG_R1) | - (1 << TCG_REG_R2) | - (1 << TCG_REG_R3) | - (1 << TCG_REG_R12) | - (1 << TCG_REG_R14)); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffff; + + tcg_target_call_clobber_regs = 0; + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14); - tcg_regset_clear(s->reserved_regs); + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC); diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 5231056fd3..69e49c9f58 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -193,23 +193,15 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, break; case 'q': ct->ct |= TCG_CT_REG; - if (TCG_TARGET_REG_BITS == 64) { - tcg_regset_set32(ct->u.regs, 0, 0xffff); - } else { - tcg_regset_set32(ct->u.regs, 0, 0xf); - } + ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf; break; case 'Q': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xf); + ct->u.regs = 0xf; break; case 'r': ct->ct |= TCG_CT_REG; - if (TCG_TARGET_REG_BITS == 64) { - tcg_regset_set32(ct->u.regs, 0, 0xffff); - } else { - tcg_regset_set32(ct->u.regs, 0, 0xff); - } + ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff; break; case 'W': /* With TZCNT/LZCNT, we can have operand-size as an input. */ @@ -219,11 +211,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, /* qemu_ld/st address constraint */ case 'L': ct->ct |= TCG_CT_REG; - if (TCG_TARGET_REG_BITS == 64) { - tcg_regset_set32(ct->u.regs, 0, 0xffff); - } else { - tcg_regset_set32(ct->u.regs, 0, 0xff); - } + ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff; tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1); break; @@ -2643,13 +2631,13 @@ static void tcg_target_init(TCGContext *s) #endif /* CONFIG_CPUID_H */ if (TCG_TARGET_REG_BITS == 64) { - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffff; + tcg_target_available_regs[TCG_TYPE_I64] = 0xffff; } else { - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff); + tcg_target_available_regs[TCG_TYPE_I32] = 0xff; } - tcg_regset_clear(tcg_target_call_clobber_regs); + tcg_target_call_clobber_regs = 0; tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX); @@ -2664,7 +2652,7 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11); } - tcg_regset_clear(s->reserved_regs); + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); } diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c index 750baadf37..ce4030602f 100644 --- a/tcg/mips/tcg-target.inc.c +++ b/tcg/mips/tcg-target.inc.c @@ -195,11 +195,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, switch(*ct_str++) { case 'r': ct->ct |= TCG_CT_REG; - tcg_regset_set(ct->u.regs, 0xffffffff); + ct->u.regs = 0xffffffff; break; case 'L': /* qemu_ld input arg constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set(ct->u.regs, 0xffffffff); + ct->u.regs = 0xffffffff; tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); #if defined(CONFIG_SOFTMMU) if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { @@ -209,7 +209,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, break; case 'S': /* qemu_st constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set(ct->u.regs, 0xffffffff); + ct->u.regs = 0xffffffff; tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); #if defined(CONFIG_SOFTMMU) if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { @@ -2163,166 +2163,182 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } } -static const TCGTargetOpDef mips_op_defs[] = { - { INDEX_op_exit_tb, { } }, - { INDEX_op_goto_tb, { } }, - { INDEX_op_br, { } }, - { INDEX_op_goto_ptr, { "r" } }, +static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) +{ + static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; + static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; + static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } }; + static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } }; + static const TCGTargetOpDef SZ_S = { .args_ct_str = { "SZ", "S" } }; + static const TCGTargetOpDef rZ_rZ = { .args_ct_str = { "rZ", "rZ" } }; + static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } }; + static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } }; + static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } }; + static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } }; + static const TCGTargetOpDef r_r_rJ = { .args_ct_str = { "r", "r", "rJ" } }; + static const TCGTargetOpDef SZ_S_S = { .args_ct_str = { "SZ", "S", "S" } }; + static const TCGTargetOpDef SZ_SZ_S + = { .args_ct_str = { "SZ", "SZ", "S" } }; + static const TCGTargetOpDef SZ_SZ_S_S + = { .args_ct_str = { "SZ", "SZ", "S", "S" } }; + static const TCGTargetOpDef r_rZ_rN + = { .args_ct_str = { "r", "rZ", "rN" } }; + static const TCGTargetOpDef r_rZ_rZ + = { .args_ct_str = { "r", "rZ", "rZ" } }; + static const TCGTargetOpDef r_r_rIK + = { .args_ct_str = { "r", "r", "rIK" } }; + static const TCGTargetOpDef r_r_rWZ + = { .args_ct_str = { "r", "r", "rWZ" } }; + static const TCGTargetOpDef r_r_r_r + = { .args_ct_str = { "r", "r", "r", "r" } }; + static const TCGTargetOpDef r_r_L_L + = { .args_ct_str = { "r", "r", "L", "L" } }; + static const TCGTargetOpDef dep + = { .args_ct_str = { "r", "0", "rZ" } }; + static const TCGTargetOpDef movc + = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "0" } }; + static const TCGTargetOpDef movc_r6 + = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } }; + static const TCGTargetOpDef add2 + = { .args_ct_str = { "r", "r", "rZ", "rZ", "rN", "rN" } }; + static const TCGTargetOpDef br2 + = { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } }; + static const TCGTargetOpDef setc2 + = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } }; + + switch (op) { + case INDEX_op_goto_ptr: + return &r; - { INDEX_op_ld8u_i32, { "r", "r" } }, - { INDEX_op_ld8s_i32, { "r", "r" } }, - { INDEX_op_ld16u_i32, { "r", "r" } }, - { INDEX_op_ld16s_i32, { "r", "r" } }, - { INDEX_op_ld_i32, { "r", "r" } }, - { INDEX_op_st8_i32, { "rZ", "r" } }, - { INDEX_op_st16_i32, { "rZ", "r" } }, - { INDEX_op_st_i32, { "rZ", "r" } }, + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_not_i32: + case INDEX_op_bswap16_i32: + case INDEX_op_bswap32_i32: + case INDEX_op_ext8s_i32: + case INDEX_op_ext16s_i32: + case INDEX_op_extract_i32: + case INDEX_op_ld8u_i64: + case INDEX_op_ld8s_i64: + case INDEX_op_ld16u_i64: + case INDEX_op_ld16s_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld32u_i64: + case INDEX_op_ld_i64: + case INDEX_op_not_i64: + case INDEX_op_bswap16_i64: + case INDEX_op_bswap32_i64: + case INDEX_op_bswap64_i64: + case INDEX_op_ext8s_i64: + case INDEX_op_ext16s_i64: + case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: + case INDEX_op_extrh_i64_i32: + case INDEX_op_extract_i64: + return &r_r; - { INDEX_op_add_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_mul_i32, { "r", "rZ", "rZ" } }, -#if !use_mips32r6_instructions - { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } }, - { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } }, -#endif - { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_div_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_divu_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_rem_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_remu_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_sub_i32, { "r", "rZ", "rN" } }, - - { INDEX_op_and_i32, { "r", "rZ", "rIK" } }, - { INDEX_op_nor_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_not_i32, { "r", "rZ" } }, - { INDEX_op_or_i32, { "r", "rZ", "rIZ" } }, - { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } }, - - { INDEX_op_shl_i32, { "r", "rZ", "ri" } }, - { INDEX_op_shr_i32, { "r", "rZ", "ri" } }, - { INDEX_op_sar_i32, { "r", "rZ", "ri" } }, - { INDEX_op_rotr_i32, { "r", "rZ", "ri" } }, - { INDEX_op_rotl_i32, { "r", "rZ", "ri" } }, - { INDEX_op_clz_i32, { "r", "r", "rWZ" } }, - - { INDEX_op_bswap16_i32, { "r", "r" } }, - { INDEX_op_bswap32_i32, { "r", "r" } }, - - { INDEX_op_ext8s_i32, { "r", "rZ" } }, - { INDEX_op_ext16s_i32, { "r", "rZ" } }, - - { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, - { INDEX_op_extract_i32, { "r", "r" } }, - - { INDEX_op_brcond_i32, { "rZ", "rZ" } }, -#if use_mips32r6_instructions - { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "rZ" } }, -#else - { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } }, -#endif - { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } }, + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + case INDEX_op_st8_i64: + case INDEX_op_st16_i64: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: + return &rZ_r; -#if TCG_TARGET_REG_BITS == 32 - { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } }, - { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } }, - { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } }, - { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } }, -#endif + case INDEX_op_add_i32: + case INDEX_op_add_i64: + return &r_r_rJ; + case INDEX_op_sub_i32: + case INDEX_op_sub_i64: + return &r_rZ_rN; + case INDEX_op_mul_i32: + case INDEX_op_mulsh_i32: + case INDEX_op_muluh_i32: + case INDEX_op_div_i32: + case INDEX_op_divu_i32: + case INDEX_op_rem_i32: + case INDEX_op_remu_i32: + case INDEX_op_nor_i32: + case INDEX_op_setcond_i32: + case INDEX_op_mul_i64: + case INDEX_op_mulsh_i64: + case INDEX_op_muluh_i64: + case INDEX_op_div_i64: + case INDEX_op_divu_i64: + case INDEX_op_rem_i64: + case INDEX_op_remu_i64: + case INDEX_op_nor_i64: + case INDEX_op_setcond_i64: + return &r_rZ_rZ; + case INDEX_op_muls2_i32: + case INDEX_op_mulu2_i32: + case INDEX_op_muls2_i64: + case INDEX_op_mulu2_i64: + return &r_r_r_r; + case INDEX_op_and_i32: + case INDEX_op_and_i64: + return &r_r_rIK; + case INDEX_op_or_i32: + case INDEX_op_xor_i32: + case INDEX_op_or_i64: + case INDEX_op_xor_i64: + return &r_r_rI; + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + case INDEX_op_rotr_i32: + case INDEX_op_rotl_i32: + case INDEX_op_shl_i64: + case INDEX_op_shr_i64: + case INDEX_op_sar_i64: + case INDEX_op_rotr_i64: + case INDEX_op_rotl_i64: + return &r_r_ri; + case INDEX_op_clz_i32: + case INDEX_op_clz_i64: + return &r_r_rWZ; -#if TCG_TARGET_REG_BITS == 64 - { INDEX_op_ld8u_i64, { "r", "r" } }, - { INDEX_op_ld8s_i64, { "r", "r" } }, - { INDEX_op_ld16u_i64, { "r", "r" } }, - { INDEX_op_ld16s_i64, { "r", "r" } }, - { INDEX_op_ld32s_i64, { "r", "r" } }, - { INDEX_op_ld32u_i64, { "r", "r" } }, - { INDEX_op_ld_i64, { "r", "r" } }, - { INDEX_op_st8_i64, { "rZ", "r" } }, - { INDEX_op_st16_i64, { "rZ", "r" } }, - { INDEX_op_st32_i64, { "rZ", "r" } }, - { INDEX_op_st_i64, { "rZ", "r" } }, - - { INDEX_op_add_i64, { "r", "rZ", "rJ" } }, - { INDEX_op_mul_i64, { "r", "rZ", "rZ" } }, -#if !use_mips32r6_instructions - { INDEX_op_muls2_i64, { "r", "r", "rZ", "rZ" } }, - { INDEX_op_mulu2_i64, { "r", "r", "rZ", "rZ" } }, -#endif - { INDEX_op_mulsh_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_muluh_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_div_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_divu_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_rem_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_remu_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_sub_i64, { "r", "rZ", "rN" } }, - - { INDEX_op_and_i64, { "r", "rZ", "rIK" } }, - { INDEX_op_nor_i64, { "r", "rZ", "rZ" } }, - { INDEX_op_not_i64, { "r", "rZ" } }, - { INDEX_op_or_i64, { "r", "rZ", "rI" } }, - { INDEX_op_xor_i64, { "r", "rZ", "rI" } }, - - { INDEX_op_shl_i64, { "r", "rZ", "ri" } }, - { INDEX_op_shr_i64, { "r", "rZ", "ri" } }, - { INDEX_op_sar_i64, { "r", "rZ", "ri" } }, - { INDEX_op_rotr_i64, { "r", "rZ", "ri" } }, - { INDEX_op_rotl_i64, { "r", "rZ", "ri" } }, - { INDEX_op_clz_i64, { "r", "r", "rWZ" } }, - - { INDEX_op_bswap16_i64, { "r", "r" } }, - { INDEX_op_bswap32_i64, { "r", "r" } }, - { INDEX_op_bswap64_i64, { "r", "r" } }, - - { INDEX_op_ext8s_i64, { "r", "rZ" } }, - { INDEX_op_ext16s_i64, { "r", "rZ" } }, - { INDEX_op_ext32s_i64, { "r", "rZ" } }, - { INDEX_op_ext32u_i64, { "r", "rZ" } }, - { INDEX_op_ext_i32_i64, { "r", "rZ" } }, - { INDEX_op_extu_i32_i64, { "r", "rZ" } }, - { INDEX_op_extrl_i64_i32, { "r", "rZ" } }, - { INDEX_op_extrh_i64_i32, { "r", "rZ" } }, - - { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, - { INDEX_op_extract_i64, { "r", "r" } }, - - { INDEX_op_brcond_i64, { "rZ", "rZ" } }, -#if use_mips32r6_instructions - { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rZ", "rZ" } }, -#else - { INDEX_op_movcond_i64, { "r", "rZ", "rZ", "rZ", "0" } }, -#endif - { INDEX_op_setcond_i64, { "r", "rZ", "rZ" } }, - - { INDEX_op_qemu_ld_i32, { "r", "LZ" } }, - { INDEX_op_qemu_st_i32, { "SZ", "SZ" } }, - { INDEX_op_qemu_ld_i64, { "r", "LZ" } }, - { INDEX_op_qemu_st_i64, { "SZ", "SZ" } }, -#elif TARGET_LONG_BITS == 32 - { INDEX_op_qemu_ld_i32, { "r", "LZ" } }, - { INDEX_op_qemu_st_i32, { "SZ", "SZ" } }, - { INDEX_op_qemu_ld_i64, { "r", "r", "LZ" } }, - { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ" } }, -#else - { INDEX_op_qemu_ld_i32, { "r", "LZ", "LZ" } }, - { INDEX_op_qemu_st_i32, { "SZ", "SZ", "SZ" } }, - { INDEX_op_qemu_ld_i64, { "r", "r", "LZ", "LZ" } }, - { INDEX_op_qemu_st_i64, { "SZ", "SZ", "SZ", "SZ" } }, -#endif + case INDEX_op_deposit_i32: + case INDEX_op_deposit_i64: + return &dep; + case INDEX_op_brcond_i32: + case INDEX_op_brcond_i64: + return &rZ_rZ; + case INDEX_op_movcond_i32: + case INDEX_op_movcond_i64: + return use_mips32r6_instructions ? &movc_r6 : &movc; - { INDEX_op_mb, { } }, - { -1 }, -}; + case INDEX_op_add2_i32: + case INDEX_op_sub2_i32: + return &add2; + case INDEX_op_setcond2_i32: + return &setc2; + case INDEX_op_brcond2_i32: + return &br2; -static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) -{ - int i, n = ARRAY_SIZE(mips_op_defs); + case INDEX_op_qemu_ld_i32: + return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 + ? &r_L : &r_L_L); + case INDEX_op_qemu_st_i32: + return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 + ? &SZ_S : &SZ_S_S); + case INDEX_op_qemu_ld_i64: + return (TCG_TARGET_REG_BITS == 64 ? &r_L + : TARGET_LONG_BITS == 32 ? &r_r_L : &r_r_L_L); + case INDEX_op_qemu_st_i64: + return (TCG_TARGET_REG_BITS == 64 ? &SZ_S + : TARGET_LONG_BITS == 32 ? &SZ_SZ_S : &SZ_SZ_S_S); - for (i = 0; i < n; ++i) { - if (mips_op_defs[i].op == op) { - return &mips_op_defs[i]; - } + default: + return NULL; } - return NULL; } static int tcg_target_callee_save_regs[] = { @@ -2607,29 +2623,30 @@ static void tcg_target_qemu_prologue(TCGContext *s) static void tcg_target_init(TCGContext *s) { tcg_target_detect_isa(); - tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff; if (TCG_TARGET_REG_BITS == 64) { - tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64], 0xffffffff); - } - tcg_regset_set(tcg_target_call_clobber_regs, - (1 << TCG_REG_V0) | - (1 << TCG_REG_V1) | - (1 << TCG_REG_A0) | - (1 << TCG_REG_A1) | - (1 << TCG_REG_A2) | - (1 << TCG_REG_A3) | - (1 << TCG_REG_T0) | - (1 << TCG_REG_T1) | - (1 << TCG_REG_T2) | - (1 << TCG_REG_T3) | - (1 << TCG_REG_T4) | - (1 << TCG_REG_T5) | - (1 << TCG_REG_T6) | - (1 << TCG_REG_T7) | - (1 << TCG_REG_T8) | - (1 << TCG_REG_T9)); - - tcg_regset_clear(s->reserved_regs); + tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff; + } + + tcg_target_call_clobber_regs = 0; + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_A3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T4); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T5); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T6); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T7); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T8); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_T9); + + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0); /* kernel use only */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */ diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c index 21d764c102..879885b68b 100644 --- a/tcg/ppc/tcg-target.inc.c +++ b/tcg/ppc/tcg-target.inc.c @@ -260,11 +260,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, break; case 'r': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffffffff); + ct->u.regs = 0xffffffff; break; case 'L': /* qemu_ld constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffffffff); + ct->u.regs = 0xffffffff; tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3); #ifdef CONFIG_SOFTMMU tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4); @@ -273,7 +273,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, break; case 'S': /* qemu_st constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffffffff); + ct->u.regs = 0xffffffff; tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3); #ifdef CONFIG_SOFTMMU tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4); @@ -1374,7 +1374,9 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, pair = (uint64_t)i2 << 32 | i1; #endif - atomic_set((uint64_t *)jmp_addr, pair); + /* As per the enclosing if, this is ppc64. Avoid the _Static_assert + within atomic_set that would fail to build a ppc32 host. */ + atomic_set__nocheck((uint64_t *)jmp_addr, pair); flush_icache_range(jmp_addr, jmp_addr + 8); } else { intptr_t diff = addr - jmp_addr; @@ -2594,166 +2596,181 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, } } -static const TCGTargetOpDef ppc_op_defs[] = { - { INDEX_op_exit_tb, { } }, - { INDEX_op_goto_tb, { } }, - { INDEX_op_br, { } }, - { INDEX_op_goto_ptr, { "r" } }, - - { INDEX_op_ld8u_i32, { "r", "r" } }, - { INDEX_op_ld8s_i32, { "r", "r" } }, - { INDEX_op_ld16u_i32, { "r", "r" } }, - { INDEX_op_ld16s_i32, { "r", "r" } }, - { INDEX_op_ld_i32, { "r", "r" } }, - - { INDEX_op_st8_i32, { "r", "r" } }, - { INDEX_op_st16_i32, { "r", "r" } }, - { INDEX_op_st_i32, { "r", "r" } }, - - { INDEX_op_add_i32, { "r", "r", "ri" } }, - { INDEX_op_mul_i32, { "r", "r", "rI" } }, - { INDEX_op_div_i32, { "r", "r", "r" } }, - { INDEX_op_divu_i32, { "r", "r", "r" } }, - { INDEX_op_sub_i32, { "r", "rI", "ri" } }, - { INDEX_op_and_i32, { "r", "r", "ri" } }, - { INDEX_op_or_i32, { "r", "r", "ri" } }, - { INDEX_op_xor_i32, { "r", "r", "ri" } }, - { INDEX_op_andc_i32, { "r", "r", "ri" } }, - { INDEX_op_orc_i32, { "r", "r", "ri" } }, - { INDEX_op_eqv_i32, { "r", "r", "ri" } }, - { INDEX_op_nand_i32, { "r", "r", "r" } }, - { INDEX_op_nor_i32, { "r", "r", "r" } }, - { INDEX_op_clz_i32, { "r", "r", "rZW" } }, - { INDEX_op_ctz_i32, { "r", "r", "rZW" } }, - { INDEX_op_ctpop_i32, { "r", "r" } }, - - { INDEX_op_shl_i32, { "r", "r", "ri" } }, - { INDEX_op_shr_i32, { "r", "r", "ri" } }, - { INDEX_op_sar_i32, { "r", "r", "ri" } }, - { INDEX_op_rotl_i32, { "r", "r", "ri" } }, - { INDEX_op_rotr_i32, { "r", "r", "ri" } }, - - { INDEX_op_neg_i32, { "r", "r" } }, - { INDEX_op_not_i32, { "r", "r" } }, - { INDEX_op_ext8s_i32, { "r", "r" } }, - { INDEX_op_ext16s_i32, { "r", "r" } }, - { INDEX_op_bswap16_i32, { "r", "r" } }, - { INDEX_op_bswap32_i32, { "r", "r" } }, - - { INDEX_op_brcond_i32, { "r", "ri" } }, - { INDEX_op_setcond_i32, { "r", "r", "ri" } }, - { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } }, - - { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, - { INDEX_op_extract_i32, { "r", "r" } }, - - { INDEX_op_muluh_i32, { "r", "r", "r" } }, - { INDEX_op_mulsh_i32, { "r", "r", "r" } }, - -#if TCG_TARGET_REG_BITS == 64 - { INDEX_op_ld8u_i64, { "r", "r" } }, - { INDEX_op_ld8s_i64, { "r", "r" } }, - { INDEX_op_ld16u_i64, { "r", "r" } }, - { INDEX_op_ld16s_i64, { "r", "r" } }, - { INDEX_op_ld32u_i64, { "r", "r" } }, - { INDEX_op_ld32s_i64, { "r", "r" } }, - { INDEX_op_ld_i64, { "r", "r" } }, - - { INDEX_op_st8_i64, { "r", "r" } }, - { INDEX_op_st16_i64, { "r", "r" } }, - { INDEX_op_st32_i64, { "r", "r" } }, - { INDEX_op_st_i64, { "r", "r" } }, - - { INDEX_op_add_i64, { "r", "r", "rT" } }, - { INDEX_op_sub_i64, { "r", "rI", "rT" } }, - { INDEX_op_and_i64, { "r", "r", "ri" } }, - { INDEX_op_or_i64, { "r", "r", "rU" } }, - { INDEX_op_xor_i64, { "r", "r", "rU" } }, - { INDEX_op_andc_i64, { "r", "r", "ri" } }, - { INDEX_op_orc_i64, { "r", "r", "r" } }, - { INDEX_op_eqv_i64, { "r", "r", "r" } }, - { INDEX_op_nand_i64, { "r", "r", "r" } }, - { INDEX_op_nor_i64, { "r", "r", "r" } }, - { INDEX_op_clz_i64, { "r", "r", "rZW" } }, - { INDEX_op_ctz_i64, { "r", "r", "rZW" } }, - { INDEX_op_ctpop_i64, { "r", "r" } }, - - { INDEX_op_shl_i64, { "r", "r", "ri" } }, - { INDEX_op_shr_i64, { "r", "r", "ri" } }, - { INDEX_op_sar_i64, { "r", "r", "ri" } }, - { INDEX_op_rotl_i64, { "r", "r", "ri" } }, - { INDEX_op_rotr_i64, { "r", "r", "ri" } }, - - { INDEX_op_mul_i64, { "r", "r", "rI" } }, - { INDEX_op_div_i64, { "r", "r", "r" } }, - { INDEX_op_divu_i64, { "r", "r", "r" } }, - - { INDEX_op_neg_i64, { "r", "r" } }, - { INDEX_op_not_i64, { "r", "r" } }, - { INDEX_op_ext8s_i64, { "r", "r" } }, - { INDEX_op_ext16s_i64, { "r", "r" } }, - { INDEX_op_ext32s_i64, { "r", "r" } }, - { INDEX_op_ext_i32_i64, { "r", "r" } }, - { INDEX_op_extu_i32_i64, { "r", "r" } }, - { INDEX_op_bswap16_i64, { "r", "r" } }, - { INDEX_op_bswap32_i64, { "r", "r" } }, - { INDEX_op_bswap64_i64, { "r", "r" } }, - - { INDEX_op_brcond_i64, { "r", "ri" } }, - { INDEX_op_setcond_i64, { "r", "r", "ri" } }, - { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } }, - - { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, - { INDEX_op_extract_i64, { "r", "r" } }, - - { INDEX_op_mulsh_i64, { "r", "r", "r" } }, - { INDEX_op_muluh_i64, { "r", "r", "r" } }, -#endif +static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) +{ + static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; + static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; + static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } }; + static const TCGTargetOpDef S_S = { .args_ct_str = { "S", "S" } }; + static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } }; + static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } }; + static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } }; + static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } }; + static const TCGTargetOpDef S_S_S = { .args_ct_str = { "S", "S", "S" } }; + static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } }; + static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } }; + static const TCGTargetOpDef r_r_rT = { .args_ct_str = { "r", "r", "rT" } }; + static const TCGTargetOpDef r_r_rU = { .args_ct_str = { "r", "r", "rU" } }; + static const TCGTargetOpDef r_rI_ri + = { .args_ct_str = { "r", "rI", "ri" } }; + static const TCGTargetOpDef r_rI_rT + = { .args_ct_str = { "r", "rI", "rT" } }; + static const TCGTargetOpDef r_r_rZW + = { .args_ct_str = { "r", "r", "rZW" } }; + static const TCGTargetOpDef L_L_L_L + = { .args_ct_str = { "L", "L", "L", "L" } }; + static const TCGTargetOpDef S_S_S_S + = { .args_ct_str = { "S", "S", "S", "S" } }; + static const TCGTargetOpDef movc + = { .args_ct_str = { "r", "r", "ri", "rZ", "rZ" } }; + static const TCGTargetOpDef dep + = { .args_ct_str = { "r", "0", "rZ" } }; + static const TCGTargetOpDef br2 + = { .args_ct_str = { "r", "r", "ri", "ri" } }; + static const TCGTargetOpDef setc2 + = { .args_ct_str = { "r", "r", "r", "ri", "ri" } }; + static const TCGTargetOpDef add2 + = { .args_ct_str = { "r", "r", "r", "r", "rI", "rZM" } }; + static const TCGTargetOpDef sub2 + = { .args_ct_str = { "r", "r", "rI", "rZM", "r", "r" } }; + + switch (op) { + case INDEX_op_goto_ptr: + return &r; -#if TCG_TARGET_REG_BITS == 32 - { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } }, - { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } }, -#endif + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + case INDEX_op_ctpop_i32: + case INDEX_op_neg_i32: + case INDEX_op_not_i32: + case INDEX_op_ext8s_i32: + case INDEX_op_ext16s_i32: + case INDEX_op_bswap16_i32: + case INDEX_op_bswap32_i32: + case INDEX_op_extract_i32: + case INDEX_op_ld8u_i64: + case INDEX_op_ld8s_i64: + case INDEX_op_ld16u_i64: + case INDEX_op_ld16s_i64: + case INDEX_op_ld32u_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld_i64: + case INDEX_op_st8_i64: + case INDEX_op_st16_i64: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: + case INDEX_op_ctpop_i64: + case INDEX_op_neg_i64: + case INDEX_op_not_i64: + case INDEX_op_ext8s_i64: + case INDEX_op_ext16s_i64: + case INDEX_op_ext32s_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + case INDEX_op_bswap16_i64: + case INDEX_op_bswap32_i64: + case INDEX_op_bswap64_i64: + case INDEX_op_extract_i64: + return &r_r; -#if TCG_TARGET_REG_BITS == 64 - { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } }, - { INDEX_op_sub2_i64, { "r", "r", "rI", "rZM", "r", "r" } }, -#else - { INDEX_op_add2_i32, { "r", "r", "r", "r", "rI", "rZM" } }, - { INDEX_op_sub2_i32, { "r", "r", "rI", "rZM", "r", "r" } }, -#endif + case INDEX_op_add_i32: + case INDEX_op_and_i32: + case INDEX_op_or_i32: + case INDEX_op_xor_i32: + case INDEX_op_andc_i32: + case INDEX_op_orc_i32: + case INDEX_op_eqv_i32: + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + case INDEX_op_rotl_i32: + case INDEX_op_rotr_i32: + case INDEX_op_setcond_i32: + case INDEX_op_and_i64: + case INDEX_op_andc_i64: + case INDEX_op_shl_i64: + case INDEX_op_shr_i64: + case INDEX_op_sar_i64: + case INDEX_op_rotl_i64: + case INDEX_op_rotr_i64: + case INDEX_op_setcond_i64: + return &r_r_ri; + case INDEX_op_mul_i32: + case INDEX_op_mul_i64: + return &r_r_rI; + case INDEX_op_div_i32: + case INDEX_op_divu_i32: + case INDEX_op_nand_i32: + case INDEX_op_nor_i32: + case INDEX_op_muluh_i32: + case INDEX_op_mulsh_i32: + case INDEX_op_orc_i64: + case INDEX_op_eqv_i64: + case INDEX_op_nand_i64: + case INDEX_op_nor_i64: + case INDEX_op_div_i64: + case INDEX_op_divu_i64: + case INDEX_op_mulsh_i64: + case INDEX_op_muluh_i64: + return &r_r_r; + case INDEX_op_sub_i32: + return &r_rI_ri; + case INDEX_op_add_i64: + return &r_r_rT; + case INDEX_op_or_i64: + case INDEX_op_xor_i64: + return &r_r_rU; + case INDEX_op_sub_i64: + return &r_rI_rT; + case INDEX_op_clz_i32: + case INDEX_op_ctz_i32: + case INDEX_op_clz_i64: + case INDEX_op_ctz_i64: + return &r_r_rZW; -#if TCG_TARGET_REG_BITS == 64 - { INDEX_op_qemu_ld_i32, { "r", "L" } }, - { INDEX_op_qemu_st_i32, { "S", "S" } }, - { INDEX_op_qemu_ld_i64, { "r", "L" } }, - { INDEX_op_qemu_st_i64, { "S", "S" } }, -#elif TARGET_LONG_BITS == 32 - { INDEX_op_qemu_ld_i32, { "r", "L" } }, - { INDEX_op_qemu_st_i32, { "S", "S" } }, - { INDEX_op_qemu_ld_i64, { "L", "L", "L" } }, - { INDEX_op_qemu_st_i64, { "S", "S", "S" } }, -#else - { INDEX_op_qemu_ld_i32, { "r", "L", "L" } }, - { INDEX_op_qemu_st_i32, { "S", "S", "S" } }, - { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } }, - { INDEX_op_qemu_st_i64, { "S", "S", "S", "S" } }, -#endif + case INDEX_op_brcond_i32: + case INDEX_op_brcond_i64: + return &r_ri; - { INDEX_op_mb, { } }, - { -1 }, -}; + case INDEX_op_movcond_i32: + case INDEX_op_movcond_i64: + return &movc; + case INDEX_op_deposit_i32: + case INDEX_op_deposit_i64: + return &dep; + case INDEX_op_brcond2_i32: + return &br2; + case INDEX_op_setcond2_i32: + return &setc2; + case INDEX_op_add2_i64: + case INDEX_op_add2_i32: + return &add2; + case INDEX_op_sub2_i64: + case INDEX_op_sub2_i32: + return &sub2; -static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) -{ - int i, n = ARRAY_SIZE(ppc_op_defs); + case INDEX_op_qemu_ld_i32: + return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 + ? &r_L : &r_L_L); + case INDEX_op_qemu_st_i32: + return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32 + ? &S_S : &S_S_S); + case INDEX_op_qemu_ld_i64: + return (TCG_TARGET_REG_BITS == 64 ? &r_L + : TARGET_LONG_BITS == 32 ? &L_L_L : &L_L_L_L); + case INDEX_op_qemu_st_i64: + return (TCG_TARGET_REG_BITS == 64 ? &S_S + : TARGET_LONG_BITS == 32 ? &S_S_S : &S_S_S_S); - for (i = 0; i < n; ++i) { - if (ppc_op_defs[i].op == op) { - return &ppc_op_defs[i]; - } + default: + return NULL; } - return NULL; } static void tcg_target_init(TCGContext *s) @@ -2770,23 +2787,24 @@ static void tcg_target_init(TCGContext *s) } #endif - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); - tcg_regset_set32(tcg_target_call_clobber_regs, 0, - (1 << TCG_REG_R0) | - (1 << TCG_REG_R2) | - (1 << TCG_REG_R3) | - (1 << TCG_REG_R4) | - (1 << TCG_REG_R5) | - (1 << TCG_REG_R6) | - (1 << TCG_REG_R7) | - (1 << TCG_REG_R8) | - (1 << TCG_REG_R9) | - (1 << TCG_REG_R10) | - (1 << TCG_REG_R11) | - (1 << TCG_REG_R12)); - - tcg_regset_clear(s->reserved_regs); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff; + tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff; + + tcg_target_call_clobber_regs = 0; + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R7); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12); + + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */ #if defined(_CALL_SYSV) diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c index e7ab8e4df3..38a7cdab75 100644 --- a/tcg/s390/tcg-target.inc.c +++ b/tcg/s390/tcg-target.inc.c @@ -402,23 +402,23 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, switch (*ct_str++) { case 'r': /* all registers */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffff); + ct->u.regs = 0xffff; break; case 'L': /* qemu_ld/st constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffff); - tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2); - tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3); - tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4); + ct->u.regs = 0xffff; + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2); + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3); + tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4); break; case 'a': /* force R2 for division */ ct->ct |= TCG_CT_REG; - tcg_regset_clear(ct->u.regs); + ct->u.regs = 0; tcg_regset_set_reg(ct->u.regs, TCG_REG_R2); break; case 'b': /* force R3 for division */ ct->ct |= TCG_CT_REG; - tcg_regset_clear(ct->u.regs); + ct->u.regs = 0; tcg_regset_set_reg(ct->u.regs, TCG_REG_R3); break; case 'A': @@ -2519,10 +2519,10 @@ static void tcg_target_init(TCGContext *s) { query_s390_facilities(); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffff; + tcg_target_available_regs[TCG_TYPE_I64] = 0xffff; - tcg_regset_clear(tcg_target_call_clobber_regs); + tcg_target_call_clobber_regs = 0; tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2); @@ -2535,7 +2535,7 @@ static void tcg_target_init(TCGContext *s) /* The return register can be considered call-clobbered. */ tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14); - tcg_regset_clear(s->reserved_regs); + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_TMP0); /* XXX many insns can't be used with R0, so we better avoid it for now */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); diff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c index bd7c1461c6..bc673bd8c6 100644 --- a/tcg/sparc/tcg-target.inc.c +++ b/tcg/sparc/tcg-target.inc.c @@ -343,16 +343,15 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, switch (*ct_str++) { case 'r': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffffffff); + ct->u.regs = 0xffffffff; break; case 'R': ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, ALL_64); + ct->u.regs = ALL_64; break; case 'A': /* qemu_ld/st address constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, - TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff); + ct->u.regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff; reserve_helpers: tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1); @@ -360,11 +359,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, break; case 's': /* qemu_st data 32-bit constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffffffff); + ct->u.regs = 0xffffffff; goto reserve_helpers; case 'S': /* qemu_st data 64-bit constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, ALL_64); + ct->u.regs = ALL_64; goto reserve_helpers; case 'I': ct->ct |= TCG_CT_CONST_S11; @@ -1633,112 +1632,147 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } } -static const TCGTargetOpDef sparc_op_defs[] = { - { INDEX_op_exit_tb, { } }, - { INDEX_op_goto_tb, { } }, - { INDEX_op_br, { } }, - { INDEX_op_goto_ptr, { "r" } }, - - { INDEX_op_ld8u_i32, { "r", "r" } }, - { INDEX_op_ld8s_i32, { "r", "r" } }, - { INDEX_op_ld16u_i32, { "r", "r" } }, - { INDEX_op_ld16s_i32, { "r", "r" } }, - { INDEX_op_ld_i32, { "r", "r" } }, - { INDEX_op_st8_i32, { "rZ", "r" } }, - { INDEX_op_st16_i32, { "rZ", "r" } }, - { INDEX_op_st_i32, { "rZ", "r" } }, - - { INDEX_op_add_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_mul_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_div_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_divu_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_sub_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_and_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_andc_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_or_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_orc_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_xor_i32, { "r", "rZ", "rJ" } }, - - { INDEX_op_shl_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_shr_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_sar_i32, { "r", "rZ", "rJ" } }, - - { INDEX_op_neg_i32, { "r", "rJ" } }, - { INDEX_op_not_i32, { "r", "rJ" } }, - - { INDEX_op_brcond_i32, { "rZ", "rJ" } }, - { INDEX_op_setcond_i32, { "r", "rZ", "rJ" } }, - { INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } }, - - { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } }, - { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } }, - { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } }, - { INDEX_op_muls2_i32, { "r", "r", "rZ", "rJ" } }, - - { INDEX_op_ld8u_i64, { "R", "r" } }, - { INDEX_op_ld8s_i64, { "R", "r" } }, - { INDEX_op_ld16u_i64, { "R", "r" } }, - { INDEX_op_ld16s_i64, { "R", "r" } }, - { INDEX_op_ld32u_i64, { "R", "r" } }, - { INDEX_op_ld32s_i64, { "R", "r" } }, - { INDEX_op_ld_i64, { "R", "r" } }, - { INDEX_op_st8_i64, { "RZ", "r" } }, - { INDEX_op_st16_i64, { "RZ", "r" } }, - { INDEX_op_st32_i64, { "RZ", "r" } }, - { INDEX_op_st_i64, { "RZ", "r" } }, - - { INDEX_op_add_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_mul_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_div_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_divu_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_sub_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_and_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_andc_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_or_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_orc_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_xor_i64, { "R", "RZ", "RJ" } }, - - { INDEX_op_shl_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_shr_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_sar_i64, { "R", "RZ", "RJ" } }, - - { INDEX_op_neg_i64, { "R", "RJ" } }, - { INDEX_op_not_i64, { "R", "RJ" } }, - - { INDEX_op_ext32s_i64, { "R", "R" } }, - { INDEX_op_ext32u_i64, { "R", "R" } }, - { INDEX_op_ext_i32_i64, { "R", "r" } }, - { INDEX_op_extu_i32_i64, { "R", "r" } }, - { INDEX_op_extrl_i64_i32, { "r", "R" } }, - { INDEX_op_extrh_i64_i32, { "r", "R" } }, - - { INDEX_op_brcond_i64, { "RZ", "RJ" } }, - { INDEX_op_setcond_i64, { "R", "RZ", "RJ" } }, - { INDEX_op_movcond_i64, { "R", "RZ", "RJ", "RI", "0" } }, - - { INDEX_op_add2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, - { INDEX_op_sub2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } }, - { INDEX_op_muluh_i64, { "R", "RZ", "RZ" } }, - - { INDEX_op_qemu_ld_i32, { "r", "A" } }, - { INDEX_op_qemu_ld_i64, { "R", "A" } }, - { INDEX_op_qemu_st_i32, { "sZ", "A" } }, - { INDEX_op_qemu_st_i64, { "SZ", "A" } }, - - { INDEX_op_mb, { } }, - { -1 }, -}; - static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) { - int i, n = ARRAY_SIZE(sparc_op_defs); + static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; + static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; + static const TCGTargetOpDef R_r = { .args_ct_str = { "R", "r" } }; + static const TCGTargetOpDef r_R = { .args_ct_str = { "r", "R" } }; + static const TCGTargetOpDef R_R = { .args_ct_str = { "R", "R" } }; + static const TCGTargetOpDef r_A = { .args_ct_str = { "r", "A" } }; + static const TCGTargetOpDef R_A = { .args_ct_str = { "R", "A" } }; + static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } }; + static const TCGTargetOpDef RZ_r = { .args_ct_str = { "RZ", "r" } }; + static const TCGTargetOpDef sZ_A = { .args_ct_str = { "sZ", "A" } }; + static const TCGTargetOpDef SZ_A = { .args_ct_str = { "SZ", "A" } }; + static const TCGTargetOpDef rZ_rJ = { .args_ct_str = { "rZ", "rJ" } }; + static const TCGTargetOpDef RZ_RJ = { .args_ct_str = { "RZ", "RJ" } }; + static const TCGTargetOpDef R_R_R = { .args_ct_str = { "R", "R", "R" } }; + static const TCGTargetOpDef r_rZ_rJ + = { .args_ct_str = { "r", "rZ", "rJ" } }; + static const TCGTargetOpDef R_RZ_RJ + = { .args_ct_str = { "R", "RZ", "RJ" } }; + static const TCGTargetOpDef r_r_rZ_rJ + = { .args_ct_str = { "r", "r", "rZ", "rJ" } }; + static const TCGTargetOpDef movc_32 + = { .args_ct_str = { "r", "rZ", "rJ", "rI", "0" } }; + static const TCGTargetOpDef movc_64 + = { .args_ct_str = { "R", "RZ", "RJ", "RI", "0" } }; + static const TCGTargetOpDef add2_32 + = { .args_ct_str = { "r", "r", "rZ", "rZ", "rJ", "rJ" } }; + static const TCGTargetOpDef add2_64 + = { .args_ct_str = { "R", "R", "RZ", "RZ", "RJ", "RI" } }; + + switch (op) { + case INDEX_op_goto_ptr: + return &r; - for (i = 0; i < n; ++i) { - if (sparc_op_defs[i].op == op) { - return &sparc_op_defs[i]; - } + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_neg_i32: + case INDEX_op_not_i32: + return &r_r; + + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + return &rZ_r; + + case INDEX_op_add_i32: + case INDEX_op_mul_i32: + case INDEX_op_div_i32: + case INDEX_op_divu_i32: + case INDEX_op_sub_i32: + case INDEX_op_and_i32: + case INDEX_op_andc_i32: + case INDEX_op_or_i32: + case INDEX_op_orc_i32: + case INDEX_op_xor_i32: + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + case INDEX_op_setcond_i32: + return &r_rZ_rJ; + + case INDEX_op_brcond_i32: + return &rZ_rJ; + case INDEX_op_movcond_i32: + return &movc_32; + case INDEX_op_add2_i32: + case INDEX_op_sub2_i32: + return &add2_32; + case INDEX_op_mulu2_i32: + case INDEX_op_muls2_i32: + return &r_r_rZ_rJ; + + case INDEX_op_ld8u_i64: + case INDEX_op_ld8s_i64: + case INDEX_op_ld16u_i64: + case INDEX_op_ld16s_i64: + case INDEX_op_ld32u_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + return &R_r; + + case INDEX_op_st8_i64: + case INDEX_op_st16_i64: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: + return &RZ_r; + + case INDEX_op_add_i64: + case INDEX_op_mul_i64: + case INDEX_op_div_i64: + case INDEX_op_divu_i64: + case INDEX_op_sub_i64: + case INDEX_op_and_i64: + case INDEX_op_andc_i64: + case INDEX_op_or_i64: + case INDEX_op_orc_i64: + case INDEX_op_xor_i64: + case INDEX_op_shl_i64: + case INDEX_op_shr_i64: + case INDEX_op_sar_i64: + case INDEX_op_setcond_i64: + return &R_RZ_RJ; + + case INDEX_op_neg_i64: + case INDEX_op_not_i64: + case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: + return &R_R; + + case INDEX_op_extrl_i64_i32: + case INDEX_op_extrh_i64_i32: + return &r_R; + + case INDEX_op_brcond_i64: + return &RZ_RJ; + case INDEX_op_movcond_i64: + return &movc_64; + case INDEX_op_add2_i64: + case INDEX_op_sub2_i64: + return &add2_64; + case INDEX_op_muluh_i64: + return &R_R_R; + + case INDEX_op_qemu_ld_i32: + return &r_A; + case INDEX_op_qemu_ld_i64: + return &R_A; + case INDEX_op_qemu_st_i32: + return &sZ_A; + case INDEX_op_qemu_st_i64: + return &SZ_A; + + default: + return NULL; } - return NULL; } static void tcg_target_init(TCGContext *s) @@ -1752,26 +1786,27 @@ static void tcg_target_init(TCGContext *s) } #endif - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64); - - tcg_regset_set32(tcg_target_call_clobber_regs, 0, - (1 << TCG_REG_G1) | - (1 << TCG_REG_G2) | - (1 << TCG_REG_G3) | - (1 << TCG_REG_G4) | - (1 << TCG_REG_G5) | - (1 << TCG_REG_G6) | - (1 << TCG_REG_G7) | - (1 << TCG_REG_O0) | - (1 << TCG_REG_O1) | - (1 << TCG_REG_O2) | - (1 << TCG_REG_O3) | - (1 << TCG_REG_O4) | - (1 << TCG_REG_O5) | - (1 << TCG_REG_O7)); - - tcg_regset_clear(s->reserved_regs); + tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff; + tcg_target_available_regs[TCG_TYPE_I64] = ALL_64; + + tcg_target_call_clobber_regs = 0; + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G4); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G5); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G6); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G7); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O0); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O1); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O2); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O3); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O4); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O5); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O6); + tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O7); + + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */ @@ -749,6 +749,229 @@ int tcg_check_temp_count(void) } #endif +/* Return true if OP may appear in the opcode stream. + Test the runtime variable that controls each opcode. */ +bool tcg_op_supported(TCGOpcode op) +{ + switch (op) { + case INDEX_op_discard: + case INDEX_op_set_label: + case INDEX_op_call: + case INDEX_op_br: + case INDEX_op_mb: + case INDEX_op_insn_start: + case INDEX_op_exit_tb: + case INDEX_op_goto_tb: + case INDEX_op_qemu_ld_i32: + case INDEX_op_qemu_st_i32: + case INDEX_op_qemu_ld_i64: + case INDEX_op_qemu_st_i64: + return true; + + case INDEX_op_goto_ptr: + return TCG_TARGET_HAS_goto_ptr; + + case INDEX_op_mov_i32: + case INDEX_op_movi_i32: + case INDEX_op_setcond_i32: + case INDEX_op_brcond_i32: + case INDEX_op_ld8u_i32: + case INDEX_op_ld8s_i32: + case INDEX_op_ld16u_i32: + case INDEX_op_ld16s_i32: + case INDEX_op_ld_i32: + case INDEX_op_st8_i32: + case INDEX_op_st16_i32: + case INDEX_op_st_i32: + case INDEX_op_add_i32: + case INDEX_op_sub_i32: + case INDEX_op_mul_i32: + case INDEX_op_and_i32: + case INDEX_op_or_i32: + case INDEX_op_xor_i32: + case INDEX_op_shl_i32: + case INDEX_op_shr_i32: + case INDEX_op_sar_i32: + return true; + + case INDEX_op_movcond_i32: + return TCG_TARGET_HAS_movcond_i32; + case INDEX_op_div_i32: + case INDEX_op_divu_i32: + return TCG_TARGET_HAS_div_i32; + case INDEX_op_rem_i32: + case INDEX_op_remu_i32: + return TCG_TARGET_HAS_rem_i32; + case INDEX_op_div2_i32: + case INDEX_op_divu2_i32: + return TCG_TARGET_HAS_div2_i32; + case INDEX_op_rotl_i32: + case INDEX_op_rotr_i32: + return TCG_TARGET_HAS_rot_i32; + case INDEX_op_deposit_i32: + return TCG_TARGET_HAS_deposit_i32; + case INDEX_op_extract_i32: + return TCG_TARGET_HAS_extract_i32; + case INDEX_op_sextract_i32: + return TCG_TARGET_HAS_sextract_i32; + case INDEX_op_add2_i32: + return TCG_TARGET_HAS_add2_i32; + case INDEX_op_sub2_i32: + return TCG_TARGET_HAS_sub2_i32; + case INDEX_op_mulu2_i32: + return TCG_TARGET_HAS_mulu2_i32; + case INDEX_op_muls2_i32: + return TCG_TARGET_HAS_muls2_i32; + case INDEX_op_muluh_i32: + return TCG_TARGET_HAS_muluh_i32; + case INDEX_op_mulsh_i32: + return TCG_TARGET_HAS_mulsh_i32; + case INDEX_op_ext8s_i32: + return TCG_TARGET_HAS_ext8s_i32; + case INDEX_op_ext16s_i32: + return TCG_TARGET_HAS_ext16s_i32; + case INDEX_op_ext8u_i32: + return TCG_TARGET_HAS_ext8u_i32; + case INDEX_op_ext16u_i32: + return TCG_TARGET_HAS_ext16u_i32; + case INDEX_op_bswap16_i32: + return TCG_TARGET_HAS_bswap16_i32; + case INDEX_op_bswap32_i32: + return TCG_TARGET_HAS_bswap32_i32; + case INDEX_op_not_i32: + return TCG_TARGET_HAS_not_i32; + case INDEX_op_neg_i32: + return TCG_TARGET_HAS_neg_i32; + case INDEX_op_andc_i32: + return TCG_TARGET_HAS_andc_i32; + case INDEX_op_orc_i32: + return TCG_TARGET_HAS_orc_i32; + case INDEX_op_eqv_i32: + return TCG_TARGET_HAS_eqv_i32; + case INDEX_op_nand_i32: + return TCG_TARGET_HAS_nand_i32; + case INDEX_op_nor_i32: + return TCG_TARGET_HAS_nor_i32; + case INDEX_op_clz_i32: + return TCG_TARGET_HAS_clz_i32; + case INDEX_op_ctz_i32: + return TCG_TARGET_HAS_ctz_i32; + case INDEX_op_ctpop_i32: + return TCG_TARGET_HAS_ctpop_i32; + + case INDEX_op_brcond2_i32: + case INDEX_op_setcond2_i32: + return TCG_TARGET_REG_BITS == 32; + + case INDEX_op_mov_i64: + case INDEX_op_movi_i64: + case INDEX_op_setcond_i64: + case INDEX_op_brcond_i64: + case INDEX_op_ld8u_i64: + case INDEX_op_ld8s_i64: + case INDEX_op_ld16u_i64: + case INDEX_op_ld16s_i64: + case INDEX_op_ld32u_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld_i64: + case INDEX_op_st8_i64: + case INDEX_op_st16_i64: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: + case INDEX_op_add_i64: + case INDEX_op_sub_i64: + case INDEX_op_mul_i64: + case INDEX_op_and_i64: + case INDEX_op_or_i64: + case INDEX_op_xor_i64: + case INDEX_op_shl_i64: + case INDEX_op_shr_i64: + case INDEX_op_sar_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + return TCG_TARGET_REG_BITS == 64; + + case INDEX_op_movcond_i64: + return TCG_TARGET_HAS_movcond_i64; + case INDEX_op_div_i64: + case INDEX_op_divu_i64: + return TCG_TARGET_HAS_div_i64; + case INDEX_op_rem_i64: + case INDEX_op_remu_i64: + return TCG_TARGET_HAS_rem_i64; + case INDEX_op_div2_i64: + case INDEX_op_divu2_i64: + return TCG_TARGET_HAS_div2_i64; + case INDEX_op_rotl_i64: + case INDEX_op_rotr_i64: + return TCG_TARGET_HAS_rot_i64; + case INDEX_op_deposit_i64: + return TCG_TARGET_HAS_deposit_i64; + case INDEX_op_extract_i64: + return TCG_TARGET_HAS_extract_i64; + case INDEX_op_sextract_i64: + return TCG_TARGET_HAS_sextract_i64; + case INDEX_op_extrl_i64_i32: + return TCG_TARGET_HAS_extrl_i64_i32; + case INDEX_op_extrh_i64_i32: + return TCG_TARGET_HAS_extrh_i64_i32; + case INDEX_op_ext8s_i64: + return TCG_TARGET_HAS_ext8s_i64; + case INDEX_op_ext16s_i64: + return TCG_TARGET_HAS_ext16s_i64; + case INDEX_op_ext32s_i64: + return TCG_TARGET_HAS_ext32s_i64; + case INDEX_op_ext8u_i64: + return TCG_TARGET_HAS_ext8u_i64; + case INDEX_op_ext16u_i64: + return TCG_TARGET_HAS_ext16u_i64; + case INDEX_op_ext32u_i64: + return TCG_TARGET_HAS_ext32u_i64; + case INDEX_op_bswap16_i64: + return TCG_TARGET_HAS_bswap16_i64; + case INDEX_op_bswap32_i64: + return TCG_TARGET_HAS_bswap32_i64; + case INDEX_op_bswap64_i64: + return TCG_TARGET_HAS_bswap64_i64; + case INDEX_op_not_i64: + return TCG_TARGET_HAS_not_i64; + case INDEX_op_neg_i64: + return TCG_TARGET_HAS_neg_i64; + case INDEX_op_andc_i64: + return TCG_TARGET_HAS_andc_i64; + case INDEX_op_orc_i64: + return TCG_TARGET_HAS_orc_i64; + case INDEX_op_eqv_i64: + return TCG_TARGET_HAS_eqv_i64; + case INDEX_op_nand_i64: + return TCG_TARGET_HAS_nand_i64; + case INDEX_op_nor_i64: + return TCG_TARGET_HAS_nor_i64; + case INDEX_op_clz_i64: + return TCG_TARGET_HAS_clz_i64; + case INDEX_op_ctz_i64: + return TCG_TARGET_HAS_ctz_i64; + case INDEX_op_ctpop_i64: + return TCG_TARGET_HAS_ctpop_i64; + case INDEX_op_add2_i64: + return TCG_TARGET_HAS_add2_i64; + case INDEX_op_sub2_i64: + return TCG_TARGET_HAS_sub2_i64; + case INDEX_op_mulu2_i64: + return TCG_TARGET_HAS_mulu2_i64; + case INDEX_op_muls2_i64: + return TCG_TARGET_HAS_muls2_i64; + case INDEX_op_muluh_i64: + return TCG_TARGET_HAS_muluh_i64; + case INDEX_op_mulsh_i64: + return TCG_TARGET_HAS_mulsh_i64; + + case NB_OPS: + break; + } + g_assert_not_reached(); +} + /* Note: we convert the 64 bit args to 32 bit and do some alignment and endian swap. Maybe it would be better to do the alignment and endian swap in tcg_reg_alloc_call(). */ @@ -1277,7 +1500,7 @@ static void process_op_defs(TCGContext *s) /* Incomplete TCGTargetOpDef entry. */ tcg_debug_assert(ct_str != NULL); - tcg_regset_clear(def->args_ct[i].u.regs); + def->args_ct[i].u.regs = 0; def->args_ct[i].ct = 0; while (*ct_str != '\0') { switch(*ct_str) { @@ -1993,7 +2216,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs, TCGReg reg; TCGRegSet reg_ct; - tcg_regset_andnot(reg_ct, desired_regs, allocated_regs); + reg_ct = desired_regs & ~allocated_regs; order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order; /* first try free registers */ @@ -2139,7 +2362,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, TCGTemp *ts, *ots; TCGType otype, itype; - tcg_regset_set(allocated_regs, s->reserved_regs); + allocated_regs = s->reserved_regs; ots = &s->temps[args[0]]; ts = &s->temps[args[1]]; @@ -2227,8 +2450,8 @@ static void tcg_reg_alloc_op(TCGContext *s, args + nb_oargs + nb_iargs, sizeof(TCGArg) * def->nb_cargs); - tcg_regset_set(i_allocated_regs, s->reserved_regs); - tcg_regset_set(o_allocated_regs, s->reserved_regs); + i_allocated_regs = s->reserved_regs; + o_allocated_regs = s->reserved_regs; /* satisfy input constraints */ for(k = 0; k < nb_iargs; k++) { @@ -2428,7 +2651,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, } /* assign input registers */ - tcg_regset_set(allocated_regs, s->reserved_regs); + allocated_regs = s->reserved_regs; for(i = 0; i < nb_regs; i++) { arg = args[nb_oargs + i]; if (arg != TCG_CALL_DUMMY_ARG) { @@ -2441,9 +2664,8 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs, tcg_out_mov(s, ts->type, reg, ts->reg); } } else { - TCGRegSet arg_set; + TCGRegSet arg_set = 0; - tcg_regset_clear(arg_set); tcg_regset_set_reg(arg_set, reg); temp_load(s, ts, arg_set, allocated_regs); } @@ -2673,9 +2895,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) break; default: /* Sanity check that we've not introduced any unhandled opcodes. */ - if (def->flags & TCG_OPF_NOT_PRESENT) { - tcg_abort(); - } + tcg_debug_assert(tcg_op_supported(opc)); /* Note: in order to speed up the code, it would be much faster to have specialized register allocator functions for some common argument patterns */ @@ -186,16 +186,9 @@ typedef enum TCGOpcode { NB_OPS, } TCGOpcode; -#define tcg_regset_clear(d) (d) = 0 -#define tcg_regset_set(d, s) (d) = (s) -#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg) -#define tcg_regset_set_reg(d, r) (d) |= 1L << (r) -#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r)) -#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1) -#define tcg_regset_or(d, a, b) (d) = (a) | (b) -#define tcg_regset_and(d, a, b) (d) = (a) & (b) -#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b) -#define tcg_regset_not(d, a) (d) = ~(a) +#define tcg_regset_set_reg(d, r) ((d) |= (TCGRegSet)1 << (r)) +#define tcg_regset_reset_reg(d, r) ((d) &= ~((TCGRegSet)1 << (r))) +#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1) #ifndef TCG_TARGET_INSN_UNIT_SIZE # error "Missing TCG_TARGET_INSN_UNIT_SIZE" @@ -932,6 +925,8 @@ do {\ #define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T)) #endif +bool tcg_op_supported(TCGOpcode op); + void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret, int nargs, TCGArg *args); diff --git a/tcg/tci/tcg-target.inc.c b/tcg/tci/tcg-target.inc.c index 94461b2baf..913c3802a3 100644 --- a/tcg/tci/tcg-target.inc.c +++ b/tcg/tci/tcg-target.inc.c @@ -390,7 +390,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, case 'L': /* qemu_ld constraint */ case 'S': /* qemu_st constraint */ ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, BIT(TCG_TARGET_NB_REGS) - 1); + ct->u.regs = BIT(TCG_TARGET_NB_REGS) - 1; break; default: return NULL; @@ -870,16 +870,13 @@ static void tcg_target_init(TCGContext *s) tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX); /* Registers available for 32 bit operations. */ - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, - BIT(TCG_TARGET_NB_REGS) - 1); + tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1; /* Registers available for 64 bit operations. */ - tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, - BIT(TCG_TARGET_NB_REGS) - 1); + tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1; /* TODO: Which registers should be set here? */ - tcg_regset_set32(tcg_target_call_clobber_regs, 0, - BIT(TCG_TARGET_NB_REGS) - 1); + tcg_target_call_clobber_regs = BIT(TCG_TARGET_NB_REGS) - 1; - tcg_regset_clear(s->reserved_regs); + s->reserved_regs = 0; tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); /* We use negative offsets from "sp" so that we can distinguish |