Commit 4cb110fb by Richard Henderson Committed by Richard Henderson

optabs.c (expand_vec_perm): Use the correct mode for scaling the selector.

        * optabs.c (expand_vec_perm): Use the correct mode for scaling the
        selector.  Save the qimode constant selector for later use by the
        qimode vec_perm pattern.

From-SVN: r180567
parent ed80f859
2011-10-27 Richard Henderson <rth@redhat.com>
* optabs.c (expand_vec_perm): Use the correct mode for scaling the
selector. Save the qimode constant selector for later use by the
qimode vec_perm pattern.
2011-10-27 Bernd Schmidt <bernds@codesourcery.com>
* config/c6x/c6x.c (unit_req_imbalance, res_mii): Cast the first arg
......@@ -6912,7 +6912,7 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
enum insn_code icode;
enum machine_mode qimode;
unsigned int i, w, e, u;
rtx tmp, sel_qi;
rtx tmp, sel_qi = NULL;
rtvec vec;
if (!target || GET_MODE (target) != mode)
......@@ -6946,9 +6946,6 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
/* Fall back to a constant byte-based permutation. */
if (qimode != VOIDmode)
{
icode = direct_optab_handler (vec_perm_const_optab, qimode);
if (icode != CODE_FOR_nothing)
{
vec = rtvec_alloc (w);
for (i = 0; i < e; ++i)
{
......@@ -6963,6 +6960,9 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
}
sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
icode = direct_optab_handler (vec_perm_const_optab, qimode);
if (icode != CODE_FOR_nothing)
{
tmp = expand_vec_perm_1 (icode, gen_lowpart (qimode, target),
gen_lowpart (qimode, v0),
gen_lowpart (qimode, v1), sel_qi);
......@@ -6989,11 +6989,16 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
if (icode == CODE_FOR_nothing)
return NULL_RTX;
if (sel_qi == NULL)
{
/* Multiply each element by its byte size. */
enum machine_mode selmode = GET_MODE (sel);
if (u == 2)
sel = expand_simple_binop (mode, PLUS, sel, sel, sel, 0, OPTAB_DIRECT);
sel = expand_simple_binop (selmode, PLUS, sel, sel,
sel, 0, OPTAB_DIRECT);
else
sel = expand_simple_binop (mode, ASHIFT, sel, GEN_INT (exact_log2 (u)),
sel = expand_simple_binop (selmode, ASHIFT, sel,
GEN_INT (exact_log2 (u)),
sel, 0, OPTAB_DIRECT);
gcc_assert (sel != NULL);
......@@ -7018,18 +7023,19 @@ expand_vec_perm (enum machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
for (i = 0; i < w; ++i)
RTVEC_ELT (vec, i) = GEN_INT (i % u);
tmp = gen_rtx_CONST_VECTOR (qimode, vec);
sel = expand_simple_binop (qimode, PLUS, sel, tmp, sel, 0, OPTAB_DIRECT);
gcc_assert (sel != NULL);
sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
sel, 0, OPTAB_DIRECT);
gcc_assert (sel_qi != NULL);
}
tmp = expand_vec_perm_1 (icode, gen_lowpart (qimode, target),
gen_lowpart (qimode, v0),
gen_lowpart (qimode, v1), sel);
gen_lowpart (qimode, v1), sel_qi);
if (tmp)
tmp = gen_lowpart (mode, tmp);
return tmp;
}
/* Return insn code for a conditional operator with a comparison in
mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment