diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2019-04-30 11:02:23 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2019-05-22 15:09:43 -0400 |
commit | 38dc12947ec9106237f9cdbd428792c985cd86ae (patch) | |
tree | e9358d64ea6a91ed24c196f3add29a1f958c6416 /tcg/tcg-op-vec.c | |
parent | 532ba368a13712724137228b5e7e9435994d25e1 (diff) |
tcg: Add support for vector bitwise select
This operation performs d = (b & a) | (c & ~a), and is present
on a majority of host vector units. Include gvec expanders.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg-op-vec.c')
-rw-r--r-- | tcg/tcg-op-vec.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 543508d545..99cbf29e0b 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -88,6 +88,7 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list, case INDEX_op_dup2_vec: case INDEX_op_ld_vec: case INDEX_op_st_vec: + case INDEX_op_bitsel_vec: /* These opcodes are mandatory and should not be listed. */ g_assert_not_reached(); default: @@ -691,3 +692,28 @@ void tcg_gen_sars_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 b) { do_shifts(vece, r, a, b, INDEX_op_sars_vec, INDEX_op_sarv_vec); } + +void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a, + TCGv_vec b, TCGv_vec c) +{ + TCGTemp *rt = tcgv_vec_temp(r); + TCGTemp *at = tcgv_vec_temp(a); + TCGTemp *bt = tcgv_vec_temp(b); + TCGTemp *ct = tcgv_vec_temp(c); + TCGType type = rt->base_type; + + tcg_debug_assert(at->base_type >= type); + tcg_debug_assert(bt->base_type >= type); + tcg_debug_assert(ct->base_type >= type); + + if (TCG_TARGET_HAS_bitsel_vec) { + vec_gen_4(INDEX_op_bitsel_vec, type, MO_8, + temp_arg(rt), temp_arg(at), temp_arg(bt), temp_arg(ct)); + } else { + TCGv_vec t = tcg_temp_new_vec(type); + tcg_gen_and_vec(MO_8, t, a, b); + tcg_gen_andc_vec(MO_8, r, c, a); + tcg_gen_or_vec(MO_8, r, r, t); + tcg_temp_free_vec(t); + } +} |