This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Is vec_init<mode> allowed to FAIL?
- From: "Jan Hoogerbrugge" <jan dot hoogerbrugge at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 20 Mar 2008 16:26:02 +0100
- Subject: Is vec_init<mode> allowed to FAIL?
Hi,
I am trying to define vec_init<mode>. I can only do splats on register
values. So
operands[1] of vec_init should be registers and those registers should
be the same.
Here is some code:
(define_expand "vec_init<mode>"
[(match_operand:VEC_MODE32 0 "register_operand" "")
(match_operand 1 "register_operand" "")]
""
{
if(trimedia_expand_vector_init(operands[0], operands[1]))
DONE;
else
FAIL;
}
)
int
trimedia_expand_vector_init (rtx target, rtx vals)
{
enum machine_mode mode = GET_MODE (target);
enum machine_mode inner_mode = GET_MODE_INNER (mode);
int n_elts = GET_MODE_NUNITS (mode);
rtx elem, tmp1, tmp2;
int i;
for (i = 0; i < n_elts; ++i)
{
elem = XVECEXP (vals, 0, i);
if (CONSTANT_P (elem))
return 0;
if (!rtx_equal_p (elem, XVECEXP (vals, 0, 0)))
return 0;
}
tmp1 = gen_reg_rtx (SImode);
tmp2 = gen_reg_rtx (SImode);
if (GET_MODE_SIZE (mode) == 4)
{
if (inner_mode == QImode)
{
emit_insn (gen_packqi (tmp1, elem, elem));
emit_insn (gen_packhi (target, tmp1, tmp1));
return 1;
}
else if (inner_mode == HImode)
{
emit_insn (gen_packhi (target, elem, elem));
return 1;
}
}
else if (GET_MODE_SIZE (mode) == 8)
{
if (inner_mode == QImode)
{
emit_insn (gen_packqi (tmp1, elem, elem));
emit_insn (gen_packhi (tmp2, tmp1, tmp1));
emit_insn (gen_packsi (target, tmp2, tmp2));
return 1;
}
else if (inner_mode == HImode)
{
emit_insn (gen_packhi (tmp2, elem, elem));
emit_insn (gen_packsi (target, tmp2, tmp2));
return 1;
}
}
return 0;
}
I see however that no code is generated if trimedia_expand_vector_init()
returns 0 and the define_expand FAILs. I also see in other targets that a
vec_init always ends with a DONE. Could it be that vec_init is not allowed to
FAIL?
Regards,
Jan