@@ -192,7 +192,7 @@ extern bool have_avx2;
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 0
#define TCG_TARGET_HAS_cmpsel_vec -1
-#define TCG_TARGET_HAS_vmrgh_vec 0
+#define TCG_TARGET_HAS_vmrgh_vec 1
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
(((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
@@ -2823,6 +2823,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_umax_vec:
insn = umax_insn[vece];
goto gen_simd;
+ case INDEX_op_vmrgh_vec:
+ insn = punpckh_insn[vece];
+ goto gen_simd;
case INDEX_op_shlv_vec:
insn = shlv_insn[vece];
goto gen_simd;
@@ -3223,6 +3226,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
case INDEX_op_umin_vec:
case INDEX_op_smax_vec:
case INDEX_op_umax_vec:
+ case INDEX_op_vmrgh_vec:
case INDEX_op_shlv_vec:
case INDEX_op_shrv_vec:
case INDEX_op_sarv_vec:
@@ -3321,6 +3325,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
case INDEX_op_umax_vec:
case INDEX_op_abs_vec:
return vece <= MO_32;
+ case INDEX_op_vmrgh_vec:
+ return vece <= MO_32 ? -1 : 0;
default:
return 0;
@@ -3614,6 +3620,14 @@ static void expand_vec_cmpsel(TCGType type, unsigned vece, TCGv_vec v0,
tcg_temp_free_vec(t);
}
+static void expand_vec_vmrg(TCGOpcode opc, TCGType type, unsigned vece,
+ TCGv_vec v0, TCGv_vec v1, TCGv_vec v2)
+{
+ vec_gen_3(opc, type, vece,
+ tcgv_vec_arg(v0), tcgv_vec_arg(v2),
+ tcgv_vec_arg(v1));
+}
+
void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg a0, ...)
{
@@ -3653,6 +3667,11 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg));
break;
+ case INDEX_op_vmrgh_vec:
+ v2 = temp_tcgv_vec(arg_temp(a2));
+ expand_vec_vmrg(opc, type, vece, v0, v1, v2);
+ break;
+
default:
break;
}
Signed-off-by: Stefan Brankovic <stefan.brankovic@rt-rk.com> --- tcg/i386/tcg-target.h | 2 +- tcg/i386/tcg-target.inc.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-)