This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Bugfix: Additional parameter for canonicalize comparison


Hi,

the attached patch fixes a problem I encountered with Richards patch
adding an extvz expander to the s390 backend.

According to its definition the CANONICALIZE_COMPARISON macro is
allowed to modify the two operands as well as the comparison code in
order to make a comparison valid or more efficient. S/390 and other
targets transform the operands while leaving the comparison
semantically equivalent. But this does *not* mean that the operands
after that transformation will resolve to the same value.  try_combine
unfortunately requires that when re-using op0 in other contexts i.e. a
SET rtx. On S/390 this happened when transforming op0 from a
ZERO_EXTRACT to and AND without adding a SHIFT. The comparison stays
equivalent but the value of op0 changes.

Other targets mostly swap the operands.  This would also be incorrect
for combine but so far didn't trigger any problems since the problem
in combine is only triggered when comparing with 0 and swapping the
operands would most likely lead to non-canonical RTL in that case.

The patch adds a boolean parameter to the canonicalize_comparison
invokation which tells the callee that the value of op0 needs to be
preserved.

While touching it I also converted the CANONICALIZE_COMPARISON target
macro into a target hook.

Tested on s390, s390x and x86_64. No regressions.
SPU tests where done by Ulrich Weigand.  No regressions either.
Compile tests on the other affected targets done via cross build.

I'll cc the target maintainers for their approval.
Ok for mainline?

Bye,

-Andreas-

2012-12-06  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 and return value.
	(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 and return value.
	(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 prototype.  New
	function. Rename old function with that name to
	sh_canonicalize_comparison_1 and add new parameter and return
	value.
	(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.


---
 gcc/combine.c                 |    8 !
 gcc/config/alpha/alpha.c      |   32 +++++++
 gcc/config/alpha/alpha.h      |   20 ----
 gcc/config/arm/arm-protos.h   |    1 
 gcc/config/arm/arm.c          |   76 +!!!!!!!!!!!!!!!!
 gcc/config/arm/arm.h          |    3 
 gcc/config/s390/s390-protos.h |    1 
 gcc/config/s390/s390.c        |   24 +++!!
 gcc/config/s390/s390.h        |    4 
 gcc/config/sh/sh-protos.h     |    2 
 gcc/config/sh/sh.c            |  175 ++++++!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 gcc/config/sh/sh.h            |    4 
 gcc/config/spu/spu.c          |   20 ++++
 gcc/config/spu/spu.h          |   12 --
 gcc/doc/tm.texi               |   22 !!!!!
 gcc/doc/tm.texi.in            |   22 !!!!!
 gcc/target.def                |    8 +
 gcc/targhooks.c               |   11 ++
 gcc/targhooks.h               |    2 
 19 files changed, 119 insertions(+), 49 deletions(-), 279 modifications(!)

Index: gcc/combine.c
===================================================================
*** gcc/combine.c.orig
--- gcc/combine.c
*************** try_combine (rtx i3, rtx i2, rtx i1, rtx
*** 2944,2952 ****
  	  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
  	}
  
        /* Do the rest only if op1 is const0_rtx, which may be the
--- 2944,2950 ----
  	  compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
  	  compare_code = simplify_compare_const (compare_code,
  						 op0, &op1);
! 	  targetm.canonicalize_comparison ((int*)&compare_code, &op0, &op1, 1);
  	}
  
        /* Do the rest only if op1 is const0_rtx, which may be the
*************** simplify_comparison (enum rtx_code code,
*** 11959,11969 ****
  	    }
  	}
  
- #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
  
    *pop0 = op0;
    *pop1 = op1;
--- 11957,11965 ----
  	    }
  	}
  
    /* If this machine only supports a subset of valid comparisons, see if we
       can convert an unsupported one into a supported one.  */
!   targetm.canonicalize_comparison ((int*)&code, &op0, &op1, 0);
  
    *pop0 = op0;
    *pop1 = op1;
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_select_ccmode (enum rtx_code code, 
*** 745,753 ****
  /* 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)
  {
    /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
    if ((*code == EQ || *code == NE)
        && *op1 == const0_rtx
--- 745,759 ----
  /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
     that we can implement more efficiently.  */
  
! static bool
! s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
! 			      bool op0_preserve_value)
  {
+   bool modified = false;
+ 
+   if (op0_preserve_value)
+     return false;
+ 
    /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
    if ((*code == EQ || *code == NE)
        && *op1 == const0_rtx
*************** s390_canonicalize_comparison (enum rtx_c
*** 771,776 ****
--- 777,783 ----
  
  	  *op0 = gen_rtx_AND (GET_MODE (inner), inner,
  			      gen_int_mode (block, GET_MODE (inner)));
+ 	  modified = true;
  	}
      }
  
*************** s390_canonicalize_comparison (enum rtx_c
*** 805,810 ****
--- 812,818 ----
  	      mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
  	      inner = adjust_address_nv (inner, QImode, part);
  	      *op0 = gen_rtx_AND (QImode, inner, mask);
+ 	      modified = true;
  	    }
  	}
      }
*************** s390_canonicalize_comparison (enum rtx_c
*** 819,824 ****
--- 827,833 ----
      {
        *op0 = gen_lowpart (HImode, *op0);
        *op1 = constm1_rtx;
+       modified = true;
      }
  
    /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible.  */
*************** s390_canonicalize_comparison (enum rtx_c
*** 846,851 ****
--- 855,861 ----
  	{
  	  *op0 = XVECEXP (*op0, 0, 0);
  	  *code = new_code;
+ 	  modified = true;
  	}
      }
  
*************** s390_canonicalize_comparison (enum rtx_c
*** 870,875 ****
--- 880,886 ----
  	{
  	  *op0 = XVECEXP (*op0, 0, 0);
  	  *code = new_code;
+ 	  modified = true;
  	}
      }
  
*************** s390_canonicalize_comparison (enum rtx_c
*** 888,901 ****
        else
  	*code = NE;
        *op0 = XEXP (*op0, 0);
      }
  
    /* Prefer register over memory as first operand.  */
    if (MEM_P (*op0) && REG_P (*op1))
      {
        rtx tem = *op0; *op0 = *op1; *op1 = tem;
!       *code = swap_condition (*code);
      }
  }
  
  /* Emit a compare instruction suitable to implement the comparison
--- 899,916 ----
        else
  	*code = NE;
        *op0 = XEXP (*op0, 0);
+       modified = true;
      }
  
    /* Prefer register over memory as first operand.  */
    if (MEM_P (*op0) && REG_P (*op1))
      {
        rtx tem = *op0; *op0 = *op1; *op1 = tem;
!       *code = (int)swap_condition ((enum rtx_code)*code);
!       modified = true;
      }
+ 
+   return modified;
  }
  
  /* Emit a compare instruction suitable to implement the comparison
*************** s390_loop_unroll_adjust (unsigned nunrol
*** 11071,11076 ****
--- 11086,11094 ----
  #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: gcc/target.def
===================================================================
*** gcc/target.def.orig
--- gcc/target.def
*************** DEFHOOK
*** 2877,2882 ****
--- 2877,2890 ----
   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,
+  "",
+  bool, (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: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig
--- gcc/targhooks.c
*************** default_debug_unwind_info (void)
*** 1414,1419 ****
--- 1414,1430 ----
    return UI_NONE;
  }
  
+ /* For targets where comparisons might need some additional
+    transformations in order to become valid or more efficient.  */
+ bool
+ default_canonicalize_comparison (int *code ATTRIBUTE_UNUSED,
+ 				 rtx *op0 ATTRIBUTE_UNUSED,
+ 				 rtx *op1 ATTRIBUTE_UNUSED,
+ 				 bool op0_preserve_value ATTRIBUTE_UNUSED)
+ {
+   return false;
+ }
+ 
  /* To be used by targets where reg_raw_mode doesn't return the right
     mode for registers used in apply_builtin_return and apply_builtin_arg.  */
  
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig
--- gcc/targhooks.h
*************** extern unsigned char default_class_max_n
*** 179,184 ****
--- 179,186 ----
  
  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);
Index: gcc/doc/tm.texi.in
===================================================================
*** gcc/doc/tm.texi.in.orig
--- gcc/doc/tm.texi.in
*************** You should define this macro if and only
*** 5930,5954 ****
  in @file{@var{machine}-modes.def}.
  @end defmac
  
! @defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
  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.
  
  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
  
  @defmac REVERSIBLE_CC_MODE (@var{mode})
  A C expression whose value is one if it is always safe to reverse a
--- 5930,5958 ----
  in @file{@var{machine}-modes.def}.
  @end defmac
  
! @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, 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.
! 
! The hook should return @code{true} if any modification was done.
  
  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 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: gcc/config/arm/arm.c
===================================================================
*** gcc/config/arm/arm.c.orig
--- gcc/config/arm/arm.c
*************** static int arm_cortex_a5_branch_cost (bo
*** 269,275 ****
  
  static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
  					     const unsigned char *sel);
! 
  
  /* Table of machine attributes.  */
  static const struct attribute_spec arm_attribute_table[] =
--- 269,276 ----
  
  static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
  					     const unsigned char *sel);
! static bool arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
! 					 bool op0_preserve_value);
  
  /* Table of machine attributes.  */
  static const struct attribute_spec arm_attribute_table[] =
*************** static const struct attribute_spec arm_a
*** 626,631 ****
--- 627,636 ----
  #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;
  
  /* Obstack for minipool constant handling.  */
*************** arm_gen_constant (enum rtx_code code, en
*** 3543,3553 ****
     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)
  {
    enum machine_mode mode;
    unsigned HOST_WIDE_INT i, maxval;
  
    mode = GET_MODE (*op0);
    if (mode == VOIDmode)
--- 3548,3560 ----
     This can be done for a few constant compares, where we can make the
     immediate value easier to load.  */
  
! static bool
! arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
! 			     bool op0_preserve_value)
  {
    enum machine_mode mode;
    unsigned HOST_WIDE_INT i, maxval;
+   bool modified = false;
  
    mode = GET_MODE (*op0);
    if (mode == VOIDmode)
*************** arm_canonicalize_comparison (enum rtx_co
*** 3563,3577 ****
      {
        rtx tem;
  
!       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)
  		{
  		case GT:
  		case LE:
--- 3570,3584 ----
      {
        rtx tem;
  
!       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)
  		{
  		case GT:
  		case LE:
*************** arm_canonicalize_comparison (enum rtx_co
*** 3579,3585 ****
  		      && arm_const_double_by_immediates (GEN_INT (i + 1)))
  		    {
  		      *op1 = GEN_INT (i + 1);
! 		      return code == GT ? GE : LT;
  		    }
  		  break;
  		case GTU:
--- 3586,3593 ----
  		      && arm_const_double_by_immediates (GEN_INT (i + 1)))
  		    {
  		      *op1 = GEN_INT (i + 1);
! 		      *code = *code == GT ? GE : LT;
! 		      modified = true;
  		    }
  		  break;
  		case GTU:
*************** arm_canonicalize_comparison (enum rtx_co
*** 3588,3594 ****
  		      && arm_const_double_by_immediates (GEN_INT (i + 1)))
  		    {
  		      *op1 = GEN_INT (i + 1);
! 		      return code == GTU ? GEU : LTU;
  		    }
  		  break;
  		default:
--- 3596,3603 ----
  		      && arm_const_double_by_immediates (GEN_INT (i + 1)))
  		    {
  		      *op1 = GEN_INT (i + 1);
! 		      *code = *code == GTU ? GEU : LTU;
! 		      modified = true;
  		    }
  		  break;
  		default:
*************** arm_canonicalize_comparison (enum rtx_co
*** 3597,3646 ****
  	    }
  
  	  /* If that did not work, reverse the condition.  */
! 	  tem = *op0;
! 	  *op0 = *op1;
! 	  *op1 = tem;
! 	  return swap_condition (code);
  	}
! 
!       return code;
      }
  
    /* 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
        && GET_CODE (*op0) == ZERO_EXTEND
        && GET_CODE (XEXP (*op0, 0)) == SUBREG
        && GET_MODE (XEXP (*op0, 0)) == QImode
        && GET_MODE (SUBREG_REG (XEXP (*op0, 0))) == SImode
        && subreg_lowpart_p (XEXP (*op0, 0))
        && *op1 == const0_rtx)
!     *op0 = gen_rtx_AND (SImode, SUBREG_REG (XEXP (*op0, 0)),
! 			GEN_INT (255));
  
    /* Comparisons smaller than DImode.  Only adjust comparisons against
       an out-of-range constant.  */
    if (!CONST_INT_P (*op1)
        || const_ok_for_arm (INTVAL (*op1))
        || const_ok_for_arm (- INTVAL (*op1)))
!     return code;
  
    i = INTVAL (*op1);
  
!   switch (code)
      {
      case EQ:
      case NE:
!       return code;
! 
      case GT:
      case LE:
        if (i != maxval
  	  && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
  	{
  	  *op1 = GEN_INT (i + 1);
! 	  return code == GT ? GE : LT;
  	}
        break;
  
--- 3606,3662 ----
  	    }
  
  	  /* If that did not work, reverse the condition.  */
! 	  if (!modified && !op0_preserve_value)
! 	    {
! 	      tem = *op0;
! 	      *op0 = *op1;
! 	      *op1 = tem;
! 	      *code = (int)swap_condition ((enum rtx_code)*code);
! 	      modified = true;
! 	    }
  	}
!       return modified;
      }
  
    /* 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 (!op0_preserve_value
!       && mode == SImode
        && GET_CODE (*op0) == ZERO_EXTEND
        && GET_CODE (XEXP (*op0, 0)) == SUBREG
        && GET_MODE (XEXP (*op0, 0)) == QImode
        && GET_MODE (SUBREG_REG (XEXP (*op0, 0))) == SImode
        && subreg_lowpart_p (XEXP (*op0, 0))
        && *op1 == const0_rtx)
!     {
!       *op0 = gen_rtx_AND (SImode, SUBREG_REG (XEXP (*op0, 0)),
! 			  GEN_INT (255));
!       modified = true;
!     }
  
    /* Comparisons smaller than DImode.  Only adjust comparisons against
       an out-of-range constant.  */
    if (!CONST_INT_P (*op1)
        || const_ok_for_arm (INTVAL (*op1))
        || const_ok_for_arm (- INTVAL (*op1)))
!     return modified;
  
    i = INTVAL (*op1);
  
!   switch (*code)
      {
      case EQ:
      case NE:
!       break;
      case GT:
      case LE:
        if (i != maxval
  	  && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
  	{
  	  *op1 = GEN_INT (i + 1);
! 	  *code = *code == GT ? GE : LT;
! 	  modified = true;
  	}
        break;
  
*************** arm_canonicalize_comparison (enum rtx_co
*** 3650,3656 ****
  	  && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
  	{
  	  *op1 = GEN_INT (i - 1);
! 	  return code == GE ? GT : LE;
  	}
        break;
  
--- 3666,3673 ----
  	  && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
  	{
  	  *op1 = GEN_INT (i - 1);
! 	  *code = *code == GE ? GT : LE;
! 	  modified = true;
  	}
        break;
  
*************** arm_canonicalize_comparison (enum rtx_co
*** 3660,3666 ****
  	  && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
  	{
  	  *op1 = GEN_INT (i + 1);
! 	  return code == GTU ? GEU : LTU;
  	}
        break;
  
--- 3677,3684 ----
  	  && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
  	{
  	  *op1 = GEN_INT (i + 1);
! 	  *code = *code == GTU ? GEU : LTU;
! 	  modified = true;
  	}
        break;
  
*************** arm_canonicalize_comparison (enum rtx_co
*** 3670,3676 ****
  	  && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
  	{
  	  *op1 = GEN_INT (i - 1);
! 	  return code == GEU ? GTU : LEU;
  	}
        break;
  
--- 3688,3695 ----
  	  && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
  	{
  	  *op1 = GEN_INT (i - 1);
! 	  *code = *code == GEU ? GTU : LEU;
! 	  modified = true;
  	}
        break;
  
*************** arm_canonicalize_comparison (enum rtx_co
*** 3678,3684 ****
        gcc_unreachable ();
      }
  
!   return code;
  }
  
  
--- 3697,3703 ----
        gcc_unreachable ();
      }
  
!   return modified;
  }
  
  
*************** bool
*** 26970,26976 ****
  arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
  {
    enum rtx_code code = GET_CODE (*comparison);
-   enum rtx_code canonical_code;
    enum machine_mode mode = (GET_MODE (*op1) == VOIDmode) 
      ? GET_MODE (*op2) : GET_MODE (*op1);
  
--- 26989,26994 ----
*************** arm_validize_comparison (rtx *comparison
*** 26979,26986 ****
    if (code == UNEQ || code == LTGT)
      return false;
  
!   canonical_code = arm_canonicalize_comparison (code, op1, op2);
!   PUT_CODE (*comparison, canonical_code);
  
    switch (mode)
      {
--- 26997,27004 ----
    if (code == UNEQ || code == LTGT)
      return false;
  
!   arm_canonicalize_comparison ((int*)&code, op1, op2, 0);
!   PUT_CODE (*comparison, code);
  
    switch (mode)
      {
Index: gcc/config/arm/arm.h
===================================================================
*** gcc/config/arm/arm.h.orig
--- gcc/config/arm/arm.h
*************** extern int making_const_table;
*** 2077,2085 ****
     ? 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)
--- 2077,2082 ----
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h.orig
--- gcc/config/s390/s390.h
*************** do {									\
*** 720,729 ****
     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
--- 720,725 ----
Index: gcc/config/alpha/alpha.c
===================================================================
*** gcc/config/alpha/alpha.c.orig
--- gcc/config/alpha/alpha.c
*************** alpha_conditional_register_usage (void)
*** 9683,9688 ****
--- 9683,9717 ----
      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 bool
+ alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+ 			       bool op0_preserve_value)
+ {
+   bool modified = false;
+ 
+   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);
+       modified = true;
+     }
+ 
+   if ((*code == LT || *code == LTU)
+       && CONST_INT_P (*op1) && INTVAL (*op1) == 256)
+     {
+       *code = *code == LT ? LE : LEU;
+       *op1 = GEN_INT (255);
+       modified = true;
+     }
+   return modified;
+ }
  
  /* Initialize the GCC target structure.  */
  #if TARGET_ABI_OPEN_VMS
*************** alpha_conditional_register_usage (void)
*** 9850,9855 ****
--- 9879,9887 ----
  #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;
  
  
Index: gcc/config/alpha/alpha.h
===================================================================
*** gcc/config/alpha/alpha.h.orig
--- gcc/config/alpha/alpha.h
*************** do {									     \
*** 921,946 ****
  #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.  */
--- 921,926 ----
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig
--- gcc/doc/tm.texi
*************** You should define this macro if and only
*** 6026,6050 ****
  in @file{@var{machine}-modes.def}.
  @end defmac
  
! @defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
  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.
  
  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
  
  @defmac REVERSIBLE_CC_MODE (@var{mode})
  A C expression whose value is one if it is always safe to reverse a
--- 6026,6054 ----
  in @file{@var{machine}-modes.def}.
  @end defmac
  
! @deftypefn {Target Hook} bool 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, 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.
! 
! The hook should return @code{true} if any modification was done.
  
  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 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: gcc/config/arm/arm-protos.h
===================================================================
*** gcc/config/arm/arm-protos.h.orig
--- gcc/config/arm/arm-protos.h
*************** extern int const_ok_for_op (HOST_WIDE_IN
*** 53,59 ****
  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);
--- 53,58 ----
Index: gcc/config/s390/s390-protos.h
===================================================================
*** gcc/config/s390/s390-protos.h.orig
--- gcc/config/s390/s390-protos.h
*************** extern int tls_symbolic_operand (rtx);
*** 58,64 ****
  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);
--- 58,63 ----
Index: gcc/config/sh/sh-protos.h
===================================================================
*** gcc/config/sh/sh-protos.h.orig
--- gcc/config/sh/sh-protos.h
*************** extern bool sh_expand_t_scc (rtx *);
*** 159,166 ****
  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);
  
--- 159,164 ----
Index: gcc/config/sh/sh.c
===================================================================
*** gcc/config/sh/sh.c.orig
--- gcc/config/sh/sh.c
*************** static int max_mov_insn_displacement (en
*** 314,319 ****
--- 314,320 ----
  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 bool sh_canonicalize_comparison (int *, rtx *, rtx *, bool);
  
  static void sh_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
  
*************** static const struct attribute_spec sh_at
*** 586,591 ****
--- 587,595 ----
  #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)
  
*************** prepare_move_operands (rtx operands[], e
*** 1909,1921 ****
      }
  }
  
! /* Implement the CANONICALIZE_COMPARISON macro for the combine pass.
!    This function is also re-used to canonicalize comparisons in cbranch
!    pattern expanders.  */
! void
! sh_canonicalize_comparison (enum rtx_code& cmp, rtx& op0, rtx& op1,
! 			    enum machine_mode mode)
  {
    /* When invoked from within the combine pass the mode is not specified,
       so try to get it from one of the operands.  */
    if (mode == VOIDmode)
--- 1913,1930 ----
      }
  }
  
! /* 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 bool
! sh_canonicalize_comparison_1 (enum rtx_code& cmp, rtx& op0, rtx& op1,
! 			      enum machine_mode mode,
! 			      bool op0_preserve_value ATTRIBUTE_UNUSED)
  {
+   bool modified = false;
+   HOST_WIDE_INT val;
+ 
    /* When invoked from within the combine pass the mode is not specified,
       so try to get it from one of the operands.  */
    if (mode == VOIDmode)
*************** sh_canonicalize_comparison (enum rtx_cod
*** 1925,2011 ****
  
    // We need to have a mode to do something useful here.
    if (mode == VOIDmode)
!     return;
  
    // Currently, we don't deal with floats here.
    if (GET_MODE_CLASS (mode) == MODE_FLOAT)
!     return;
  
    // Make sure that the constant operand is the second operand.
    if (CONST_INT_P (op0) && !CONST_INT_P (op1))
      {
        std::swap (op0, op1);
        cmp = swap_condition (cmp);
      }
  
!   if (CONST_INT_P (op1))
      {
!       /* Try to adjust the constant operand in such a way that available
!          comparison insns can be utilized better and the constant can be
!          loaded with a 'mov #imm,Rm' insn.  This avoids a load from the
!          constant pool.  */
!       const HOST_WIDE_INT val = INTVAL (op1);
! 
!       /* x > -1		  --> x >= 0
! 	 x > 0xFFFFFF7F	  --> x >= 0xFFFFFF80
! 	 x <= -1	  --> x < 0
! 	 x <= 0xFFFFFF7F  --> x < 0xFFFFFF80  */
!       if ((val == -1 || val == -0x81) && (cmp == GT || cmp == LE))
! 	{
! 	  cmp = cmp == GT ? GE : LT;
! 	  op1 = gen_int_mode (val + 1, mode);
!         }
  
!       /* x >= 1     --> x > 0
! 	 x >= 0x80  --> x > 0x7F
! 	 x < 1      --> x <= 0
! 	 x < 0x80   --> x <= 0x7F  */
!       else if ((val == 1 || val == 0x80) && (cmp == GE || cmp == LT))
! 	{
! 	  cmp = cmp == GE ? GT : LE;
! 	  op1 = gen_int_mode (val - 1, mode);
! 	}
  
!       /* unsigned x >= 1  --> x != 0
! 	 unsigned x < 1   --> x == 0  */
!       else if (val == 1 && (cmp == GEU || cmp == LTU))
! 	{
! 	  cmp = cmp == GEU ? NE : EQ;
! 	  op1 = CONST0_RTX (mode);
! 	}
  
!       /* unsigned x >= 0x80  --> unsigned x > 0x7F
! 	 unsigned x < 0x80   --> unsigned x < 0x7F  */
!       else if (val == 0x80 && (cmp == GEU || cmp == LTU))
! 	{
! 	  cmp = cmp == GEU ? GTU : LEU;
! 	  op1 = gen_int_mode (val - 1, mode);
! 	}
  
!       /* unsigned x > 0   --> x != 0
! 	 unsigned x <= 0  --> x == 0  */
!       else if (val == 0 && (cmp == GTU || cmp == LEU))
! 	cmp = cmp == GTU ? NE : EQ;
  
!       /* unsigned x > 0x7FFFFFFF   --> signed x < 0
! 	 unsigned x <= 0x7FFFFFFF  --> signed x >= 0  */
!       else if (mode == SImode && (cmp == GTU || cmp == LEU)
! 	       && val == 0x7FFFFFFF)
! 	{
! 	  cmp = cmp == GTU ? LT : GE;
! 	  op1 = const0_rtx;
! 	}
  
!       /* unsigned x >= 0x80000000  --> signed x < 0
! 	 unsigned x < 0x80000000   --> signed x >= 0  */
!       else if (mode == SImode && (cmp == GEU || cmp == LTU)
! 	       && (unsigned HOST_WIDE_INT)val
! 		   == ((unsigned HOST_WIDE_INT)0x7FFFFFFF + 1))
! 	{
! 	  cmp = cmp == GEU ? LT : GE;
! 	  op1 = const0_rtx;
! 	}
      }
  }
  
  enum rtx_code
--- 1934,2047 ----
  
    // We need to have a mode to do something useful here.
    if (mode == VOIDmode)
!     return false;
  
    // Currently, we don't deal with floats here.
    if (GET_MODE_CLASS (mode) == MODE_FLOAT)
!     return false;
  
    // Make sure that the constant operand is the second operand.
    if (CONST_INT_P (op0) && !CONST_INT_P (op1))
      {
        std::swap (op0, op1);
        cmp = swap_condition (cmp);
+       modified = true;
      }
  
!   if (!CONST_INT_P (op1))
!     return modified;
! 
!   /* Try to adjust the constant operand in such a way that available
!      comparison insns can be utilized better and the constant can be
!      loaded with a 'mov #imm,Rm' insn.  This avoids a load from the
!      constant pool.  */
!   val = INTVAL (op1);
! 
!   /* x > -1		  --> x >= 0
!      x > 0xFFFFFF7F	  --> x >= 0xFFFFFF80
!      x <= -1	  --> x < 0
!      x <= 0xFFFFFF7F  --> x < 0xFFFFFF80  */
!   if ((val == -1 || val == -0x81) && (cmp == GT || cmp == LE))
      {
!       cmp = cmp == GT ? GE : LT;
!       op1 = gen_int_mode (val + 1, mode);
!       return true;
!     }
  
!   /* x >= 1     --> x > 0
!      x >= 0x80  --> x > 0x7F
!      x < 1      --> x <= 0
!      x < 0x80   --> x <= 0x7F  */
!   else if ((val == 1 || val == 0x80) && (cmp == GE || cmp == LT))
!     {
!       cmp = cmp == GE ? GT : LE;
!       op1 = gen_int_mode (val - 1, mode);
!       return true;
!     }
  
!   /* unsigned x >= 1  --> x != 0
!      unsigned x < 1   --> x == 0  */
!   else if (val == 1 && (cmp == GEU || cmp == LTU))
!     {
!       cmp = cmp == GEU ? NE : EQ;
!       op1 = CONST0_RTX (mode);
!       return true;
!     }
  
!   /* unsigned x >= 0x80  --> unsigned x > 0x7F
!      unsigned x < 0x80   --> unsigned x < 0x7F  */
!   else if (val == 0x80 && (cmp == GEU || cmp == LTU))
!     {
!       cmp = cmp == GEU ? GTU : LEU;
!       op1 = gen_int_mode (val - 1, mode);
!       return true;
!     }
  
!   /* unsigned x > 0   --> x != 0
!      unsigned x <= 0  --> x == 0  */
!   else if (val == 0 && (cmp == GTU || cmp == LEU))
!     {
!       cmp = cmp == GTU ? NE : EQ;
!       return true;
!     }
  
!   /* unsigned x > 0x7FFFFFFF   --> signed x < 0
!      unsigned x <= 0x7FFFFFFF  --> signed x >= 0  */
!   else if (mode == SImode && (cmp == GTU || cmp == LEU)
! 	   && val == 0x7FFFFFFF)
!     {
!       cmp = cmp == GTU ? LT : GE;
!       op1 = const0_rtx;
!       return true;
!     }
  
!   /* unsigned x >= 0x80000000  --> signed x < 0
!      unsigned x < 0x80000000   --> signed x >= 0  */
!   else if (mode == SImode && (cmp == GEU || cmp == LTU)
! 	   && (unsigned HOST_WIDE_INT)val
! 	   == ((unsigned HOST_WIDE_INT)0x7FFFFFFF + 1))
!     {
!       cmp = cmp == GEU ? LT : GE;
!       op1 = const0_rtx;
!       return true;
      }
+   return modified;
+ }
+ 
+ /* This function implements the canonicalize_comparison target hook.
+    This wrapper around the internally used
+    sh_canonicalize_comparison_1 function is needed to do the enum
+    rtx_code <-> int conversion.  Target hooks cannot use enum rtx_code
+    in its definition.  */
+ static bool
+ sh_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
+ 			    bool op0_preserve_value)
+ {
+   enum rtx_code tmp_code = (enum rtx_code)*code;
+   bool modified = sh_canonicalize_comparison_1 (tmp_code, *op0, *op1,
+ 						VOIDmode, op0_preserve_value);
+   *code = (int)tmp_code;
+   return modified;
  }
  
  enum rtx_code
*************** prepare_cbranch_operands (rtx *operands,
*** 2021,2027 ****
    else
      scratch = operands[4];
  
!   sh_canonicalize_comparison (comparison, operands[1], operands[2], mode);
  
    /* Notice that this function is also invoked after reload by
       the cbranchdi4_i pattern, through expand_cbranchdi4.  */
--- 2057,2064 ----
    else
      scratch = operands[4];
  
!   sh_canonicalize_comparison_1 (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: gcc/config/sh/sh.h
===================================================================
*** gcc/config/sh/sh.h.orig
--- gcc/config/sh/sh.h
*************** struct sh_args {
*** 1872,1881 ****
     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) \
--- 1872,1877 ----
Index: gcc/config/spu/spu.c
===================================================================
*** gcc/config/spu/spu.c.orig
--- gcc/config/spu/spu.c
*************** spu_output_mi_thunk (FILE *file, tree th
*** 7095,7100 ****
--- 7095,7117 ----
    final_end_function ();
  }
  
+ /* Canonicalize a comparison from one we don't have to one we do have.  */
+ static bool
+ 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);
+       return true;
+     }
+   return false;
+ }
+ 
  
  /*  Table of machine attributes.  */
  static const struct attribute_spec spu_attribute_table[] =
*************** static const struct attribute_spec spu_a
*** 7308,7313 ****
--- 7325,7333 ----
  #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: gcc/config/spu/spu.h
===================================================================
*** gcc/config/spu/spu.h.orig
--- gcc/config/spu/spu.h
*************** do {									\
*** 520,537 ****
  
  #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
--- 520,525 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]