Merge tag 'pull-tcg-20240523' of https://gitlab.com/rth7680/qemu into staging
tcg: Introduce TCG_TARGET_HAS_tst_vec
accel/tcg: Init tb size and icount before plugin_gen_tb_end
# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmZPazYdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/hkwgAl/Qdaha8HNW+TkbL
# 3aQU914xSTbQVYKKCihe1R6tJ4jRw9zSj4Bf43f2GCNaz5GZyO2ek3DYHoYF4z/A
# OzNW1Vg2qQ+DS65EhTrvBWOko70zvTeh4eLyASxgEbCpWmsh1d2oLGO0mdjJkrfe
# UdcEXPZ+q0iXAWRFChRClYS5eeVnwYfIeOIzdeUgUezA6fD2zyBT5BgJAxgUTm9w
# jDXJqzcVypDFTSnrBxBVeV2SAVknVM6coc2BoJ/JiVSgupJZuNX7PSbwNI7GTfl/
# LfmiAQyhF78KQiK6TqrliK5mr9R0MSyLORcKQQJrh9G+lxxeO4Sd5qw7V21mVhbc
# YpLJaw==
# =SJem
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 23 May 2024 09:13:42 AM PDT
# gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg: issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate]
* tag 'pull-tcg-20240523' of https://gitlab.com/rth7680/qemu:
accel/tcg: Init tb size and icount before plugin_gen_tb_end
tcg/arm: Support TCG_TARGET_HAS_tst_vec
tcg/aarch64: Support TCG_TARGET_HAS_tst_vec
tcg: Expand TCG_COND_TST* if not TCG_TARGET_HAS_tst_vec
tcg: Introduce TCG_TARGET_HAS_tst_vec
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index c56967e..113edcf 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -214,14 +214,14 @@
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 2a1c080..21d5884 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -155,6 +155,7 @@
#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 56fc9cb..ffa8a3e5 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -2737,7 +2737,8 @@
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 @@
}
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 @@
}
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 85d5746..8bd9e6a 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -167,6 +167,7 @@
#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 6a04c73..3de5f50 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -2740,17 +2740,33 @@
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 @@
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 a43875c..fb72614 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -150,6 +150,7 @@
#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 a10d4e1..2f67a97 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -224,6 +224,7 @@
#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 fede627..29e4860 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -194,6 +194,7 @@
#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 04a7aba..e154fb1 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -173,6 +173,7 @@
#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 ae448c3..62ce9d7 100644
--- a/tcg/s390x/tcg-target.h
+++ b/tcg/s390x/tcg-target.h
@@ -163,6 +163,7 @@
#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 094298b..84af210 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -508,9 +508,11 @@
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 @@
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 @@
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,