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]

[MIPS 20/30] Improve handling of GT and GTU


[Last of these patches for today]

We can implement LE and LEU of most 16-bit CONST_INTs by adding
one to the constant and using LT and LTU.  We were missing the
same transformation when inverting a GT or GTU.

Richard


gcc/
	* config/mips/mips.c (mips_canonicalize_comparison):  Check
	mips_relational_operand_ok_p before trying to rewrite the test.
	Only calculate PLUS_ONE if needed.
	(mips_emit_int_relational): Don't call mips_relational_operand_ok_p
	here.

Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	2007-10-18 11:07:13.000000000 +0100
--- gcc/config/mips/mips.c	2007-10-18 11:07:13.000000000 +0100
*************** mips_relational_operand_ok_p (enum rtx_c
*** 3742,3781 ****
  mips_canonicalize_comparison (enum rtx_code *code, rtx *cmp1,
  			      enum machine_mode mode)
  {
!   HOST_WIDE_INT original, plus_one;
  
!   if (GET_CODE (*cmp1) != CONST_INT)
!     return false;
! 
!   original = INTVAL (*cmp1);
!   plus_one = trunc_int_for_mode ((unsigned HOST_WIDE_INT) original + 1, mode);
! 
!   switch (*code)
!     {
!     case LE:
!       if (original < plus_one)
! 	{
! 	  *code = LT;
! 	  *cmp1 = force_reg (mode, GEN_INT (plus_one));
! 	  return true;
! 	}
!       break;
  
!     case LEU:
!       if (plus_one != 0)
! 	{
! 	  *code = LTU;
! 	  *cmp1 = force_reg (mode, GEN_INT (plus_one));
! 	  return true;
! 	}
!       break;
  
!     default:
!       return false;
!    }
  
    return false;
- 
  }
  
  /* Compare CMP0 and CMP1 using relational operator CODE and store the
--- 3742,3779 ----
  mips_canonicalize_comparison (enum rtx_code *code, rtx *cmp1,
  			      enum machine_mode mode)
  {
!   HOST_WIDE_INT plus_one;
  
!   if (mips_relational_operand_ok_p (*code, *cmp1))
!     return true;
  
!   if (GET_CODE (*cmp1) == CONST_INT)
!     switch (*code)
!       {
!       case LE:
! 	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
! 	if (INTVAL (*cmp1) < plus_one)
! 	  {
! 	    *code = LT;
! 	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
! 	    return true;
! 	  }
! 	break;
  
!       case LEU:
! 	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
! 	if (plus_one != 0)
! 	  {
! 	    *code = LTU;
! 	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
! 	    return true;
! 	  }
! 	break;
  
+       default:
+ 	break;
+       }
    return false;
  }
  
  /* Compare CMP0 and CMP1 using relational operator CODE and store the
*************** mips_canonicalize_comparison (enum rtx_c
*** 3787,3805 ****
  mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
  			  rtx target, rtx cmp0, rtx cmp1)
  {
!   /* First see if there is a MIPS instruction that can do this operation
!      with CMP1 in its current form. If not, try to canonicalize the
!      comparison to LT. If that fails, try doing the same for the
!      inverse operation.  If that also fails, force CMP1 into a register
!      and try again.  */
!   if (mips_relational_operand_ok_p (code, cmp1))
!     mips_emit_binary (code, target, cmp0, cmp1);
!   else if (mips_canonicalize_comparison (&code, &cmp1, GET_MODE (target)))
      mips_emit_binary (code, target, cmp0, cmp1);
    else
      {
        enum rtx_code inv_code = reverse_condition (code);
!       if (!mips_relational_operand_ok_p (inv_code, cmp1))
  	{
  	  cmp1 = force_reg (GET_MODE (cmp0), cmp1);
  	  mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);
--- 3785,3799 ----
  mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
  			  rtx target, rtx cmp0, rtx cmp1)
  {
!   /* First see if there is a MIPS instruction that can do this operation.
!      If not, try doing the same for the inverse operation.  If that also
!      fails, force CMP1 into a register and try again.  */
!   if (mips_canonicalize_comparison (&code, &cmp1, GET_MODE (target)))
      mips_emit_binary (code, target, cmp0, cmp1);
    else
      {
        enum rtx_code inv_code = reverse_condition (code);
!       if (!mips_canonicalize_comparison (&inv_code, &cmp1, GET_MODE (target)))
  	{
  	  cmp1 = force_reg (GET_MODE (cmp0), cmp1);
  	  mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);


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