diff options
-rw-r--r-- | accel/tcg/translator.c | 8 | ||||
-rw-r--r-- | include/tcg/tcg.h | 1 | ||||
-rw-r--r-- | tcg/aarch64/tcg-target.c.inc | 26 | ||||
-rw-r--r-- | tcg/aarch64/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/arm/tcg-target.c.inc | 23 | ||||
-rw-r--r-- | tcg/arm/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/i386/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/loongarch64/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/ppc/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/s390x/tcg-target.h | 1 | ||||
-rw-r--r-- | tcg/tcg-op-vec.c | 18 |
11 files changed, 73 insertions, 9 deletions
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index c56967eecd..113edcffe3 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -214,14 +214,14 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns, set_can_do_io(db, true); tcg_ctx->emit_before_op = NULL; + /* May be used by disas_log or plugin callbacks. */ + tb->size = db->pc_next - db->pc_first; + tb->icount = db->num_insns; + if (plugin_enabled) { plugin_gen_tb_end(cpu, db->num_insns); } - /* The disas_log hook may use these values rather than recompute. */ - tb->size = db->pc_next - db->pc_first; - tb->icount = db->num_insns; - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(db->pc_first)) { FILE *logfile = qemu_log_trylock(); diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 2a1c080bab..21d5884741 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -155,6 +155,7 @@ typedef uint64_t TCGRegSet; #define TCG_TARGET_HAS_minmax_vec 0 #define TCG_TARGET_HAS_bitsel_vec 0 #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 0 #else #define TCG_TARGET_MAYBE_vec 1 #endif diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 56fc9cb9e0..ffa8a3e519 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -2737,7 +2737,8 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, TCGCond cond = args[3]; AArch64Insn insn; - if (cond == TCG_COND_NE) { + switch (cond) { + case TCG_COND_NE: if (const_args[2]) { if (is_scalar) { tcg_out_insn(s, 3611, CMTST, vece, a0, a1, a1); @@ -2752,7 +2753,27 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, } tcg_out_insn(s, 3617, NOT, is_q, 0, a0, a0); } - } else { + break; + + case TCG_COND_TSTNE: + case TCG_COND_TSTEQ: + if (const_args[2]) { + /* (x & 0) == 0 */ + tcg_out_dupi_vec(s, type, MO_8, a0, + -(cond == TCG_COND_TSTEQ)); + break; + } + if (is_scalar) { + tcg_out_insn(s, 3611, CMTST, vece, a0, a1, a2); + } else { + tcg_out_insn(s, 3616, CMTST, is_q, vece, a0, a1, a2); + } + if (cond == TCG_COND_TSTEQ) { + tcg_out_insn(s, 3617, NOT, is_q, 0, a0, a0); + } + break; + + default: if (const_args[2]) { if (is_scalar) { insn = cmp0_scalar_insn[cond]; @@ -2791,6 +2812,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, } tcg_out_insn_3616(s, insn, is_q, vece, a0, a1, a2); } + break; } } break; diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 85d5746e47..8bd9e6a5eb 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -167,6 +167,7 @@ typedef enum { #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec 1 #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 1 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_NEED_LDST_LABELS diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 6a04c73c76..3de5f50b62 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -2740,17 +2740,33 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, case INDEX_op_cmp_vec: { TCGCond cond = args[3]; + ARMInsn insn; - if (cond == TCG_COND_NE) { + switch (cond) { + case TCG_COND_NE: if (const_args[2]) { tcg_out_vreg3(s, INSN_VTST, q, vece, a0, a1, a1); } else { tcg_out_vreg3(s, INSN_VCEQ, q, vece, a0, a1, a2); tcg_out_vreg2(s, INSN_VMVN, q, 0, a0, a0); } - } else { - ARMInsn insn; + break; + case TCG_COND_TSTNE: + case TCG_COND_TSTEQ: + if (const_args[2]) { + /* (x & 0) == 0 */ + tcg_out_dupi_vec(s, type, MO_8, a0, + -(cond == TCG_COND_TSTEQ)); + break; + } + tcg_out_vreg3(s, INSN_VTST, q, vece, a0, a1, a2); + if (cond == TCG_COND_TSTEQ) { + tcg_out_vreg2(s, INSN_VMVN, q, 0, a0, a0); + } + break; + + default: if (const_args[2]) { insn = vec_cmp0_insn[cond]; if (insn) { @@ -2769,6 +2785,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, tcg_debug_assert(insn != 0); } tcg_out_vreg3(s, insn, q, vece, a0, a1, a2); + break; } } return; diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index a43875cb09..fb7261499b 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -150,6 +150,7 @@ extern bool use_neon_instructions; #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec 1 #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 1 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_NEED_LDST_LABELS diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index a10d4e1fce..2f67a97e05 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -224,6 +224,7 @@ typedef enum { #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec have_avx512vl #define TCG_TARGET_HAS_cmpsel_vec -1 +#define TCG_TARGET_HAS_tst_vec 0 #define TCG_TARGET_deposit_i32_valid(ofs, len) \ (((ofs) == 0 && ((len) == 8 || (len) == 16)) || \ diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h index fede627bf7..29e4860d20 100644 --- a/tcg/loongarch64/tcg-target.h +++ b/tcg/loongarch64/tcg-target.h @@ -194,6 +194,7 @@ typedef enum { #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec 1 #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 0 #define TCG_TARGET_DEFAULT_MO (0) diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index 04a7aba4d3..e154fb14df 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -173,6 +173,7 @@ typedef enum { #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec have_vsx #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 0 #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_NEED_LDST_LABELS diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h index ae448c3a3a..62ce9d792a 100644 --- a/tcg/s390x/tcg-target.h +++ b/tcg/s390x/tcg-target.h @@ -163,6 +163,7 @@ extern uint64_t s390_facilities[3]; #define TCG_TARGET_HAS_minmax_vec 1 #define TCG_TARGET_HAS_bitsel_vec 1 #define TCG_TARGET_HAS_cmpsel_vec 0 +#define TCG_TARGET_HAS_tst_vec 0 /* used for function call generation */ #define TCG_TARGET_STACK_ALIGN 8 diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 094298bb27..84af210bc0 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -508,9 +508,11 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGTemp *rt = tcgv_vec_temp(r); TCGTemp *at = tcgv_vec_temp(a); TCGTemp *bt = tcgv_vec_temp(b); + TCGTemp *tt = NULL; TCGArg ri = temp_arg(rt); TCGArg ai = temp_arg(at); TCGArg bi = temp_arg(bt); + TCGArg ti; TCGType type = rt->base_type; int can; @@ -518,6 +520,18 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, tcg_debug_assert(bt->base_type >= type); tcg_assert_listed_vecop(INDEX_op_cmp_vec); can = tcg_can_emit_vec_op(INDEX_op_cmp_vec, type, vece); + + if (!TCG_TARGET_HAS_tst_vec && is_tst_cond(cond)) { + tt = tcg_temp_new_internal(type, TEMP_EBB); + ti = temp_arg(tt); + vec_gen_3(INDEX_op_and_vec, type, 0, ti, ai, bi); + at = tt; + ai = ti; + bt = tcg_constant_internal(type, 0); + bi = temp_arg(bt); + cond = tcg_tst_eqne_cond(cond); + } + if (can > 0) { vec_gen_4(INDEX_op_cmp_vec, type, vece, ri, ai, bi, cond); } else { @@ -526,6 +540,10 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, tcg_expand_vec_op(INDEX_op_cmp_vec, type, vece, ri, ai, bi, cond); tcg_swap_vecop_list(hold_list); } + + if (tt) { + tcg_temp_free_internal(tt); + } } static bool do_op3(unsigned vece, TCGv_vec r, TCGv_vec a, |