tcg queued patches

-----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJZvo7AAAoJEGTfOOivfiFf7FgIAKEVBYVENbDD98AIOCwg4qld
 uSQDGFoLwPZvyPK6STTDY5BKyiCTsjSEIjs1wJ6r7BCLqvs8sdKKr2r7CXdG4bVG
 KKYpZXPyrpW3wDUletHm8fDBq36swYAkFl4e2z8IgFDMryqnOktJ8qHIanl3C8qN
 B5tIeNWeOGqsoc2TYjBdgG6kjDjSV2CRi0KbEA0SYr8lgpX1mFLRlRQ/WJcK90tj
 CfTKUhFFUWbv7WN00onz/NPiFnX+AuqaeQlaPvHH3AijMN2G34nCHu1zLiBqI2x7
 6kCupqA3w6p3VzKSOPtB0JNREt5IP4jj5jPGfl69NZl3EYUxi4wEktWGWt9b4Eo=
 =o5Mz
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2017-09-17 16:24:48 +01:00
commit 4f2058ded4
19 changed files with 1162 additions and 842 deletions

View File

@ -86,7 +86,6 @@ M: Richard Henderson <rth@twiddle.net>
S: Maintained S: Maintained
F: cpus.c F: cpus.c
F: exec.c F: exec.c
F: softmmu_template.h
F: accel/tcg/ F: accel/tcg/
F: include/exec/cpu*.h F: include/exec/cpu*.h
F: include/exec/exec-all.h F: include/exec/exec-all.h
@ -1604,8 +1603,7 @@ Overall
M: Riku Voipio <riku.voipio@iki.fi> M: Riku Voipio <riku.voipio@iki.fi>
S: Maintained S: Maintained
F: thunk.c F: thunk.c
F: user-exec.c F: accel/tcg/user-exec*.c
F: user-exec-stub.c
BSD user BSD user
S: Orphan S: Orphan

View File

@ -94,7 +94,7 @@ all: $(PROGS) stap
obj-y += exec.o obj-y += exec.o
obj-y += accel/ obj-y += accel/
obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o 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) += tcg/tci.o
obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
obj-y += fpu/softfloat.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 -I$(SRC_PATH)/linux-user
obj-y += 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 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) -I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR)
obj-y += bsd-user/ obj-y += bsd-user/
obj-y += gdbstub.o user-exec.o user-exec-stub.o obj-y += gdbstub.o
endif #CONFIG_BSD_USER endif #CONFIG_BSD_USER

View File

@ -1,4 +1,8 @@
obj-$(CONFIG_SOFTMMU) += tcg-all.o obj-$(CONFIG_SOFTMMU) += tcg-all.o
obj-$(CONFIG_SOFTMMU) += cputlb.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 += cpu-exec.o cpu-exec-common.o translate-all.o
obj-y += translator.o obj-y += translator.o
obj-$(CONFIG_USER_ONLY) += user-exec.o
obj-$(call lnot,$(CONFIG_SOFTMMU)) += user-exec-stub.o

View File

@ -178,57 +178,3 @@ void HELPER(exit_atomic)(CPUArchState *env)
{ {
cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); 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 */

View File

@ -24,6 +24,7 @@
#include "qemu/bitops.h" #include "qemu/bitops.h"
#include "exec/cpu_ldst.h" #include "exec/cpu_ldst.h"
#include "translate-all.h" #include "translate-all.h"
#include "exec/helper-proto.h"
#undef EAX #undef EAX
#undef ECX #undef ECX
@ -573,3 +574,54 @@ int cpu_signal_handler(int host_signum, void *pinfo,
#error host CPU specific signal handler needed #error host CPU specific signal handler needed
#endif #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 */

View File

@ -121,11 +121,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
switch (*ct_str++) { switch (*ct_str++) {
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1); ct->u.regs = 0xffffffffu;
break; break;
case 'l': /* qemu_ld / qemu_st address, data_reg */ case 'l': /* qemu_ld / qemu_st address, data_reg */
ct->ct |= TCG_CT_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 #ifdef CONFIG_SOFTMMU
/* x0 and x1 will be overwritten when reading the tlb entry, /* x0 and x1 will be overwritten when reading the tlb entry,
and x2, and x3 for helper args, better to avoid using them. */ 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 #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) 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" } };
for (i = 0; i < n; ++i) { switch (op) {
if (aarch64_op_defs[i].op == op) { case INDEX_op_goto_ptr:
return &aarch64_op_defs[i]; return &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_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) static void tcg_target_init(TCGContext *s)
{ {
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffffu;
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffffu;
tcg_regset_set32(tcg_target_call_clobber_regs, 0, tcg_target_call_clobber_regs = 0xfffffffu;
(1 << TCG_REG_X0) | (1 << TCG_REG_X1) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X19);
(1 << TCG_REG_X2) | (1 << TCG_REG_X3) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X20);
(1 << TCG_REG_X4) | (1 << TCG_REG_X5) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X21);
(1 << TCG_REG_X6) | (1 << TCG_REG_X7) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X22);
(1 << TCG_REG_X8) | (1 << TCG_REG_X9) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X23);
(1 << TCG_REG_X10) | (1 << TCG_REG_X11) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X24);
(1 << TCG_REG_X12) | (1 << TCG_REG_X13) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X25);
(1 << TCG_REG_X14) | (1 << TCG_REG_X15) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X26);
(1 << TCG_REG_X16) | (1 << TCG_REG_X17) | tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X27);
(1 << TCG_REG_X18) | (1 << TCG_REG_X30)); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X28);
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X29);
tcg_regset_clear(s->reserved_regs); s->reserved_regs = 0;
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); 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_FP);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);

View File

@ -264,13 +264,13 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1); ct->u.regs = 0xffff;
break; break;
/* qemu_ld address */ /* qemu_ld address */
case 'l': case 'l':
ct->ct |= TCG_CT_REG; 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 #ifdef CONFIG_SOFTMMU
/* r0-r2,lr will be overwritten when reading the tlb entry, /* r0-r2,lr will be overwritten when reading the tlb entry,
so don't use these. */ so don't use these. */
@ -284,7 +284,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
/* qemu_st address & data */ /* qemu_st address & data */
case 's': case 's':
ct->ct |= TCG_CT_REG; 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) /* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
and r0-r1 doing the byte swapping, so don't use these. */ and r0-r1 doing the byte swapping, so don't use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); 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" } },
{ INDEX_op_deposit_i32, { "r", "0", "rZ" } },
{ INDEX_op_extract_i32, { "r", "r" } },
{ INDEX_op_sextract_i32, { "r", "r" } },
{ INDEX_op_div_i32, { "r", "r", "r" } },
{ INDEX_op_divu_i32, { "r", "r", "r" } },
{ INDEX_op_mb, { } },
{ -1 },
};
static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
{ {
int i, n = ARRAY_SIZE(arm_op_defs); 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" } };
for (i = 0; i < n; ++i) { switch (op) {
if (arm_op_defs[i].op == op) { case INDEX_op_goto_ptr:
return &arm_op_defs[i]; return &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;
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;
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;
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;
default:
return NULL;
} }
return NULL;
} }
static void tcg_target_init(TCGContext *s) 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_target_available_regs[TCG_TYPE_I32] = 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_regset_clear(s->reserved_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);
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);
s->reserved_regs = 0;
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); 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_TMP);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC); tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);

View File

@ -193,23 +193,15 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
break; break;
case 'q': case 'q':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) { ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf;
tcg_regset_set32(ct->u.regs, 0, 0xffff);
} else {
tcg_regset_set32(ct->u.regs, 0, 0xf);
}
break; break;
case 'Q': case 'Q':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xf); ct->u.regs = 0xf;
break; break;
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) { ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
tcg_regset_set32(ct->u.regs, 0, 0xffff);
} else {
tcg_regset_set32(ct->u.regs, 0, 0xff);
}
break; break;
case 'W': case 'W':
/* With TZCNT/LZCNT, we can have operand-size as an input. */ /* 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 */ /* qemu_ld/st address constraint */
case 'L': case 'L':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) { ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
tcg_regset_set32(ct->u.regs, 0, 0xffff);
} else {
tcg_regset_set32(ct->u.regs, 0, 0xff);
}
tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1); tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
break; break;
@ -2643,13 +2631,13 @@ static void tcg_target_init(TCGContext *s)
#endif /* CONFIG_CPUID_H */ #endif /* CONFIG_CPUID_H */
if (TCG_TARGET_REG_BITS == 64) { if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff); tcg_target_available_regs[TCG_TYPE_I64] = 0xffff;
} else { } 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_EAX);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX); 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_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); tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
} }

View File

@ -195,11 +195,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
switch(*ct_str++) { switch(*ct_str++) {
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set(ct->u.regs, 0xffffffff); ct->u.regs = 0xffffffff;
break; break;
case 'L': /* qemu_ld input arg constraint */ case 'L': /* qemu_ld input arg constraint */
ct->ct |= TCG_CT_REG; 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); tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
@ -209,7 +209,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
break; break;
case 'S': /* qemu_st constraint */ case 'S': /* qemu_st constraint */
ct->ct |= TCG_CT_REG; 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); tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
#if defined(CONFIG_SOFTMMU) #if defined(CONFIG_SOFTMMU)
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) { 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" } },
{ 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", "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" } },
#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
#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
{ INDEX_op_mb, { } },
{ -1 },
};
static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
{ {
int i, n = ARRAY_SIZE(mips_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 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" } };
for (i = 0; i < n; ++i) { switch (op) {
if (mips_op_defs[i].op == op) { case INDEX_op_goto_ptr:
return &mips_op_defs[i]; return &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;
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:
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;
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;
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;
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);
default:
return NULL;
} }
return NULL;
} }
static int tcg_target_callee_save_regs[] = { 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) static void tcg_target_init(TCGContext *s)
{ {
tcg_target_detect_isa(); 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) { if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I64], 0xffffffff); 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_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_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_K0); /* kernel use only */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */

View File

@ -260,11 +260,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
break; break;
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffffffff); ct->u.regs = 0xffffffff;
break; break;
case 'L': /* qemu_ld constraint */ case 'L': /* qemu_ld constraint */
ct->ct |= TCG_CT_REG; 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); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
@ -273,7 +273,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
break; break;
case 'S': /* qemu_st constraint */ case 'S': /* qemu_st constraint */
ct->ct |= TCG_CT_REG; 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); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4); 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; pair = (uint64_t)i2 << 32 | i1;
#endif #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); flush_icache_range(jmp_addr, jmp_addr + 8);
} else { } else {
intptr_t diff = addr - jmp_addr; 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
#if TCG_TARGET_REG_BITS == 32
{ INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
{ INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
#endif
#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
#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
{ INDEX_op_mb, { } },
{ -1 },
};
static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
{ {
int i, n = ARRAY_SIZE(ppc_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 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" } };
for (i = 0; i < n; ++i) { switch (op) {
if (ppc_op_defs[i].op == op) { case INDEX_op_goto_ptr:
return &ppc_op_defs[i]; return &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_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;
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;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
return &r_ri;
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;
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);
default:
return NULL;
} }
return NULL;
} }
static void tcg_target_init(TCGContext *s) static void tcg_target_init(TCGContext *s)
@ -2770,23 +2787,24 @@ static void tcg_target_init(TCGContext *s)
} }
#endif #endif
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); tcg_target_available_regs[TCG_TYPE_I64] = 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_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_R0); /* tcg temp */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
#if defined(_CALL_SYSV) #if defined(_CALL_SYSV)

View File

@ -402,23 +402,23 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
switch (*ct_str++) { switch (*ct_str++) {
case 'r': /* all registers */ case 'r': /* all registers */
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffff); ct->u.regs = 0xffff;
break; break;
case 'L': /* qemu_ld/st constraint */ case 'L': /* qemu_ld/st constraint */
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffff); ct->u.regs = 0xffff;
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2); 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_R3);
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4); tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
break; break;
case 'a': /* force R2 for division */ case 'a': /* force R2 for division */
ct->ct |= TCG_CT_REG; 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); tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
break; break;
case 'b': /* force R3 for division */ case 'b': /* force R3 for division */
ct->ct |= TCG_CT_REG; 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); tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
break; break;
case 'A': case 'A':
@ -2519,10 +2519,10 @@ static void tcg_target_init(TCGContext *s)
{ {
query_s390_facilities(); query_s390_facilities();
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff); tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 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_R0);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1); 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_R2);
@ -2535,7 +2535,7 @@ static void tcg_target_init(TCGContext *s)
/* The return register can be considered call-clobbered. */ /* The return register can be considered call-clobbered. */
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14); 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); 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 */ /* 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); tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);

View File

@ -343,16 +343,15 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
switch (*ct_str++) { switch (*ct_str++) {
case 'r': case 'r':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffffffff); ct->u.regs = 0xffffffff;
break; break;
case 'R': case 'R':
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, ALL_64); ct->u.regs = ALL_64;
break; break;
case 'A': /* qemu_ld/st address constraint */ case 'A': /* qemu_ld/st address constraint */
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, ct->u.regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff);
reserve_helpers: reserve_helpers:
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0); tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1); tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
@ -360,11 +359,11 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
break; break;
case 's': /* qemu_st data 32-bit constraint */ case 's': /* qemu_st data 32-bit constraint */
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, 0xffffffff); ct->u.regs = 0xffffffff;
goto reserve_helpers; goto reserve_helpers;
case 'S': /* qemu_st data 64-bit constraint */ case 'S': /* qemu_st data 64-bit constraint */
ct->ct |= TCG_CT_REG; ct->ct |= TCG_CT_REG;
tcg_regset_set32(ct->u.regs, 0, ALL_64); ct->u.regs = ALL_64;
goto reserve_helpers; goto reserve_helpers;
case 'I': case 'I':
ct->ct |= TCG_CT_CONST_S11; 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) 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" } };
for (i = 0; i < n; ++i) { switch (op) {
if (sparc_op_defs[i].op == op) { case INDEX_op_goto_ptr:
return &sparc_op_defs[i]; return &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_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) static void tcg_target_init(TCGContext *s)
@ -1752,26 +1786,27 @@ static void tcg_target_init(TCGContext *s)
} }
#endif #endif
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64); tcg_target_available_regs[TCG_TYPE_I64] = ALL_64;
tcg_regset_set32(tcg_target_call_clobber_regs, 0, tcg_target_call_clobber_regs = 0;
(1 << TCG_REG_G1) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);
(1 << TCG_REG_G2) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G2);
(1 << TCG_REG_G3) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G3);
(1 << TCG_REG_G4) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G4);
(1 << TCG_REG_G5) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G5);
(1 << TCG_REG_G6) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G6);
(1 << TCG_REG_G7) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G7);
(1 << TCG_REG_O0) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O0);
(1 << TCG_REG_O1) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O1);
(1 << TCG_REG_O2) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O2);
(1 << TCG_REG_O3) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O3);
(1 << TCG_REG_O4) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O4);
(1 << TCG_REG_O5) | tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O5);
(1 << TCG_REG_O7)); tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O6);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O7);
tcg_regset_clear(s->reserved_regs); s->reserved_regs = 0;
tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */ 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_G6); /* reserved for os */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */

242
tcg/tcg.c
View File

@ -749,6 +749,229 @@ int tcg_check_temp_count(void)
} }
#endif #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 /* 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. Maybe it would be better to do the alignment
and endian swap in tcg_reg_alloc_call(). */ and endian swap in tcg_reg_alloc_call(). */
@ -1277,7 +1500,7 @@ static void process_op_defs(TCGContext *s)
/* Incomplete TCGTargetOpDef entry. */ /* Incomplete TCGTargetOpDef entry. */
tcg_debug_assert(ct_str != NULL); 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; def->args_ct[i].ct = 0;
while (*ct_str != '\0') { while (*ct_str != '\0') {
switch(*ct_str) { switch(*ct_str) {
@ -1993,7 +2216,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet desired_regs,
TCGReg reg; TCGReg reg;
TCGRegSet reg_ct; 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; order = rev ? indirect_reg_alloc_order : tcg_target_reg_alloc_order;
/* first try free registers */ /* first try free registers */
@ -2139,7 +2362,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
TCGTemp *ts, *ots; TCGTemp *ts, *ots;
TCGType otype, itype; TCGType otype, itype;
tcg_regset_set(allocated_regs, s->reserved_regs); allocated_regs = s->reserved_regs;
ots = &s->temps[args[0]]; ots = &s->temps[args[0]];
ts = &s->temps[args[1]]; ts = &s->temps[args[1]];
@ -2227,8 +2450,8 @@ static void tcg_reg_alloc_op(TCGContext *s,
args + nb_oargs + nb_iargs, args + nb_oargs + nb_iargs,
sizeof(TCGArg) * def->nb_cargs); sizeof(TCGArg) * def->nb_cargs);
tcg_regset_set(i_allocated_regs, s->reserved_regs); i_allocated_regs = s->reserved_regs;
tcg_regset_set(o_allocated_regs, s->reserved_regs); o_allocated_regs = s->reserved_regs;
/* satisfy input constraints */ /* satisfy input constraints */
for(k = 0; k < nb_iargs; k++) { 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 */ /* assign input registers */
tcg_regset_set(allocated_regs, s->reserved_regs); allocated_regs = s->reserved_regs;
for(i = 0; i < nb_regs; i++) { for(i = 0; i < nb_regs; i++) {
arg = args[nb_oargs + i]; arg = args[nb_oargs + i];
if (arg != TCG_CALL_DUMMY_ARG) { 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); tcg_out_mov(s, ts->type, reg, ts->reg);
} }
} else { } else {
TCGRegSet arg_set; TCGRegSet arg_set = 0;
tcg_regset_clear(arg_set);
tcg_regset_set_reg(arg_set, reg); tcg_regset_set_reg(arg_set, reg);
temp_load(s, ts, arg_set, allocated_regs); temp_load(s, ts, arg_set, allocated_regs);
} }
@ -2673,9 +2895,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
break; break;
default: default:
/* Sanity check that we've not introduced any unhandled opcodes. */ /* Sanity check that we've not introduced any unhandled opcodes. */
if (def->flags & TCG_OPF_NOT_PRESENT) { tcg_debug_assert(tcg_op_supported(opc));
tcg_abort();
}
/* Note: in order to speed up the code, it would be much /* Note: in order to speed up the code, it would be much
faster to have specialized register allocator functions for faster to have specialized register allocator functions for
some common argument patterns */ some common argument patterns */

View File

@ -186,16 +186,9 @@ typedef enum TCGOpcode {
NB_OPS, NB_OPS,
} TCGOpcode; } TCGOpcode;
#define tcg_regset_clear(d) (d) = 0 #define tcg_regset_set_reg(d, r) ((d) |= (TCGRegSet)1 << (r))
#define tcg_regset_set(d, s) (d) = (s) #define tcg_regset_reset_reg(d, r) ((d) &= ~((TCGRegSet)1 << (r)))
#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg) #define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
#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)
#ifndef TCG_TARGET_INSN_UNIT_SIZE #ifndef TCG_TARGET_INSN_UNIT_SIZE
# error "Missing 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)) #define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
#endif #endif
bool tcg_op_supported(TCGOpcode op);
void tcg_gen_callN(TCGContext *s, void *func, void tcg_gen_callN(TCGContext *s, void *func,
TCGArg ret, int nargs, TCGArg *args); TCGArg ret, int nargs, TCGArg *args);

View File

@ -390,7 +390,7 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
case 'L': /* qemu_ld constraint */ case 'L': /* qemu_ld constraint */
case 'S': /* qemu_st constraint */ case 'S': /* qemu_st constraint */
ct->ct |= TCG_CT_REG; 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; break;
default: default:
return NULL; return NULL;
@ -870,16 +870,13 @@ static void tcg_target_init(TCGContext *s)
tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX); tcg_debug_assert(tcg_op_defs_max <= UINT8_MAX);
/* Registers available for 32 bit operations. */ /* Registers available for 32 bit operations. */
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1;
BIT(TCG_TARGET_NB_REGS) - 1);
/* Registers available for 64 bit operations. */ /* Registers available for 64 bit operations. */
tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1;
BIT(TCG_TARGET_NB_REGS) - 1);
/* TODO: Which registers should be set here? */ /* TODO: Which registers should be set here? */
tcg_regset_set32(tcg_target_call_clobber_regs, 0, tcg_target_call_clobber_regs = BIT(TCG_TARGET_NB_REGS) - 1;
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); tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
/* We use negative offsets from "sp" so that we can distinguish /* We use negative offsets from "sp" so that we can distinguish