2012-12-19 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Dec 2012 12:39:17 +0000 (12:39 +0000)
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Dec 2012 12:39:17 +0000 (12:39 +0000)
* target.def: Define canonicalize_comparison hook.
* targhooks.h (default_canonicalize_comparison): New prototype.
* targhooks.c (default_canonicalize_comparison): New function.
* doc/tm.texi: Add documentation for the new target hook.
* doc/tm.texi.in: Likewise.
* combine.c (try_combine): Adjust to use the target hook.
* config/alpha/alpha.h (CANONICALIZE_COMPARISON): Remove macro
definition.
* config/alpha/alpha.c (alpha_canonicalize_comparison): New
function.
(TARGET_CANONICALIZE_COMPARISON): New macro definition.
* config/arm/arm-protos.h (arm_canonicalize_comparison): Remove
prototype.
* config/arm/arm.c (arm_canonicalize_comparison): Add new
parameter.
(TARGET_CANONICALIZE_COMPARISON): New macro definition.
* config/arm/arm.h (CANONICALIZE_COMPARISON): Remove macro
definition.
* config/s390/s390-protos.h (s390_canonicalize_comparison): Remove
prototype.
* config/s390/s390.c (s390_canonicalize_comparison): Add new
parameter.
(TARGET_CANONICALIZE_COMPARISON): New macro definition.
* config/s390/s390.h (CANONICALIZE_COMPARISON): Remove macro
definition.
* config/sh/sh-protos.h (sh_canonicalize_comparison): Remove
prototype.
* config/sh/sh.c (sh_canonicalize_comparison): Add new prototype.  New
function overloading the old one.
(TARGET_CANONICALIZE_COMPARISON): New macro definition.
* config/sh/sh.h (CANONICALIZE_COMPARISON): Remove macro
definition.
* config/spu/spu.c (spu_canonicalize_comparison): New function.
(TARGET_CANONICALIZE_COMPARISON): New macro definition.
* config/spu/spu.h (CANONICALIZE_COMPARISON): Remove macro
definition.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194608 138bc75d-0d04-0410-961f-82ee72b054a4

19 files changed:
gcc/ChangeLog
gcc/combine.c
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/spu/spu.c
gcc/config/spu/spu.h
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/target.def
gcc/targhooks.h

index 34b5836..fe52e01 100644 (file)
@@ -1,3 +1,42 @@
+2012-12-19  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       * target.def: Define canonicalize_comparison hook.
+       * targhooks.h (default_canonicalize_comparison): New prototype.
+       * targhooks.c (default_canonicalize_comparison): New function.
+       * doc/tm.texi: Add documentation for the new target hook.
+       * doc/tm.texi.in: Likewise.
+       * combine.c (try_combine): Adjust to use the target hook.
+       * config/alpha/alpha.h (CANONICALIZE_COMPARISON): Remove macro
+       definition.
+       * config/alpha/alpha.c (alpha_canonicalize_comparison): New
+       function.
+       (TARGET_CANONICALIZE_COMPARISON): New macro definition.
+       * config/arm/arm-protos.h (arm_canonicalize_comparison): Remove
+       prototype.
+       * config/arm/arm.c (arm_canonicalize_comparison): Add new
+       parameter.
+       (TARGET_CANONICALIZE_COMPARISON): New macro definition.
+       * config/arm/arm.h (CANONICALIZE_COMPARISON): Remove macro
+       definition.
+       * config/s390/s390-protos.h (s390_canonicalize_comparison): Remove
+       prototype.
+       * config/s390/s390.c (s390_canonicalize_comparison): Add new
+       parameter.
+       (TARGET_CANONICALIZE_COMPARISON): New macro definition.
+       * config/s390/s390.h (CANONICALIZE_COMPARISON): Remove macro
+       definition.
+       * config/sh/sh-protos.h (sh_canonicalize_comparison): Remove
+       prototype.
+       * config/sh/sh.c (sh_canonicalize_comparison): Add new prototype.  New
+       function overloading the old one.
+       (TARGET_CANONICALIZE_COMPARISON): New macro definition.
+       * config/sh/sh.h (CANONICALIZE_COMPARISON): Remove macro
+       definition.
+       * config/spu/spu.c (spu_canonicalize_comparison): New function.
+       (TARGET_CANONICALIZE_COMPARISON): New macro definition.
+       * config/spu/spu.h (CANONICALIZE_COMPARISON): Remove macro
+       definition.
+
 2012-12-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/55730
index abd67e8..001025c 100644 (file)
@@ -494,6 +494,17 @@ static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
 static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
 
 \f
+/* Convenience wrapper for the canonicalize_comparison target hook.
+   Target hooks cannot use enum rtx_code.  */
+static inline void
+target_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1,
+                               bool op0_preserve_value)
+{
+  int code_int = (int)*code;
+  targetm.canonicalize_comparison (&code_int, op0, op1, op0_preserve_value);
+  *code = (enum rtx_code)code_int;
+}
+
 /* Try to split PATTERN found in INSN.  This returns NULL_RTX if
    PATTERN can not be split.  Otherwise, it returns an insn sequence.
    This is a wrapper around split_insns which ensures that the
@@ -2944,9 +2955,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
          compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
          compare_code = simplify_compare_const (compare_code,
                                                 op0, &op1);
-#ifdef CANONICALIZE_COMPARISON
-         CANONICALIZE_COMPARISON (compare_code, op0, op1);
-#endif
+         target_canonicalize_comparison (&compare_code, &op0, &op1, 1);
        }
 
       /* Do the rest only if op1 is const0_rtx, which may be the
@@ -11959,11 +11968,9 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
            }
        }
 
-#ifdef CANONICALIZE_COMPARISON
   /* If this machine only supports a subset of valid comparisons, see if we
      can convert an unsupported one into a supported one.  */
-  CANONICALIZE_COMPARISON (code, op0, op1);
-#endif
+  target_canonicalize_comparison (&code, &op0, &op1, 0);
 
   *pop0 = op0;
   *pop1 = op1;
index 8411218..fa2f733 100644 (file)
@@ -9686,6 +9686,30 @@ alpha_conditional_register_usage (void)
     for (i = 32; i < 63; i++)
       fixed_regs[i] = call_used_regs[i] = 1;
 }
+
+/* Canonicalize a comparison from one we don't have to one we do have.  */
+
+static void
+alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                              bool op0_preserve_value)
+{
+  if (!op0_preserve_value
+      && (*code == GE || *code == GT || *code == GEU || *code == GTU)
+      && (REG_P (*op1) || *op1 == const0_rtx))
+    {
+      rtx tem = *op0;
+      *op0 = *op1;
+      *op1 = tem;
+      *code = (int)swap_condition ((enum rtx_code)*code);
+    }
+
+  if ((*code == LT || *code == LTU)
+      && CONST_INT_P (*op1) && INTVAL (*op1) == 256)
+    {
+      *code = *code == LT ? LE : LEU;
+      *op1 = GEN_INT (255);
+    }
+}
 \f
 /* Initialize the GCC target structure.  */
 #if TARGET_ABI_OPEN_VMS
@@ -9853,6 +9877,9 @@ alpha_conditional_register_usage (void)
 #undef TARGET_CONDITIONAL_REGISTER_USAGE
 #define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage
 
+#undef TARGET_CANONICALIZE_COMPARISON
+#define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 \f
index bc14d84..a70c7f8 100644 (file)
@@ -922,26 +922,6 @@ do {                                                                            \
 #define FLOAT_STORE_FLAG_VALUE(MODE) \
   REAL_VALUE_ATOF ((TARGET_FLOAT_VAX ? "0.5" : "2.0"), (MODE))
 
-/* Canonicalize a comparison from one we don't have to one we do have.  */
-
-#define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
-  do {                                                                 \
-    if (((CODE) == GE || (CODE) == GT || (CODE) == GEU || (CODE) == GTU) \
-       && (REG_P (OP1) || (OP1) == const0_rtx))                \
-      {                                                                        \
-       rtx tem = (OP0);                                                \
-       (OP0) = (OP1);                                                  \
-       (OP1) = tem;                                                    \
-       (CODE) = swap_condition (CODE);                                 \
-      }                                                                        \
-    if (((CODE) == LT || (CODE) == LTU)                                        \
-       && CONST_INT_P (OP1) && INTVAL (OP1) == 256)                    \
-      {                                                                        \
-       (CODE) = (CODE) == LT ? LE : LEU;                               \
-       (OP1) = GEN_INT (255);                                          \
-      }                                                                        \
-  } while (0)
-
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
index d942c5b..4c61e35 100644 (file)
@@ -53,7 +53,6 @@ extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
 extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
 extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
                               HOST_WIDE_INT, rtx, rtx, int);
-extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *);
 extern int legitimate_pic_operand_p (rtx);
 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern rtx legitimize_tls_address (rtx, rtx);
index 15f9c9b..be4428b 100644 (file)
@@ -269,7 +269,8 @@ static int arm_cortex_a5_branch_cost (bool, bool);
 
 static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
                                             const unsigned char *sel);
-
+static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                                        bool op0_preserve_value);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -626,6 +627,10 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_VECTORIZE_VEC_PERM_CONST_OK \
   arm_vectorize_vec_perm_const_ok
 
+#undef TARGET_CANONICALIZE_COMPARISON
+#define TARGET_CANONICALIZE_COMPARISON \
+  arm_canonicalize_comparison
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -3543,8 +3548,9 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
    This can be done for a few constant compares, where we can make the
    immediate value easier to load.  */
 
-enum rtx_code
-arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
+static void
+arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                            bool op0_preserve_value)
 {
   enum machine_mode mode;
   unsigned HOST_WIDE_INT i, maxval;
@@ -3563,15 +3569,15 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
     {
       rtx tem;
 
-      if (code == GT || code == LE
-         || (!TARGET_ARM && (code == GTU || code == LEU)))
+      if (*code == GT || *code == LE
+         || (!TARGET_ARM && (*code == GTU || *code == LEU)))
        {
          /* Missing comparison.  First try to use an available
             comparison.  */
          if (CONST_INT_P (*op1))
            {
              i = INTVAL (*op1);
-             switch (code)
+             switch (*code)
                {
                case GT:
                case LE:
@@ -3579,7 +3585,8 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
                      && arm_const_double_by_immediates (GEN_INT (i + 1)))
                    {
                      *op1 = GEN_INT (i + 1);
-                     return code == GT ? GE : LT;
+                     *code = *code == GT ? GE : LT;
+                     return;
                    }
                  break;
                case GTU:
@@ -3588,7 +3595,8 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
                      && arm_const_double_by_immediates (GEN_INT (i + 1)))
                    {
                      *op1 = GEN_INT (i + 1);
-                     return code == GTU ? GEU : LTU;
+                     *code = *code == GTU ? GEU : LTU;
+                     return;
                    }
                  break;
                default:
@@ -3597,19 +3605,22 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
            }
 
          /* If that did not work, reverse the condition.  */
-         tem = *op0;
-         *op0 = *op1;
-         *op1 = tem;
-         return swap_condition (code);
+         if (!op0_preserve_value)
+           {
+             tem = *op0;
+             *op0 = *op1;
+             *op1 = tem;
+             *code = (int)swap_condition ((enum rtx_code)*code);
+           }
        }
-
-      return code;
+      return;
     }
 
   /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
      with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
      to facilitate possible combining with a cmp into 'ands'.  */
-  if (mode == SImode
+  if (!op0_preserve_value
+      && mode == SImode
       && GET_CODE (*op0) == ZERO_EXTEND
       && GET_CODE (XEXP (*op0, 0)) == SUBREG
       && GET_MODE (XEXP (*op0, 0)) == QImode
@@ -3624,15 +3635,15 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
   if (!CONST_INT_P (*op1)
       || const_ok_for_arm (INTVAL (*op1))
       || const_ok_for_arm (- INTVAL (*op1)))
-    return code;
+    return;
 
   i = INTVAL (*op1);
 
-  switch (code)
+  switch (*code)
     {
     case EQ:
     case NE:
-      return code;
+      return;
 
     case GT:
     case LE:
@@ -3640,7 +3651,8 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
          && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
        {
          *op1 = GEN_INT (i + 1);
-         return code == GT ? GE : LT;
+         *code = *code == GT ? GE : LT;
+         return;
        }
       break;
 
@@ -3650,7 +3662,8 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
          && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
        {
          *op1 = GEN_INT (i - 1);
-         return code == GE ? GT : LE;
+         *code = *code == GE ? GT : LE;
+         return;
        }
       break;
 
@@ -3660,7 +3673,8 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
          && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
        {
          *op1 = GEN_INT (i + 1);
-         return code == GTU ? GEU : LTU;
+         *code = *code == GTU ? GEU : LTU;
+         return;
        }
       break;
 
@@ -3670,15 +3684,14 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
          && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
        {
          *op1 = GEN_INT (i - 1);
-         return code == GEU ? GTU : LEU;
+         *code = *code == GEU ? GTU : LEU;
+         return;
        }
       break;
 
     default:
       gcc_unreachable ();
     }
-
-  return code;
 }
 
 
@@ -26981,7 +26994,7 @@ bool
 arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
 {
   enum rtx_code code = GET_CODE (*comparison);
-  enum rtx_code canonical_code;
+  int code_int;
   enum machine_mode mode = (GET_MODE (*op1) == VOIDmode) 
     ? GET_MODE (*op2) : GET_MODE (*op1);
 
@@ -26990,8 +27003,9 @@ arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
   if (code == UNEQ || code == LTGT)
     return false;
 
-  canonical_code = arm_canonicalize_comparison (code, op1, op2);
-  PUT_CODE (*comparison, canonical_code);
+  code_int = (int)code;
+  arm_canonicalize_comparison (&code_int, op1, op2, 0);
+  PUT_CODE (*comparison, (enum rtx_code)code_int);
 
   switch (mode)
     {
index d0f351d..2fa945c 100644 (file)
@@ -2078,9 +2078,6 @@ extern int making_const_table;
    ? reverse_condition_maybe_unordered (code) \
    : reverse_condition (code))
 
-#define CANONICALIZE_COMPARISON(CODE, OP0, OP1)                                \
-  (CODE) = arm_canonicalize_comparison (CODE, &(OP0), &(OP1))
-
 /* The arm5 clz instruction returns 32.  */
 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
index 79673d6..9b87914 100644 (file)
@@ -58,7 +58,6 @@ extern int tls_symbolic_operand (rtx);
 extern bool s390_match_ccmode (rtx, enum machine_mode);
 extern enum machine_mode s390_tm_ccmode (rtx, rtx, bool);
 extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
-extern void s390_canonicalize_comparison (enum rtx_code *, rtx *, rtx *);
 extern rtx s390_emit_compare (enum rtx_code, rtx, rtx);
 extern void s390_emit_jump (rtx, rtx);
 extern bool symbolic_reference_mentioned_p (rtx);
index 6517bce..441d9c1 100644 (file)
@@ -745,9 +745,13 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
    that we can implement more efficiently.  */
 
-void
-s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
+static void
+s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                             bool op0_preserve_value)
 {
+  if (op0_preserve_value)
+    return;
+
   /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
   if ((*code == EQ || *code == NE)
       && *op1 == const0_rtx
@@ -894,7 +898,7 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
   if (MEM_P (*op0) && REG_P (*op1))
     {
       rtx tem = *op0; *op0 = *op1; *op1 = tem;
-      *code = swap_condition (*code);
+      *code = (int)swap_condition ((enum rtx_code)*code);
     }
 }
 
@@ -11071,6 +11075,9 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
 #undef TARGET_UNWIND_WORD_MODE
 #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
 
+#undef TARGET_CANONICALIZE_COMPARISON
+#define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-s390.h"
index 30408f4..286046a 100644 (file)
@@ -720,10 +720,6 @@ do {                                                                       \
    return the mode to be used for the comparison.  */
 #define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y))
 
-/* Canonicalize a comparison from one we don't have to one we do have.  */
-#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-  s390_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-
 /* Relative costs of operations.  */
 
 /* A C expression for the cost of a branch instruction.  A value of 1
index d4e97db..793aada 100644 (file)
@@ -159,8 +159,6 @@ extern bool sh_expand_t_scc (rtx *);
 extern rtx sh_gen_truncate (enum machine_mode, rtx, int);
 extern bool sh_vector_mode_supported_p (enum machine_mode);
 extern bool sh_cfun_trap_exit_p (void);
-extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
-                                       enum machine_mode mode = VOIDmode);
 extern rtx sh_find_equiv_gbr_addr (rtx cur_insn, rtx mem);
 extern int sh_eval_treg_value (rtx op);
 
index cf0abb4..4a42d7e 100644 (file)
@@ -314,6 +314,9 @@ static int max_mov_insn_displacement (enum machine_mode, bool);
 static int mov_insn_alignment_mask (enum machine_mode, bool);
 static HOST_WIDE_INT disp_addr_displacement (rtx);
 static bool sequence_insn_p (rtx);
+static void sh_canonicalize_comparison (int *, rtx *, rtx *, bool);
+static void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
+                                       enum machine_mode, bool);
 
 static void sh_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
 \f
@@ -586,6 +589,9 @@ static const struct attribute_spec sh_attribute_table[] =
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P   sh_legitimate_constant_p
 
+#undef TARGET_CANONICALIZE_COMPARISON
+#define TARGET_CANONICALIZE_COMPARISON sh_canonicalize_comparison
+
 /* Machine-specific symbol_ref flags.  */
 #define SYMBOL_FLAG_FUNCVEC_FUNCTION    (SYMBOL_FLAG_MACH_DEP << 0)
 
@@ -1909,12 +1915,14 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
     }
 }
 
-/* Implement the CANONICALIZE_COMPARISON macro for the combine pass.
-   This function is also re-used to canonicalize comparisons in cbranch
-   pattern expanders.  */
-void
+/* Implement the canonicalize_comparison target hook for the combine
+   pass.  For the target hook this function is invoked via
+   sh_canonicalize_comparison.  This function is also re-used to
+   canonicalize comparisons in cbranch pattern expanders.  */
+static void
 sh_canonicalize_comparison (enum rtx_code& cmp, rtx& op0, rtx& op1,
-                           enum machine_mode mode)
+                           enum machine_mode mode,
+                           bool op0_preserve_value ATTRIBUTE_UNUSED)
 {
   /* When invoked from within the combine pass the mode is not specified,
      so try to get it from one of the operands.  */
@@ -2008,6 +2016,19 @@ sh_canonicalize_comparison (enum rtx_code& cmp, rtx& op0, rtx& op1,
     }
 }
 
+/* This function implements the canonicalize_comparison target hook.
+   This wrapper around the internally used sh_canonicalize_comparison
+   function is needed to do the enum rtx_code <-> int conversion.
+   Target hooks cannot use enum rtx_code in its definition.  */
+static void
+sh_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                           bool op0_preserve_value)
+{
+  enum rtx_code tmp_code = (enum rtx_code)*code;
+  sh_canonicalize_comparison (tmp_code, *op0, *op1,
+                             VOIDmode, op0_preserve_value);
+  *code = (int)tmp_code;
+}
 enum rtx_code
 prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
                          enum rtx_code comparison)
@@ -2021,7 +2042,8 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
   else
     scratch = operands[4];
 
-  sh_canonicalize_comparison (comparison, operands[1], operands[2], mode);
+  sh_canonicalize_comparison (comparison, operands[1], operands[2],
+                             mode, false);
 
   /* Notice that this function is also invoked after reload by
      the cbranchdi4_i pattern, through expand_cbranchdi4.  */
index 212b97d..76a5cb1 100644 (file)
@@ -1873,10 +1873,6 @@ struct sh_args {
    more compact code.  */
 #define SHIFT_COUNT_TRUNCATED (0)
 
-/* CANONICALIZE_COMPARISON macro for the combine pass.  */
-#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
-  sh_canonicalize_comparison ((CODE), (OP0), (OP1))
-
 /* All integers have the same format so truncation is easy.  */
 /* But SHmedia must sign-extend DImode when truncating to SImode.  */
 #define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) \
index 82fb434..15e7c2e 100644 (file)
@@ -7095,6 +7095,20 @@ spu_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
   final_end_function ();
 }
 
+/* Canonicalize a comparison from one we don't have to one we do have.  */
+static void
+spu_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+                            bool op0_preserve_value)
+{
+  if (!op0_preserve_value
+      && (*code == LE || *code == LT || *code == LEU || *code == LTU))
+    {
+      rtx tem = *op0;
+      *op0 = *op1;
+      *op1 = tem;
+      *code = (int)swap_condition ((enum rtx_code)*code);
+    }
+}
 \f
 /*  Table of machine attributes.  */
 static const struct attribute_spec spu_attribute_table[] =
@@ -7308,6 +7322,9 @@ static const struct attribute_spec spu_attribute_table[] =
 #undef TARGET_DELAY_VARTRACK
 #define TARGET_DELAY_VARTRACK true
 
+#undef TARGET_CANONICALIZE_COMPARISON
+#define TARGET_CANONICALIZE_COMPARISON spu_canonicalize_comparison
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-spu.h"
index ce0bc8e..031b80e 100644 (file)
@@ -520,18 +520,6 @@ do {                                                                       \
 
 #define NO_IMPLICIT_EXTERN_C 1
 
-/* Canonicalize a comparison from one we don't have to one we do have.  */
-#define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
-  do {                                                                    \
-    if (((CODE) == LE || (CODE) == LT || (CODE) == LEU || (CODE) == LTU)) \
-      {                                                                   \
-        rtx tem = (OP0);                                                  \
-        (OP0) = (OP1);                                                    \
-        (OP1) = tem;                                                      \
-        (CODE) = swap_condition (CODE);                                   \
-      }                                                                   \
-  } while (0)
-
 
 /* Address spaces.  */
 #define ADDR_SPACE_EA  1
index 3ab9987..75aa867 100644 (file)
@@ -6024,25 +6024,27 @@ You should define this macro if and only if you define extra CC modes
 in @file{@var{machine}-modes.def}.
 @end defmac
 
-@defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
+@deftypefn {Target Hook} void TARGET_CANONICALIZE_COMPARISON (int *@var{code}, rtx *@var{op0}, rtx *@var{op1}, bool @var{op0_preserve_value}) (@var{code}, @var{op0}, @var{op1}, @var{op0_preserve_value})
 On some machines not all possible comparisons are defined, but you can
 convert an invalid comparison into a valid one.  For example, the Alpha
 does not have a @code{GT} comparison, but you can use an @code{LT}
 comparison instead and swap the order of the operands.
 
-On such machines, define this macro to be a C statement to do any
-required conversions.  @var{code} is the initial comparison code
-and @var{op0} and @var{op1} are the left and right operands of the
-comparison, respectively.  You should modify @var{code}, @var{op0}, and
-@var{op1} as required.
+On such machines, implement this hook to do any required conversions.
+@var{code} is the initial comparison code and @var{op0} and @var{op1}
+are the left and right operands of the comparison, respectively.  If
+@var{op0_preserve_value} is @code{true} the implementation is not
+allowed to change the value of @var{op0} since the value might be used
+in RTXs which aren't comparisons.  E.g. the implementation is not
+allowed to swap operands in that case.
 
 GCC will not assume that the comparison resulting from this macro is
 valid but will see if the resulting insn matches a pattern in the
 @file{md} file.
 
-You need not define this macro if it would never change the comparison
-code or operands.
-@end defmac
+You need not to implement this hook if it would never change the
+comparison code or operands.
+@end deftypefn
 
 @defmac REVERSIBLE_CC_MODE (@var{mode})
 A C expression whose value is one if it is always safe to reverse a
index 6d48fe4..95fab18 100644 (file)
@@ -5928,25 +5928,27 @@ You should define this macro if and only if you define extra CC modes
 in @file{@var{machine}-modes.def}.
 @end defmac
 
-@defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
+@hook TARGET_CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1}, @var{op0_preserve_value})
 On some machines not all possible comparisons are defined, but you can
 convert an invalid comparison into a valid one.  For example, the Alpha
 does not have a @code{GT} comparison, but you can use an @code{LT}
 comparison instead and swap the order of the operands.
 
-On such machines, define this macro to be a C statement to do any
-required conversions.  @var{code} is the initial comparison code
-and @var{op0} and @var{op1} are the left and right operands of the
-comparison, respectively.  You should modify @var{code}, @var{op0}, and
-@var{op1} as required.
+On such machines, implement this hook to do any required conversions.
+@var{code} is the initial comparison code and @var{op0} and @var{op1}
+are the left and right operands of the comparison, respectively.  If
+@var{op0_preserve_value} is @code{true} the implementation is not
+allowed to change the value of @var{op0} since the value might be used
+in RTXs which aren't comparisons.  E.g. the implementation is not
+allowed to swap operands in that case.
 
 GCC will not assume that the comparison resulting from this macro is
 valid but will see if the resulting insn matches a pattern in the
 @file{md} file.
 
-You need not define this macro if it would never change the comparison
-code or operands.
-@end defmac
+You need not to implement this hook if it would never change the
+comparison code or operands.
+@end deftypefn
 
 @defmac REVERSIBLE_CC_MODE (@var{mode})
 A C expression whose value is one if it is always safe to reverse a
index 0f3164a..bbda6c2 100644 (file)
@@ -2877,6 +2877,14 @@ DEFHOOK
  enum unwind_info_type, (void),
  default_debug_unwind_info)
 
+/* The code parameter should be of type enum rtx_code but this is not
+   defined at this time.  */
+DEFHOOK
+(canonicalize_comparison,
+ "",
+ void, (int *code, rtx *op0, rtx *op1, bool op0_preserve_value),
+ default_canonicalize_comparison)
+
 DEFHOOKPOD
 (atomic_test_and_set_trueval,
  "This value should be set if the result written by\
index d419602..fc13a26 100644 (file)
@@ -179,6 +179,8 @@ extern unsigned char default_class_max_nregs (reg_class_t, enum machine_mode);
 
 extern enum unwind_info_type default_debug_unwind_info (void);
 
+extern bool default_canonicalize_comparison (int *, rtx *, rtx *, bool);
+
 extern int default_label_align_after_barrier_max_skip (rtx);
 extern int default_loop_align_max_skip (rtx);
 extern int default_label_align_max_skip (rtx);