aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-09-14 20:36:36 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-10-05 16:53:17 -0700
commit9bca986df88b8ea46b100e3d21cc9e653c83e0b3 (patch)
treeaadb0386c1419151d619acafc11748384b0f7b0f
parent4223c9c1c6358f65fb2df2708c86f95faf235e30 (diff)
downloadqemu-9bca986df88b8ea46b100e3d21cc9e653c83e0b3.zip
qemu-9bca986df88b8ea46b100e3d21cc9e653c83e0b3.tar.gz
qemu-9bca986df88b8ea46b100e3d21cc9e653c83e0b3.tar.bz2
tcg/s390x: Implement TCG_TARGET_HAS_bitsel_vec
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--tcg/s390x/tcg-target-con-set.h1
-rw-r--r--tcg/s390x/tcg-target.c.inc20
-rw-r--r--tcg/s390x/tcg-target.h2
3 files changed, 22 insertions, 1 deletions
diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
index 49b98f3..426dd92 100644
--- a/tcg/s390x/tcg-target-con-set.h
+++ b/tcg/s390x/tcg-target-con-set.h
@@ -26,6 +26,7 @@ C_O1_I2(r, r, ri)
C_O1_I2(r, rZ, r)
C_O1_I2(v, v, r)
C_O1_I2(v, v, v)
+C_O1_I3(v, v, v, v)
C_O1_I4(r, r, ri, r, 0)
C_O1_I4(r, r, ri, rI, 0)
C_O2_I2(b, a, 0, r)
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index 965d9ab..ae132e1 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -296,6 +296,7 @@ typedef enum S390Opcode {
VRRa_VUPH = 0xe7d7,
VRRa_VUPL = 0xe7d6,
VRRc_VX = 0xe76d,
+ VRRe_VSEL = 0xe78d,
VRRf_VLVGP = 0xe762,
VRSa_VERLL = 0xe733,
@@ -647,6 +648,18 @@ static void tcg_out_insn_VRRc(TCGContext *s, S390Opcode op,
tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, 0) | (m4 << 12));
}
+static void tcg_out_insn_VRRe(TCGContext *s, S390Opcode op,
+ TCGReg v1, TCGReg v2, TCGReg v3, TCGReg v4)
+{
+ tcg_debug_assert(is_vector_reg(v1));
+ tcg_debug_assert(is_vector_reg(v2));
+ tcg_debug_assert(is_vector_reg(v3));
+ tcg_debug_assert(is_vector_reg(v4));
+ tcg_out16(s, (op & 0xff00) | ((v1 & 0xf) << 4) | (v2 & 0xf));
+ tcg_out16(s, v3 << 12);
+ tcg_out16(s, (op & 0x00ff) | RXB(v1, v2, v3, v4) | (v4 << 12));
+}
+
static void tcg_out_insn_VRRf(TCGContext *s, S390Opcode op,
TCGReg v1, TCGReg r2, TCGReg r3)
{
@@ -2787,6 +2800,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
tcg_out_insn(s, VRRc, VMXL, a0, a1, a2, vece);
break;
+ case INDEX_op_bitsel_vec:
+ tcg_out_insn(s, VRRe, VSEL, a0, a1, a2, args[3]);
+ break;
+
case INDEX_op_cmp_vec:
switch ((TCGCond)args[3]) {
case TCG_COND_EQ:
@@ -2827,6 +2844,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
case INDEX_op_add_vec:
case INDEX_op_and_vec:
case INDEX_op_andc_vec:
+ case INDEX_op_bitsel_vec:
case INDEX_op_neg_vec:
case INDEX_op_not_vec:
case INDEX_op_or_vec:
@@ -3168,6 +3186,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_shrs_vec:
case INDEX_op_sars_vec:
return C_O1_I2(v, v, r);
+ case INDEX_op_bitsel_vec:
+ return C_O1_I3(v, v, v, v);
default:
g_assert_not_reached();
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
index a79f4f1..527ada0 100644
--- a/tcg/s390x/tcg-target.h
+++ b/tcg/s390x/tcg-target.h
@@ -157,7 +157,7 @@ extern uint64_t s390_facilities[3];
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 0
#define TCG_TARGET_HAS_minmax_vec 1
-#define TCG_TARGET_HAS_bitsel_vec 0
+#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
/* used for function call generation */