On Thu, 2021-06-17 at 10:19 -0500, Bill Schmidt via Gcc-patches wrote:
> 2021-06-17  Bill Schmidt  <wschm...@linux.ibm.com>
> 

Hi,


> gcc/
>       * config/rs6000/rs6000-call.c (new_mma_expand_builtin):
>       Implement.

Ok,

> ---
>  gcc/config/rs6000/rs6000-call.c | 103 ++++++++++++++++++++++++++++++++
>  1 file changed, 103 insertions(+)
> 
> diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
> index 981eabc1187..e1b685fb874 100644
> --- a/gcc/config/rs6000/rs6000-call.c
> +++ b/gcc/config/rs6000/rs6000-call.c
> @@ -14962,6 +14962,109 @@ static rtx
>  new_mma_expand_builtin (tree exp, rtx target, insn_code icode,
>                       rs6000_gen_builtins fcode)
>  {
> +  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
> +  tree arg;
> +  call_expr_arg_iterator iter;
> +  const struct insn_operand_data *insn_op;
> +  rtx op[MAX_MMA_OPERANDS];
> +  unsigned nopnds = 0;
> +  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
> +  machine_mode tmode = VOIDmode;
> +
> +  if (!void_func)
> +    {
> +      tmode = insn_data[icode].operand[0].mode;
> +      if (!target
> +       || GET_MODE (target) != tmode
> +       || !(*insn_data[icode].operand[0].predicate) (target, tmode))
> +     target = gen_reg_rtx (tmode);
> +      op[nopnds++] = target;
> +    }
> +  else
> +    target = const0_rtx;
> +
> +  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
> +    {
> +      if (arg == error_mark_node)
> +     return const0_rtx;
> +
> +      rtx opnd;
> +      insn_op = &insn_data[icode].operand[nopnds];
> +      if (TREE_CODE (arg) == ADDR_EXPR
> +       && MEM_P (DECL_RTL (TREE_OPERAND (arg, 0))))
> +     opnd = DECL_RTL (TREE_OPERAND (arg, 0));
> +      else
> +     opnd = expand_normal (arg);
> +
> +      if (!(*insn_op->predicate) (opnd, insn_op->mode))
> +     {
> +       if (!strcmp (insn_op->constraint, "n"))
> +         {
> +           if (!CONST_INT_P (opnd))
> +             error ("argument %d must be an unsigned literal", nopnds);
> +           else
> +             error ("argument %d is an unsigned literal that is "
> +                    "out of range", nopnds);
> +           return const0_rtx;
> +         }
> +       opnd = copy_to_mode_reg (insn_op->mode, opnd);
> +     }
> +
> +      /* Some MMA instructions have INOUT accumulator operands, so force
> +      their target register to be the same as their input register.  */
> +      if (!void_func
> +       && nopnds == 1
> +       && !strcmp (insn_op->constraint, "0")
> +       && insn_op->mode == tmode
> +       && REG_P (opnd)
> +       && (*insn_data[icode].operand[0].predicate) (opnd, tmode))
> +     target = op[0] = opnd;
> +
> +      op[nopnds++] = opnd;
> +    }
> +
> +  rtx pat;
> +  switch (nopnds)
> +    {
> +    case 1:
> +      pat = GEN_FCN (icode) (op[0]);
> +      break;
> +    case 2:
> +      pat = GEN_FCN (icode) (op[0], op[1]);
> +      break;
> +    case 3:
> +      /* The ASSEMBLE builtin source operands are reversed in little-endian
> +      mode, so reorder them.  */
> +      if (fcode == RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL && !WORDS_BIG_ENDIAN)
> +     std::swap (op[1], op[2]);
> +      pat = GEN_FCN (icode) (op[0], op[1], op[2]);
> +      break;
> +    case 4:
> +      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
> +      break;
> +    case 5:
> +      /* The ASSEMBLE builtin source operands are reversed in little-endian
> +      mode, so reorder them.  */

I'd be tempted to consolidate the source operand reversal comments for
RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL and 
RS6000_BIF_ASSEMBLE_ACC_INTERNAL..  up at the start of the case
statement..  but actually i think this makes sense as-is. 
Ok.


> +      if (fcode == RS6000_BIF_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
> +     {
> +       std::swap (op[1], op[4]);
> +       std::swap (op[2], op[3]);
> +     }
> +      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
> +      break;
> +    case 6:
> +      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
> +      break;
> +    case 7:
> +      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], 
> op[6]);
> +      break;
> +    default:
> +      gcc_unreachable ();
> +    }
> +  if (!pat)
> +    return NULL_RTX;
> +  emit_insn (pat);
> +

Ok,
lgtm,
thanks
-Will

>    return target;
>  }
> 

Reply via email to