summaryrefslogtreecommitdiffstats
path: root/tcg
diff options
context:
space:
mode:
authorRichard Henderson2018-12-17 22:22:06 +0100
committerRichard Henderson2019-01-28 16:03:34 +0100
commitf550805d8309500d642f640af8d9928958465478 (patch)
treef665698007c1d6f897ae854d02768b1249979b3f /tcg
parenttcg: Add logical simplifications during gvec expand (diff)
downloadqemu-f550805d8309500d642f640af8d9928958465478.tar.gz
qemu-f550805d8309500d642f640af8d9928958465478.tar.xz
qemu-f550805d8309500d642f640af8d9928958465478.zip
tcg: Add gvec expanders for nand, nor, eqv
Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg-op-gvec.c51
-rw-r--r--tcg/tcg-op-gvec.h6
-rw-r--r--tcg/tcg-op-vec.c21
-rw-r--r--tcg/tcg-op.h3
4 files changed, 81 insertions, 0 deletions
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index ec231b78fb..81689d02f7 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -1920,6 +1920,57 @@ void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
}
}
+void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ static const GVecGen3 g = {
+ .fni8 = tcg_gen_nand_i64,
+ .fniv = tcg_gen_nand_vec,
+ .fno = gen_helper_gvec_nand,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ };
+
+ if (aofs == bofs) {
+ tcg_gen_gvec_not(vece, dofs, aofs, oprsz, maxsz);
+ } else {
+ tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+ }
+}
+
+void tcg_gen_gvec_nor(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ static const GVecGen3 g = {
+ .fni8 = tcg_gen_nor_i64,
+ .fniv = tcg_gen_nor_vec,
+ .fno = gen_helper_gvec_nor,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ };
+
+ if (aofs == bofs) {
+ tcg_gen_gvec_not(vece, dofs, aofs, oprsz, maxsz);
+ } else {
+ tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+ }
+}
+
+void tcg_gen_gvec_eqv(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ static const GVecGen3 g = {
+ .fni8 = tcg_gen_eqv_i64,
+ .fniv = tcg_gen_eqv_vec,
+ .fno = gen_helper_gvec_eqv,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ };
+
+ if (aofs == bofs) {
+ tcg_gen_gvec_dup8i(dofs, oprsz, maxsz, -1);
+ } else {
+ tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+ }
+}
+
static const GVecGen2s gop_ands = {
.fni8 = tcg_gen_and_i64,
.fniv = tcg_gen_and_vec,
diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index ff43a29a0b..d65b9d9d4c 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -242,6 +242,12 @@ void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_nor(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_eqv(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz);
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
index cefba3d185..d77fdf7c1d 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -275,6 +275,27 @@ void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
}
}
+void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
+{
+ /* TODO: Add TCG_TARGET_HAS_nand_vec when adding a backend supports it. */
+ tcg_gen_and_vec(0, r, a, b);
+ tcg_gen_not_vec(0, r, r);
+}
+
+void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
+{
+ /* TODO: Add TCG_TARGET_HAS_nor_vec when adding a backend supports it. */
+ tcg_gen_or_vec(0, r, a, b);
+ tcg_gen_not_vec(0, r, r);
+}
+
+void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
+{
+ /* TODO: Add TCG_TARGET_HAS_eqv_vec when adding a backend supports it. */
+ tcg_gen_xor_vec(0, r, a, b);
+ tcg_gen_not_vec(0, r, r);
+}
+
void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a)
{
if (TCG_TARGET_HAS_not_vec) {
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 7007ec0d4d..f6ef1cd690 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -962,6 +962,9 @@ void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
+void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
+void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
+void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a);