Dmitrij Pochepko <dmitrij.poche...@bell-sw.com> writes:
> +  unsigned int encoded_nelts = d->perm.encoding ().encoded_nelts ();
> +  for (unsigned int i = 0; i < encoded_nelts; ++i)
> +    if (!d->perm[i].is_constant ())
> +      return false;

I think it would be better to test this as part of the loop below.

> +
> +  /* to_constant is safe since this routine is specific to Advanced SIMD
> +     vectors.  */
> +  nelt = d->perm.length ().to_constant ();
> +  rtx insv = d->op0;
> +
> +  HOST_WIDE_INT idx = -1;
> +
> +  for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++)
> +    {
> +      if (d->perm[i].to_constant () == (HOST_WIDE_INT) i)
> +     continue;
> +      if (idx != -1)
> +     {
> +       idx = -1;
> +       break;
> +     }
> +      idx = i;
> +    }
> +
> +  if (idx == -1)
> +    {
> +      insv = d->op1;
> +      for (unsigned HOST_WIDE_INT i = 0; i < nelt; i ++)
> +     {
> +       if (d->perm[i].to_constant () == (HOST_WIDE_INT) (i + nelt))
> +         continue;
> +       if (idx != -1)
> +         return false;
> +       idx = i;
> +     }
> +
> +      if (idx == -1)
> +     return false;
> +    }
> +
> +  if (d->testing_p)
> +    return true;
> +
> +  gcc_assert (idx != -1);
> +
> +  unsigned extractindex = d->perm[idx].to_constant ();
> +  rtx extractv = d->op0;
> +  if (extractindex >= nelt)
> +    {
> +      extractv = d->op1;
> +      extractindex -= nelt;
> +    }
> +  gcc_assert (extractindex < nelt);
> +
> +  machine_mode inner_mode = GET_MODE_INNER (mode);
> +
> +  enum insn_code inscode = optab_handler (vec_set_optab, mode);
> +  gcc_assert (inscode != CODE_FOR_nothing);
> +  enum insn_code iextcode = convert_optab_handler (vec_extract_optab, mode,
> +                                                inner_mode);
> +  gcc_assert (iextcode != CODE_FOR_nothing);
> +  rtx tempinner = gen_reg_rtx (inner_mode);
> +  emit_insn (GEN_FCN (iextcode) (tempinner, extractv, GEN_INT 
> (extractindex)));
> +
> +  rtx temp = gen_reg_rtx (mode);
> +  emit_move_insn (temp, insv);
> +  emit_insn (GEN_FCN (inscode) (temp, tempinner, GEN_INT (idx)));
> +
> +  emit_move_insn (d->target, temp);

I think it'd be better to generate the target instruction directly.
We can do that by replacing:

(define_insn "*aarch64_simd_vec_copy_lane<mode>"

with:

(define_insn "@aarch64_simd_vec_copy_lane<mode>"

then using the expand_insn interface to create an instance of
code_for_aarch64_simd_vec_copy_lane (mode).

> +/* { dg-final { scan-assembler-times "\[ \t\]*ins\[ \t\]+v\[0-9\]+\.s" 4 } } 
> */

Same comment as the other patch about using {…} regexp quoting.

Thanks,
Richard

Reply via email to