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 /tcg | |
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>
Diffstat (limited to 'tcg')
-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-runtime.c | 234 | ||||
-rw-r--r-- | tcg/tcg-runtime.h | 136 | ||||
-rw-r--r-- | tcg/tcg.c | 242 | ||||
-rw-r--r-- | tcg/tcg.h | 15 | ||||
-rw-r--r-- | tcg/tci/tcg-target.inc.c | 13 |
12 files changed, 1100 insertions, 1150 deletions
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 */ diff --git a/tcg/tcg-runtime.c b/tcg/tcg-runtime.c deleted file mode 100644 index 3e23649dd7..0000000000 --- a/tcg/tcg-runtime.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Tiny Code Generator for QEMU - * - * Copyright (c) 2008 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "qemu/osdep.h" -#include "qemu/host-utils.h" -#include "cpu.h" -#include "exec/helper-proto.h" -#include "exec/cpu_ldst.h" -#include "exec/exec-all.h" -#include "exec/tb-hash.h" -#include "disas/disas.h" -#include "exec/log.h" - -/* 32-bit helpers */ - -int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2) -{ - return arg1 / arg2; -} - -int32_t HELPER(rem_i32)(int32_t arg1, int32_t arg2) -{ - return arg1 % arg2; -} - -uint32_t HELPER(divu_i32)(uint32_t arg1, uint32_t arg2) -{ - return arg1 / arg2; -} - -uint32_t HELPER(remu_i32)(uint32_t arg1, uint32_t arg2) -{ - return arg1 % arg2; -} - -/* 64-bit helpers */ - -uint64_t HELPER(shl_i64)(uint64_t arg1, uint64_t arg2) -{ - return arg1 << arg2; -} - -uint64_t HELPER(shr_i64)(uint64_t arg1, uint64_t arg2) -{ - return arg1 >> arg2; -} - -int64_t HELPER(sar_i64)(int64_t arg1, int64_t arg2) -{ - return arg1 >> arg2; -} - -int64_t HELPER(div_i64)(int64_t arg1, int64_t arg2) -{ - return arg1 / arg2; -} - -int64_t HELPER(rem_i64)(int64_t arg1, int64_t arg2) -{ - return arg1 % arg2; -} - -uint64_t HELPER(divu_i64)(uint64_t arg1, uint64_t arg2) -{ - return arg1 / arg2; -} - -uint64_t HELPER(remu_i64)(uint64_t arg1, uint64_t arg2) -{ - return arg1 % arg2; -} - -uint64_t HELPER(muluh_i64)(uint64_t arg1, uint64_t arg2) -{ - uint64_t l, h; - mulu64(&l, &h, arg1, arg2); - return h; -} - -int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2) -{ - uint64_t l, h; - muls64(&l, &h, arg1, arg2); - return h; -} - -uint32_t HELPER(clz_i32)(uint32_t arg, uint32_t zero_val) -{ - return arg ? clz32(arg) : zero_val; -} - -uint32_t HELPER(ctz_i32)(uint32_t arg, uint32_t zero_val) -{ - return arg ? ctz32(arg) : zero_val; -} - -uint64_t HELPER(clz_i64)(uint64_t arg, uint64_t zero_val) -{ - return arg ? clz64(arg) : zero_val; -} - -uint64_t HELPER(ctz_i64)(uint64_t arg, uint64_t zero_val) -{ - return arg ? ctz64(arg) : zero_val; -} - -uint32_t HELPER(clrsb_i32)(uint32_t arg) -{ - return clrsb32(arg); -} - -uint64_t HELPER(clrsb_i64)(uint64_t arg) -{ - return clrsb64(arg); -} - -uint32_t HELPER(ctpop_i32)(uint32_t arg) -{ - return ctpop32(arg); -} - -uint64_t HELPER(ctpop_i64)(uint64_t arg) -{ - return ctpop64(arg); -} - -void *HELPER(lookup_tb_ptr)(CPUArchState *env, target_ulong addr) -{ - CPUState *cpu = ENV_GET_CPU(env); - TranslationBlock *tb; - target_ulong cs_base, pc; - uint32_t flags, addr_hash; - - addr_hash = tb_jmp_cache_hash_func(addr); - tb = atomic_rcu_read(&cpu->tb_jmp_cache[addr_hash]); - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); - - if (unlikely(!(tb - && tb->pc == addr - && tb->cs_base == cs_base - && tb->flags == flags - && tb->trace_vcpu_dstate == *cpu->trace_dstate))) { - tb = tb_htable_lookup(cpu, addr, cs_base, flags); - if (!tb) { - return tcg_ctx.code_gen_epilogue; - } - atomic_set(&cpu->tb_jmp_cache[addr_hash], tb); - } - - qemu_log_mask_and_addr(CPU_LOG_EXEC, addr, - "Chain %p [%d: " TARGET_FMT_lx "] %s\n", - tb->tc_ptr, cpu->cpu_index, addr, - lookup_symbol(addr)); - return tb->tc_ptr; -} - -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/tcg/tcg-runtime.h deleted file mode 100644 index c41d38a557..0000000000 --- a/tcg/tcg-runtime.h +++ /dev/null @@ -1,136 +0,0 @@ -DEF_HELPER_FLAGS_2(div_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32) -DEF_HELPER_FLAGS_2(rem_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32) -DEF_HELPER_FLAGS_2(divu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_FLAGS_2(remu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) - -DEF_HELPER_FLAGS_2(div_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) -DEF_HELPER_FLAGS_2(rem_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) -DEF_HELPER_FLAGS_2(divu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(remu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(shl_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(shr_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) - -DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) -DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) - -DEF_HELPER_FLAGS_2(clz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_FLAGS_2(ctz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_FLAGS_2(clz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(ctz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32) -DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64) -DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32) -DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64) - -DEF_HELPER_FLAGS_2(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env, tl) - -DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env) - -#ifdef CONFIG_SOFTMMU - -DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG, - i32, env, tl, i32, i32, i32) -DEF_HELPER_FLAGS_5(atomic_cmpxchgw_be, TCG_CALL_NO_WG, - i32, env, tl, i32, i32, i32) -DEF_HELPER_FLAGS_5(atomic_cmpxchgw_le, TCG_CALL_NO_WG, - i32, env, tl, i32, i32, i32) -DEF_HELPER_FLAGS_5(atomic_cmpxchgl_be, TCG_CALL_NO_WG, - i32, env, tl, i32, i32, i32) -DEF_HELPER_FLAGS_5(atomic_cmpxchgl_le, TCG_CALL_NO_WG, - i32, env, tl, i32, i32, i32) -#ifdef CONFIG_ATOMIC64 -DEF_HELPER_FLAGS_5(atomic_cmpxchgq_be, TCG_CALL_NO_WG, - i64, env, tl, i64, i64, i32) -DEF_HELPER_FLAGS_5(atomic_cmpxchgq_le, TCG_CALL_NO_WG, - i64, env, tl, i64, i64, i32) -#endif - -#ifdef CONFIG_ATOMIC64 -#define GEN_ATOMIC_HELPERS(NAME) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_le), \ - TCG_CALL_NO_WG, i64, env, tl, i64, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_be), \ - TCG_CALL_NO_WG, i64, env, tl, i64, i32) -#else -#define GEN_ATOMIC_HELPERS(NAME) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ - DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32, i32) -#endif /* CONFIG_ATOMIC64 */ - -#else - -DEF_HELPER_FLAGS_4(atomic_cmpxchgb, TCG_CALL_NO_WG, i32, env, tl, i32, i32) -DEF_HELPER_FLAGS_4(atomic_cmpxchgw_be, TCG_CALL_NO_WG, i32, env, tl, i32, i32) -DEF_HELPER_FLAGS_4(atomic_cmpxchgw_le, TCG_CALL_NO_WG, i32, env, tl, i32, i32) -DEF_HELPER_FLAGS_4(atomic_cmpxchgl_be, TCG_CALL_NO_WG, i32, env, tl, i32, i32) -DEF_HELPER_FLAGS_4(atomic_cmpxchgl_le, TCG_CALL_NO_WG, i32, env, tl, i32, i32) -#ifdef CONFIG_ATOMIC64 -DEF_HELPER_FLAGS_4(atomic_cmpxchgq_be, TCG_CALL_NO_WG, i64, env, tl, i64, i64) -DEF_HELPER_FLAGS_4(atomic_cmpxchgq_le, TCG_CALL_NO_WG, i64, env, tl, i64, i64) -#endif - -#ifdef CONFIG_ATOMIC64 -#define GEN_ATOMIC_HELPERS(NAME) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), b), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), q_le), \ - TCG_CALL_NO_WG, i64, env, tl, i64) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), q_be), \ - TCG_CALL_NO_WG, i64, env, tl, i64) -#else -#define GEN_ATOMIC_HELPERS(NAME) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), b), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_le), \ - TCG_CALL_NO_WG, i32, env, tl, i32) \ - DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_be), \ - TCG_CALL_NO_WG, i32, env, tl, i32) -#endif /* CONFIG_ATOMIC64 */ - -#endif /* CONFIG_SOFTMMU */ - -GEN_ATOMIC_HELPERS(fetch_add) -GEN_ATOMIC_HELPERS(fetch_and) -GEN_ATOMIC_HELPERS(fetch_or) -GEN_ATOMIC_HELPERS(fetch_xor) - -GEN_ATOMIC_HELPERS(add_fetch) -GEN_ATOMIC_HELPERS(and_fetch) -GEN_ATOMIC_HELPERS(or_fetch) -GEN_ATOMIC_HELPERS(xor_fetch) - -GEN_ATOMIC_HELPERS(xchg) - -#undef GEN_ATOMIC_HELPERS @@ -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 |