aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-17 16:24:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-17 16:24:48 +0100
commit4f2058ded4feb2fa815b33b57b305c81d5016307 (patch)
tree7be54b2c17c07c8e97573ed018e805014143f52a /tcg/tcg.c
parent5ee53d1593dfc071275b13b1228c70bb88f4aaee (diff)
parent89b2e37e6506d92b00ac478e7953be6ddd7a86a9 (diff)
downloadqemu-4f2058ded4feb2fa815b33b57b305c81d5016307.zip
qemu-4f2058ded4feb2fa815b33b57b305c81d5016307.tar.gz
qemu-4f2058ded4feb2fa815b33b57b305c81d5016307.tar.bz2
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/tcg.c')
-rw-r--r--tcg/tcg.c242
1 files changed, 231 insertions, 11 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index fd8a3df..dff9999 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -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 */