Commit 17f79944 authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg: Introduce do_op3_nofail for vector expansion



This makes do_op3 match do_op2 in allowing for failure,
and thus fall back expansions.

Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent f75da298
Loading
Loading
Loading
Loading
+27 −18
Original line number Diff line number Diff line
@@ -562,7 +562,7 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece,
    }
}

static void do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
static bool do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
                   TCGv_vec b, TCGOpcode opc)
{
    TCGTemp *rt = tcgv_vec_temp(r);
@@ -580,82 +580,91 @@ static void do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
    can = tcg_can_emit_vec_op(opc, type, vece);
    if (can > 0) {
        vec_gen_3(opc, type, vece, ri, ai, bi);
    } else {
    } else if (can < 0) {
        const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL);
        tcg_debug_assert(can < 0);
        tcg_expand_vec_op(opc, type, vece, ri, ai, bi);
        tcg_swap_vecop_list(hold_list);
    } else {
        return false;
    }
    return true;
}

static void do_op3_nofail(unsigned vece, TCGv_vec r, TCGv_vec a,
                          TCGv_vec b, TCGOpcode opc)
{
    bool ok = do_op3(vece, r, a, b, opc);
    tcg_debug_assert(ok);
}

void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_add_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_add_vec);
}

void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_sub_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_sub_vec);
}

void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_mul_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_mul_vec);
}

void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_ssadd_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_ssadd_vec);
}

void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_usadd_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_usadd_vec);
}

void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_sssub_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_sssub_vec);
}

void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_ussub_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_ussub_vec);
}

void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_smin_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_smin_vec);
}

void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_umin_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_umin_vec);
}

void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_smax_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_smax_vec);
}

void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_umax_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_umax_vec);
}

void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_shlv_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_shlv_vec);
}

void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_shrv_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_shrv_vec);
}

void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
{
    do_op3(vece, r, a, b, INDEX_op_sarv_vec);
    do_op3_nofail(vece, r, a, b, INDEX_op_sarv_vec);
}

static void do_shifts(unsigned vece, TCGv_vec r, TCGv_vec a,
@@ -691,7 +700,7 @@ static void do_shifts(unsigned vece, TCGv_vec r, TCGv_vec a,
        } else {
            tcg_gen_dup_i32_vec(vece, vec_s, s);
        }
        do_op3(vece, r, a, vec_s, opc_v);
        do_op3_nofail(vece, r, a, vec_s, opc_v);
        tcg_temp_free_vec(vec_s);
    }
    tcg_swap_vecop_list(hold_list);