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]

[3.4] e500 FP comparison rewrite (PR/12028)


I'm backporting all the FP comparison rewrite.  It only affects E500,
and it fixes many many regressions.

This fixes 12028.

Committed to 3.4 branch.

        PR/12028
        * config/rs6000/rs6000.c (rs6000_emit_cmove): Disable comparisons
	of floats on the E500.
        (branch_positive_comparison_operator): Do not allow NE even on the
	E500.
	(ccr_bit): Remove E500 specific code.
	Remove miscompilation warning for e500.
        (print_operand): Add 'c' and 'D'.
        (rs6000_generate_compare): Rewrite to generate correct rtl.
        (rs6000_emit_sCOND): Handle E500.
        (output_cbranch): Adjust for changes in rs6000_generate_compare.
        (output_e500_flip_gt_bit): New.
	(rs6000_override_options): Error when user wants altivec and e500
	instructions.

        * config/rs6000/rs6000.md (UNSPEC_MV_CR_GT): New constant.
        (move_from_CR_gt_bit): New.
        (cceq_ior_compare): Name previously unnamed pattern.  Disable for
	E500.
        (cceq_rev_compare): Name previously unnamed pattern.  Allow for
	E500.

        * config/rs6000/spe.md (cmpsfeq_gpr): Rewrite as unspec.
        (tstsfeq_gpr): Same.
        (cmpsfgt_gpr): Same.
        (tstsfgt_gpr): Same.
        (cmpsflt_gpr): Same.
        (tstsflt_gpr): Same.
        (e500_cceq_ior_compare): New.
        (e500_flip_gt_bit): New.

        * config/rs6000/rs6000-protos.h (output_e500_flip_gt_bit):
	Protoize.
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.576.2.15
diff -c -p -r1.576.2.15 rs6000.c
*** config/rs6000/rs6000.c	15 Mar 2004 23:22:49 -0000	1.576.2.15
--- config/rs6000/rs6000.c	29 Apr 2004 19:00:53 -0000
*************** rs6000_override_options (const char *def
*** 865,870 ****
--- 865,873 ----
  
    if (TARGET_E500)
      {
+       if (TARGET_ALTIVEC)
+       error ("AltiVec and E500 instructions cannot coexist");
+ 
        /* The e500 does not have string instructions, and we set
  	 MASK_STRING above when optimizing for size.  */
        if ((target_flags & MASK_STRING) != 0)
*************** branch_positive_comparison_operator (rtx
*** 8097,8103 ****
  
    code = GET_CODE (op);
    return (code == EQ || code == LT || code == GT
- 	  || (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
  	  || code == LTU || code == GTU
  	  || code == UNORDERED);
  }
--- 8100,8105 ----
*************** ccr_bit (rtx op, int scc_p)
*** 8525,8550 ****
       allowed.  */
    if (scc_p && code != EQ && code != GT && code != LT && code != UNORDERED
        && code != GTU && code != LTU)
!     {
! #if ! ENABLE_CHECKING
!       if (TARGET_E500)
! 	inform ("your function will be miscompiled");
!       else
! #endif
!       abort ();
!     }
    
    switch (code)
      {
      case NE:
-       if (TARGET_E500 && !TARGET_FPRS
- 	  && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- 	return base_bit + 1;
        return scc_p ? base_bit + 3 : base_bit + 2;
      case EQ:
-       if (TARGET_E500 && !TARGET_FPRS
- 	  && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- 	return base_bit + 1;
        return base_bit + 2;
      case GT:  case GTU:  case UNLE:
        return base_bit + 1;
--- 8527,8539 ----
       allowed.  */
    if (scc_p && code != EQ && code != GT && code != LT && code != UNORDERED
        && code != GTU && code != LTU)
!     abort ();
    
    switch (code)
      {
      case NE:
        return scc_p ? base_bit + 3 : base_bit + 2;
      case EQ:
        return base_bit + 2;
      case GT:  case GTU:  case UNLE:
        return base_bit + 1;
*************** print_operand (FILE *file, rtx x, int co
*** 8764,8769 ****
--- 8753,8778 ----
        /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
  	 output_operand.  */
  
+     case 'c':
+       /* X is a CR register.  Print the number of the GT bit of the CR.  */
+       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+        output_operand_lossage ("invalid %%E value");
+       else
+        fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
+       return;
+ 
+     case 'D':
+       /* Like 'J' but get to the GT bit.  */
+       if (GET_CODE (x) != REG)
+        abort ();
+ 
+       /* Bit 1 is GT bit.  */
+       i = 4 * (REGNO (x) - CR0_REGNO) + 1;
+ 
+       /* If we want bit 31, write a shift count of zero, not 32.  */
+       fprintf (file, "%d", i == 31 ? 0 : i + 1);
+       return;
+ 
      case 'E':
        /* X is a CR register.  Print the number of the EQ bit of the CR */
        if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
*************** rs6000_generate_compare (enum rtx_code c
*** 9550,9585 ****
      {
        rtx cmp, or1, or2, or_result, compare_result2;
  
        switch (code)
  	{
! 	case EQ:
! 	case UNEQ:
! 	case NE:
! 	case LTGT:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
  	    : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1);
  	  break;
! 	case GT:
! 	case GTU:
! 	case UNGT:
! 	case UNGE:
! 	case GE:
! 	case GEU:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
  	    : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1);
  	  break;
! 	case LT:
! 	case LTU:
! 	case UNLT:
! 	case UNLE:
! 	case LE:
! 	case LEU:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
--- 9559,9584 ----
      {
        rtx cmp, or1, or2, or_result, compare_result2;
  
+       /* Note: The E500 comparison instructions set the GT bit (x +
+         1), on success.  This explains the mess.  */
+ 
        switch (code)
  	{
!        case EQ: case UNEQ: case NE: case LTGT:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
  	    : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1);
  	  break;
!        case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
  	    : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1);
  	  break;
!        case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
  	  cmp = flag_finite_math_only
  	    ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
  			       rs6000_compare_op1)
*************** rs6000_generate_compare (enum rtx_code c
*** 9593,9600 ****
        /* Synthesize LE and GE from LT/GT || EQ.  */
        if (code == LE || code == GE || code == LEU || code == GEU)
  	{
- 	  /* Synthesize GE/LE frome GT/LT || EQ.  */
- 
  	  emit_insn (cmp);
  
  	  switch (code)
--- 9592,9597 ----
*************** rs6000_generate_compare (enum rtx_code c
*** 9619,9641 ****
  			       rs6000_compare_op1);
  	  emit_insn (cmp);
  
! 	  /* The MC8540 FP compare instructions set the CR bits
! 	     differently than other PPC compare instructions.  For
! 	     that matter, there is no generic test instruction, but a
! 	     testgt, testlt, and testeq.  For a true condition, bit 2
! 	     is set (x1xx) in the CR.  Following the traditional CR
! 	     values:
! 
! 	     LT    GT    EQ    OV
! 	     bit3  bit2  bit1  bit0
! 
! 	     ... bit 2 would be a GT CR alias, so later on we
! 	     look in the GT bits for the branch instructions.
! 	     However, we must be careful to emit correct RTL in
! 	     the meantime, so optimizations don't get confused.  */
! 
! 	  or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
! 	  or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
  
  	  /* OR them together.  */
  	  cmp = gen_rtx_SET (VOIDmode, or_result,
--- 9616,9623 ----
  			       rs6000_compare_op1);
  	  emit_insn (cmp);
  
! 	  or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
! 	  or2 = gen_rtx_GT (SImode, compare_result2, const0_rtx);
  
  	  /* OR them together.  */
  	  cmp = gen_rtx_SET (VOIDmode, or_result,
*************** rs6000_generate_compare (enum rtx_code c
*** 9647,9662 ****
  	}
        else
  	{
- 	  /* We only care about 1 bit (x1xx), so map everything to NE to
- 	     maintain rtl sanity.  We'll get to the right bit (x1xx) at
- 	     code output time.  */
  	  if (code == NE || code == LTGT)
- 	    /* Do the inverse here because we have no cmpne
- 	       instruction.  We use the cmpeq instruction and expect
- 	       to get a 0 instead.  */
- 	    code = EQ;
- 	  else
  	    code = NE;
  	}
  
        emit_insn (cmp);
--- 9629,9638 ----
  	}
        else
  	{
  	  if (code == NE || code == LTGT)
  	    code = NE;
+          else
+            code = EQ;
  	}
  
        emit_insn (cmp);
*************** rs6000_emit_sCOND (enum rtx_code code, r
*** 9721,9726 ****
--- 9697,9720 ----
    condition_rtx = rs6000_generate_compare (code);
    cond_code = GET_CODE (condition_rtx);
  
+   if (TARGET_E500 && rs6000_compare_fp_p
+       && !TARGET_FPRS && TARGET_HARD_FLOAT)
+     {
+       rtx t;
+ 
+       PUT_MODE (condition_rtx, SImode);
+       t = XEXP (condition_rtx, 0);
+ 
+       if (cond_code != NE && cond_code != EQ)
+        abort ();
+ 
+       if (cond_code == NE)
+        emit_insn (gen_e500_flip_gt_bit (t, t));
+ 
+       emit_insn (gen_move_from_CR_gt_bit (result, t));
+       return;
+     }
+ 
    if (cond_code == NE
        || cond_code == GE || cond_code == LE
        || cond_code == GEU || cond_code == LEU
*************** output_cbranch (rtx op, const char *labe
*** 9817,9825 ****
  	 to the GT bit.  */
        if (code == EQ)
  	/* Opposite of GT.  */
- 	code = UNLE;
-       else if (code == NE)
  	code = GT;
        else
  	abort ();
      }
--- 9811,9819 ----
  	 to the GT bit.  */
        if (code == EQ)
  	/* Opposite of GT.  */
  	code = GT;
+       else if (code == NE)
+        code = UNLE;
        else
  	abort ();
      }
*************** output_cbranch (rtx op, const char *labe
*** 9899,9904 ****
--- 9893,9917 ----
    return string;
  }
  
+ /* Return the string to flip the GT bit on a CR.  */
+ char *
+ output_e500_flip_gt_bit (rtx dst, rtx src)
+ {
+   static char string[64];
+   int a, b;
+ 
+   if (GET_CODE (dst) != REG || ! CR_REGNO_P (REGNO (dst))
+       || GET_CODE (src) != REG || ! CR_REGNO_P (REGNO (src)))
+     abort ();
+ 
+   /* GT bit.  */
+   a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
+   b = 4 * (REGNO (src) - CR0_REGNO) + 1;
+ 
+   sprintf (string, "crnot %d,%d", a, b);
+   return string;
+ }
+ 
  /* Emit a conditional move: move TRUE_COND to DEST if OP of the
     operands of the last comparison is nonzero/true, FALSE_COND if it
     is zero/false.  Return 0 if the hardware has no such operation.  */
*************** rs6000_emit_cmove (rtx dest, rtx op, rtx
*** 9933,9938 ****
--- 9946,9954 ----
  	return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
        return 0;
      }
+   else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
+ 	   && GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
+     return 0;
  
    /* Eliminate half of the comparisons by switching operands, this
       makes the remaining code simpler.  */
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.284.4.8
diff -c -p -r1.284.4.8 rs6000.md
*** config/rs6000/rs6000.md	10 Mar 2004 01:51:08 -0000	1.284.4.8
--- config/rs6000/rs6000.md	29 Apr 2004 19:00:57 -0000
***************
*** 50,55 ****
--- 50,56 ----
     (UNSPEC_TLSGOTTPREL		28)
     (UNSPEC_TLSTLS		29)
     (UNSPEC_FIX_TRUNC_TF		30)	; fadd, rounding towards zero
+    (UNSPEC_MV_CR_GT            31)     ; move_from_CR_gt_bit
    ])
  
  ;;
***************
*** 11374,11379 ****
--- 11375,11389 ----
  	(const_string "mfcr")))
     (set_attr "length" "12")])
  
+ ;; Same as above, but get the GT bit.
+ (define_insn "move_from_CR_gt_bit"
+   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+        (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
+   "TARGET_E500"
+   "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1"
+   [(set_attr "type" "mfcr")
+    (set_attr "length" "12")])
+ 
  ;; Same as above, but get the OV/ORDERED bit.
  (define_insn "move_from_CR_ov_bit"
    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
***************
*** 13704,13710 ****
  ; which are generated by the branch logic.
  ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
  
! (define_insn ""
    [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
          (compare:CCEQ (match_operator:SI 1 "boolean_operator"
  	                [(match_operator:SI 2
--- 13714,13720 ----
  ; which are generated by the branch logic.
  ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
  
! (define_insn "*cceq_ior_compare"
    [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
          (compare:CCEQ (match_operator:SI 1 "boolean_operator"
  	                [(match_operator:SI 2
***************
*** 13718,13724 ****
  						      "cc_reg_operand" "0,y")
  				       (const_int 0)])])
  		      (const_int 1)))]
!   ""
    "cr%q1 %E0,%j2,%j4"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
--- 13728,13734 ----
  						      "cc_reg_operand" "0,y")
  				       (const_int 0)])])
  		      (const_int 1)))]
!   "!(TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS)"
    "cr%q1 %E0,%j2,%j4"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
***************
*** 13742,13748 ****
    "cr%q1 %E0,%j2,%j4"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
! (define_insn ""
    [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
  	(compare:CCEQ (match_operator:SI 1
  				      "branch_positive_comparison_operator"
--- 13752,13758 ----
    "cr%q1 %E0,%j2,%j4"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
! (define_insn "*cceq_rev_compare"
    [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
  	(compare:CCEQ (match_operator:SI 1
  				      "branch_positive_comparison_operator"
***************
*** 13750,13756 ****
  						      "cc_reg_operand" "0,y")
  				       (const_int 0)])
  		      (const_int 0)))]
!   "!TARGET_SPE"
    "{crnor %E0,%j1,%j1|crnot %E0,%j1}"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
--- 13760,13766 ----
  						      "cc_reg_operand" "0,y")
  				       (const_int 0)])
  		      (const_int 0)))]
!   ""
    "{crnor %E0,%j1,%j1|crnot %E0,%j1}"
    [(set_attr "type" "cr_logical,delayed_cr")])
  
Index: config/rs6000/spe.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/spe.md,v
retrieving revision 1.16.10.4
diff -c -p -r1.16.10.4 spe.md
*** config/rs6000/spe.md	27 Feb 2004 02:15:46 -0000	1.16.10.4
--- config/rs6000/spe.md	29 Apr 2004 19:00:58 -0000
***************
*** 2455,2509 ****
    "mfspefscr %0"
    [(set_attr "type" "vecsimple")])
  
  ;; MPC8540 single-precision FP instructions on GPRs.
  ;; We have 2 variants for each.  One for IEEE compliant math and one
  ;; for non IEEE compliant math.
  
  (define_insn "cmpsfeq_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmpeq %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsfeq_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststeq %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
  
  (define_insn "cmpsfgt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmpgt %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsfgt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststgt %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
  
  (define_insn "cmpsflt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmplt %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsflt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
! 	(lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
! 		 (match_operand:SF 2 "gpc_reg_operand" "r")))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststlt %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
- 
--- 2455,2552 ----
    "mfspefscr %0"
    [(set_attr "type" "vecsimple")])
  
+ ;; FP comparison stuff.
+ 
+ (define_insn "e500_cceq_ior_compare"
+   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
+         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
+                        [(match_operator:SI 2
+                                      "branch_positive_comparison_operator"
+                                      [(match_operand 3
+                                                      "cc_reg_operand" "y,y")
+                                       (const_int 0)])
+                         (match_operator:SI 4
+                                      "branch_positive_comparison_operator"
+                                      [(match_operand 5
+                                                      "cc_reg_operand" "0,y")
+                                       (const_int 0)])])
+                      (const_int 1)))]
+   "TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS"
+   "cr%q1 %c0,%j2,%j4"
+   [(set_attr "type" "cr_logical,delayed_cr")])
+ 
+ ;; Flip the GT bit.
+ (define_insn "e500_flip_gt_bit"
+   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+        (unspec:CCFP
+         [(match_operand:CCFP 1 "cc_reg_operand" "y")] 999))]
+   "!TARGET_FPRS && TARGET_HARD_FLOAT"
+   "*
+ {
+   return output_e500_flip_gt_bit (operands[0], operands[1]);
+ }"
+   [(set_attr "type" "cr_logical")])
+ 
  ;; MPC8540 single-precision FP instructions on GPRs.
  ;; We have 2 variants for each.  One for IEEE compliant math and one
  ;; for non IEEE compliant math.
  
  (define_insn "cmpsfeq_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1000))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmpeq %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsfeq_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1001))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststeq %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
  
  (define_insn "cmpsfgt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1002))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmpgt %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsfgt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1003))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststgt %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
  
  (define_insn "cmpsflt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1004))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
    "efscmplt %0,%1,%2"
    [(set_attr "type" "veccmp")])
  
  (define_insn "tstsflt_gpr"
    [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
!        (unspec:CCFP
!         [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
!                        (match_operand:SF 2 "gpc_reg_operand" "r"))]
!         1004))]
    "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
    "efststlt %0,%1,%2"
    [(set_attr "type" "veccmpsimple")])
Index: config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.71.2.4
diff -c -p -r1.71.2.4 rs6000-protos.h
*** config/rs6000/rs6000-protos.h	10 Mar 2004 01:51:08 -0000	1.71.2.4
--- config/rs6000/rs6000-protos.h	29 Apr 2004 19:00:58 -0000
*************** extern enum rtx_code rs6000_reverse_cond
*** 115,120 ****
--- 115,121 ----
  extern void rs6000_emit_sCOND (enum rtx_code, rtx);
  extern void rs6000_emit_cbranch (enum rtx_code, rtx);
  extern char * output_cbranch (rtx, const char *, int, rtx);
+ extern char * output_e500_flip_gt_bit (rtx, rtx);
  extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
  extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
  extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);


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