Unordered compares and backends lacking them

Jan Hubicka jh@suse.cz
Thu Mar 8 10:22:00 GMT 2001


Hi,
Here is an attempt to fix the mips bootstrap problem I've introduced by
reversal changes.  It adds code to prepare_cmp_insn to break out the
comparisons into old ones, so targets supporting only old FP comparison
codes remain happy (and now will support the c99 builtins as well).

On mips target this allows me to get bit farer on compiling that file,
dying later trying to construct conditional move with unordered code.
Mips.md needs updating....

But for this particular problem, I believe patch bellow is optimal solution
(except teaching all backends to do unordered compares in optimal way using
some architecture dependent tricks, that may or may not be better then
the default sollution bellow).

Honza

Thu Mar  8 19:16:01 CET 2001  Jan Hubicka  <jh@suse.cz>
	* optabs.c (prepare_cmp_insn): Split unordered compares to
	discrete equivalent.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.89
diff -c -3 -p -r1.89 optabs.c
*** optabs.c	2001/03/07 19:29:36	1.89
--- optabs.c	2001/03/08 18:14:20
*************** prepare_cmp_insn (px, py, pcomparison, s
*** 3142,3149 ****
      }
  
    if (class == MODE_FLOAT)
!     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
  
    else
      abort ();
  }
--- 3142,3218 ----
      }
  
    if (class == MODE_FLOAT)
!     {
!       enum rtx_code ordered_code = UNKNOWN;
!       /* Attempt to split the unordered comparisons.  */
!       switch (*pcomparison)
! 	{
! 	  case UNLT:
! 	    ordered_code = LT;
! 	    break;
! 	  case UNLE:
! 	    ordered_code = LE;
! 	    break;
! 	  case UNGT:
! 	    ordered_code = GT;
! 	    break;
! 	  case UNGE:
! 	    ordered_code = GE;
! 	    break;
! 	  case UNEQ:
! 	    ordered_code = EQ;
! 	    break;
! 	  /* Handled as special cases later.  */
! 	  case LTGT:
! 	    ordered_code = EQ;
! 	    break;
! 	  case UNORDERED:
! 	  case ORDERED:
! 	    ordered_code = NIL;
! 	    break;
! 	  default:
! 	    break;
! 	}
!       if (ordered_code != UNKNOWN
! 	  && (can_compare_p (UNORDERED, mode, ccp_jump)
! 	      || can_compare_p (EQ, mode, ccp_jump))
! 	  && (can_compare_p (ordered_code, mode, ccp_store_flag)
! 	      || can_compare_p (ordered_code, mode, ccp_jump)))
! 	{
! 	  rtx label = gen_label_rtx ();
! 	  rtx target = gen_reg_rtx (word_mode);
! 	  int reverse = 0;
  
+ 	  emit_move_insn (target, const1_rtx);
+ 	  
+ 	  /* We also may be able to convert ORDERED to !UNORDERED here.  */
+ 	  if (can_compare_p (UNORDERED, mode, ccp_jump))
+ 	    emit_cmp_and_jump_insn_1 (*px, *py, *pmode, UNORDERED, 0, label);
+ 	  else
+ 	    {
+ 	      emit_cmp_and_jump_insn_1 (*px, *px, *pmode, NE, 0, label);
+ 	      emit_cmp_and_jump_insn_1 (*py, *py, *pmode, NE, 0, label);
+ 	    }
+ 	  if (ordered_code != 1)
+ 	    emit_store_flag_force (target, ordered_code, *px, *py, mode, 0, 0);
+ 	  else
+ 	    emit_move_insn (target, const0_rtx);
+ 	  emit_label (label);
+ 
+ 	  if (*pcomparison == LTGT || *pcomparison == ORDERED)
+ 	    *pcomparison = EQ;
+ 	  else
+ 	    *pcomparison = NE;
+ 
+ 	  *pmode = word_mode;
+ 	  *px = target;
+ 	  *py = const0_rtx;
+ 
+ 	  return prepare_cmp_insn (px, py, pcomparison, 0, pmode, punsignedp, align,
+ 				   purpose);
+ 	}
+       prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
+     }
    else
      abort ();
  }



More information about the Gcc-patches mailing list