mips.c (mips_prepare_builtin_arg): Replace icode and opno arguments with an expand_op...
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 27 Mar 2011 09:11:15 +0000 (09:11 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 27 Mar 2011 09:11:15 +0000 (09:11 +0000)
gcc/
* config/mips/mips.c (mips_prepare_builtin_arg): Replace icode and
opno arguments with an expand_operand.  Use create_input_operand.
(mips_prepare_builtin_target): Delete.
(mips_expand_builtin_insn, mips_expand_builtin_compare_1): New
functions.
(mips_expand_builtin_direct): Use create_output_operand and
mips_expand_builtin_insn.  Update call to mips_prepare_builtin_arg.
(mips_expand_builtin_movtf): Likewise.  Use mips_expand_fp_comparison.
(mips_expand_builtin_compare): Use mips_expand_fp_comparison.

From-SVN: r171571

gcc/ChangeLog
gcc/config/mips/mips.c

index ec394f2e231018e153ba468a96ec706bc26f4a11..c80e4ee2c5707bdf9d4864d5ae3e145c9be24c64 100644 (file)
@@ -1,3 +1,15 @@
+2011-03-27  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/mips/mips.c (mips_prepare_builtin_arg): Replace icode and
+       opno arguments with an expand_operand.  Use create_input_operand.
+       (mips_prepare_builtin_target): Delete.
+       (mips_expand_builtin_insn, mips_expand_builtin_compare_1): New
+       functions.
+       (mips_expand_builtin_direct): Use create_output_operand and
+       mips_expand_builtin_insn.  Update call to mips_prepare_builtin_arg.
+       (mips_expand_builtin_movtf): Likewise.  Use mips_expand_fp_comparison.
+       (mips_expand_builtin_compare): Use mips_expand_fp_comparison.
+
 2011-03-27  Ira Rosen  <ira.rosen@linaro.org>
 
        * config/arm/arm.c (arm_autovectorize_vector_sizes): New
index 878d33e1fa6e1e0a91694aaa864aa3b5271965a1..d1f6ad57fe07d92557d22948a19509be6c619b78 100644 (file)
@@ -13184,56 +13184,64 @@ mips_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
   return mips_builtin_decls[code];
 }
 
-/* Take argument ARGNO from EXP's argument list and convert it into a
-   form suitable for input operand OPNO of instruction ICODE.  Return the
-   value.  */
+/* Take argument ARGNO from EXP's argument list and convert it into
+   an expand operand.  Store the operand in *OP.  */
 
-static rtx
-mips_prepare_builtin_arg (enum insn_code icode,
-                         unsigned int opno, tree exp, unsigned int argno)
+static void
+mips_prepare_builtin_arg (struct expand_operand *op, tree exp,
+                         unsigned int argno)
 {
   tree arg;
   rtx value;
-  enum machine_mode mode;
 
   arg = CALL_EXPR_ARG (exp, argno);
   value = expand_normal (arg);
-  mode = insn_data[icode].operand[opno].mode;
-  if (!insn_data[icode].operand[opno].predicate (value, mode))
-    {
-      /* We need to get the mode from ARG for two reasons:
+  create_input_operand (op, value, TYPE_MODE (TREE_TYPE (arg)));
+}
 
-          - to cope with address operands, where MODE is the mode of the
-            memory, rather than of VALUE itself.
+/* Expand instruction ICODE as part of a built-in function sequence.
+   Use the first NOPS elements of OPS as the instruction's operands.
+   HAS_TARGET_P is true if operand 0 is a target; it is false if the
+   instruction has no target.
 
-          - to cope with special predicates like pmode_register_operand,
-            where MODE is VOIDmode.  */
-      value = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (arg)), value);
+   Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx.  */
 
-      /* Check the predicate again.  */
-      if (!insn_data[icode].operand[opno].predicate (value, mode))
-       {
-         error ("invalid argument to built-in function");
-         return const0_rtx;
-       }
+static rtx
+mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
+                         struct expand_operand *ops, bool has_target_p)
+{
+  if (!maybe_expand_insn (icode, nops, ops))
+    {
+      error ("invalid argument to built-in function");
+      return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
     }
-
-  return value;
+  return has_target_p ? ops[0].value : const0_rtx;
 }
 
-/* Return an rtx suitable for output operand OP of instruction ICODE.
-   If TARGET is non-null, try to use it where possible.  */
+/* Expand a floating-point comparison for built-in function call EXP.
+   The first NARGS arguments are the values to be compared.  ICODE is
+   the .md pattern that does the comparison and COND is the condition
+   that is being tested.  Return an rtx for the result.  */
 
 static rtx
-mips_prepare_builtin_target (enum insn_code icode, unsigned int op, rtx target)
+mips_expand_builtin_compare_1 (enum insn_code icode,
+                              enum mips_fp_condition cond,
+                              tree exp, int nargs)
 {
-  enum machine_mode mode;
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
+  int opno, argno;
 
-  mode = insn_data[icode].operand[op].mode;
-  if (target == 0 || !insn_data[icode].operand[op].predicate (target, mode))
-    target = gen_reg_rtx (mode);
+  /* The instruction should have a target operand, an operand for each
+     argument, and an operand for COND.  */
+  gcc_assert (nargs + 2 == insn_data[(int) icode].n_operands);
 
-  return target;
+  opno = 0;
+  create_output_operand (&ops[opno++], NULL_RTX,
+                        insn_data[(int) icode].operand[0].mode);
+  for (argno = 0; argno < nargs; argno++)
+    mips_prepare_builtin_arg (&ops[opno++], exp, argno);
+  create_integer_operand (&ops[opno++], (int) cond);
+  return mips_expand_builtin_insn (icode, opno, ops, true);
 }
 
 /* Expand a MIPS_BUILTIN_DIRECT or MIPS_BUILTIN_DIRECT_NO_TARGET function;
@@ -13245,44 +13253,23 @@ static rtx
 mips_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
                            bool has_target_p)
 {
-  rtx ops[MAX_RECOG_OPERANDS];
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
   int opno, argno;
 
   /* Map any target to operand 0.  */
   opno = 0;
   if (has_target_p)
-    {
-      target = mips_prepare_builtin_target (icode, opno, target);
-      ops[opno] = target;
-      opno++;
-    }
+    create_output_operand (&ops[opno++], target, TYPE_MODE (TREE_TYPE (exp)));
 
   /* Map the arguments to the other operands.  The n_operands value
      for an expander includes match_dups and match_scratches as well as
      match_operands, so n_operands is only an upper bound on the number
      of arguments to the expander function.  */
   gcc_assert (opno + call_expr_nargs (exp) <= insn_data[icode].n_operands);
-  for (argno = 0; argno < call_expr_nargs (exp); argno++, opno++)
-    ops[opno] = mips_prepare_builtin_arg (icode, opno, exp, argno);
-
-  switch (opno)
-    {
-    case 2:
-      emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
-      break;
-
-    case 3:
-      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2]));
-      break;
-
-    case 4:
-      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]));
-      break;
+  for (argno = 0; argno < call_expr_nargs (exp); argno++)
+    mips_prepare_builtin_arg (&ops[opno++], exp, argno);
 
-    default:
-      gcc_unreachable ();
-    }
-  return target;
+  return mips_expand_builtin_insn (icode, opno, ops, has_target_p);
 }
 
 /* Expand a __builtin_mips_movt_*_ps or __builtin_mips_movf_*_ps
@@ -13296,27 +13283,24 @@ mips_expand_builtin_movtf (enum mips_builtin_type type,
                           enum insn_code icode, enum mips_fp_condition cond,
                           rtx target, tree exp)
 {
-  rtx cmp_result, op0, op1;
-
-  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
-  op0 = mips_prepare_builtin_arg (icode, 1, exp, 0);
-  op1 = mips_prepare_builtin_arg (icode, 2, exp, 1);
-  emit_insn (GEN_FCN (icode) (cmp_result, op0, op1, GEN_INT (cond)));
+  struct expand_operand ops[4];
+  rtx cmp_result;
 
-  icode = CODE_FOR_mips_cond_move_tf_ps;
-  target = mips_prepare_builtin_target (icode, 0, target);
+  cmp_result = mips_expand_builtin_compare_1 (icode, cond, exp, 2);
+  create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
   if (type == MIPS_BUILTIN_MOVT)
     {
-      op1 = mips_prepare_builtin_arg (icode, 2, exp, 2);
-      op0 = mips_prepare_builtin_arg (icode, 1, exp, 3);
+      mips_prepare_builtin_arg (&ops[2], exp, 2);
+      mips_prepare_builtin_arg (&ops[1], exp, 3);
     }
   else
     {
-      op0 = mips_prepare_builtin_arg (icode, 1, exp, 2);
-      op1 = mips_prepare_builtin_arg (icode, 2, exp, 3);
+      mips_prepare_builtin_arg (&ops[1], exp, 2);
+      mips_prepare_builtin_arg (&ops[2], exp, 3);
     }
-  emit_insn (gen_mips_cond_move_tf_ps (target, op0, op1, cmp_result));
-  return target;
+  create_fixed_operand (&ops[3], cmp_result);
+  return mips_expand_builtin_insn (CODE_FOR_mips_cond_move_tf_ps,
+                                  4, ops, true);
 }
 
 /* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
@@ -13357,36 +13341,12 @@ mips_expand_builtin_compare (enum mips_builtin_type builtin_type,
                             enum insn_code icode, enum mips_fp_condition cond,
                             rtx target, tree exp)
 {
-  rtx offset, condition, cmp_result, args[MAX_RECOG_OPERANDS];
-  int argno;
+  rtx offset, condition, cmp_result;
 
   if (target == 0 || GET_MODE (target) != SImode)
     target = gen_reg_rtx (SImode);
-
-  /* The instruction should have a target operand, an operand for each
-     argument, and an operand for COND.  */
-  gcc_assert (call_expr_nargs (exp) + 2 == insn_data[icode].n_operands);
-
-  /* Prepare the operands to the comparison.  */
-  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
-  for (argno = 0; argno < call_expr_nargs (exp); argno++)
-    args[argno] = mips_prepare_builtin_arg (icode, argno + 1, exp, argno);
-
-  switch (insn_data[icode].n_operands)
-    {
-    case 4:
-      emit_insn (GEN_FCN (icode) (cmp_result, args[0], args[1],
-                                 GEN_INT (cond)));
-      break;
-
-    case 6:
-      emit_insn (GEN_FCN (icode) (cmp_result, args[0], args[1],
-                                 args[2], args[3], GEN_INT (cond)));
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
+  cmp_result = mips_expand_builtin_compare_1 (icode, cond, exp,
+                                             call_expr_nargs (exp));
 
   /* If the comparison sets more than one register, we define the result
      to be 0 if all registers are false and -1 if all registers are true.