public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* A new ppro patch for egcs 980518
@ 1998-05-18 20:07 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 1998-05-18 20:07 UTC (permalink / raw)
  To: egcs; +Cc: ejr

Hi,

This is a new PPro patch for egcs 980518. All known PPro bugs have
been fixed. Please let me know if it works for you. Bug reports with
small test cases are very much appreciated.

Thanks.

-- 
H.J. Lu (hjl@gnu.org)
---
Sun May 17 17:41:28 1998  H.J. Lu  (hjl@gnu.org)

	* local-alloc.c (update_equiv_regs): Don't add anything between
	the cc0 setter and the next cc0 user after it.

Wed May 13 17:36:28 1998  H.J. Lu  (hjl@gnu.org)

	* reg-stack.c (subst_stack_regs_pat): Make sure the top of
	stack is the destination for conditional move insn.

	* config/i386/i386.c (expand_fp_conditional_move): New function
	to expand fp conditional move.
	(expand_int_conditional_move): New function to expand integer
	conditional move.
	(output_fp_conditional_move): New function to output fp
	conditional move.
	(output_int_conditional_move): New function to output integer
	conditional move.

	* config/i386/i386.md (movsicc, movhicc): Call
	expand_int_conditional_move () to expand int conditional move.
	(movsicc_1, movhicc_1): Use "nonimmediate_operand" as predicate
	for input, call output_int_conditional_move () to output int
	conditional move.
	(movsfcc, movdfcc, movxfcc): Use "t" as constraint for output,
	use "register_operand" as predicate for input and call
	expand_fp_conditional_move () to expand fp conditional move.
	(movxfcc_1, movdfcc_1, movxfcc_1): Use "nonimmediate_operand"
	as predicate for input, use "register_operand" as predicate for
	output and call output_fp_conditional_move () to output fp
	conditional move, remove "F" from input constraint.
	(movsicc, movhicc, movsicc_1, movhicc_1, movsfcc, movdfcc,
	movxfcc, movxfcc_1, movdfcc_1, movxfcc_1): Enable.

Mon May 11 08:04:17 1998  H.J. Lu  (hjl@gnu.org)

	* config/i386/i386.c (output_float_compare): Fix the unordered
	comparison for IEEE math and CC_FCOMI.

Fri May  8 07:53:43 1998  H.J. Lu  (hjl@gnu.org)

	* config/i386/i386.c (put_condition_code): In INT mode, check
	cc_prev_status.flags & CC_NO_OVERFLOW for GE and LT.
	(output_int_conditional_move): Likewise for GT and LE.

Index: local-alloc.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/local-alloc.c,v
retrieving revision 1.1.1.11
diff -u -p -r1.1.1.11 local-alloc.c
--- local-alloc.c	1998/04/04 16:14:34	1.1.1.11
+++ local-alloc.c	1998/05/18 00:39:54
@@ -985,10 +985,25 @@ update_equiv_regs ()
 		       && REG_BASIC_BLOCK (regno) < 0)
 		{
 		  int l;
+		  rtx before_insn;
 
-		  emit_insn_before (copy_rtx (PATTERN (equiv_insn)), insn);
-		  REG_NOTES (PREV_INSN (insn)) = REG_NOTES (equiv_insn);
+#ifdef HAVE_cc0 
+		  /* We may not put equiv_insn between
+		     prev_nonnote_insn (insn) and insn if cc0 is set in
+		     prev_nonnote_insn (insn) and used in insn. We do
+		     a sanity check here. */
+		  before_insn = prev_nonnote_insn (insn);
+		  if (!before_insn
+		      || GET_RTX_CLASS (GET_CODE (before_insn)) != 'i'
+		      || !sets_cc0_p (PATTERN (before_insn))
+		      || next_cc0_user (before_insn) != insn)
+#endif
+		    before_insn = insn;
 
+		  emit_insn_before (copy_rtx (PATTERN (equiv_insn)),
+				    before_insn);
+		  REG_NOTES (PREV_INSN (before_insn)) = REG_NOTES (equiv_insn);
+
 		  PUT_CODE (equiv_insn, NOTE);
 		  NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
 		  NOTE_SOURCE_FILE (equiv_insn) = 0;
@@ -1001,8 +1016,8 @@ update_equiv_regs ()
 		  REG_N_CALLS_CROSSED (regno) = 0;
 		  REG_LIVE_LENGTH (regno) = 2;
 
-		  if (block >= 0 && insn == basic_block_head[block])
-		    basic_block_head[block] = PREV_INSN (insn);
+		  if (block >= 0 && before_insn == basic_block_head[block])
+		    basic_block_head[block] = PREV_INSN (before_insn);
 
 		  for (l = 0; l < n_basic_blocks; l++)
 		    CLEAR_REGNO_REG_SET (basic_block_live_at_start[l], regno);
Index: reg-stack.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/reg-stack.c,v
retrieving revision 1.1.1.15
diff -u -p -r1.1.1.15 reg-stack.c
--- reg-stack.c	1998/05/06 20:59:12	1.1.1.15
+++ reg-stack.c	1998/05/14 00:00:00
@@ -2344,6 +2345,13 @@ subst_stack_regs_pat (insn, regstack, pa
       case IF_THEN_ELSE:
 	/* This insn requires the top of stack to be the destination. */
 
+	/* The comparison operator may not be FP comparison operator,
+	   which is handled correctly in compare_for_stack_reg ().
+	   We do a sanity check here. */
+	if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
+	    && REGNO (*dest) != regstack->reg[regstack->top])
+	  emit_swap_insn (insn, regstack, *dest);	
+
 	src1 = get_true_reg (&XEXP (SET_SRC (pat), 1));
 	src2 = get_true_reg (&XEXP (SET_SRC (pat), 2));
 
Index: config/i386/i386.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.1.1.16
diff -u -p -r1.1.1.16 i386.c
--- i386.c	1998/05/16 02:22:13	1.1.1.16
+++ i386.c	1998/05/18 14:00:00
@@ -3089,7 +3098,10 @@ put_condition_code (code, reverse_cc, mo
 	return;
 
       case GE:
-	fputs ("ge", file);
+	if (cc_prev_status.flags & CC_NO_OVERFLOW)
+	  fputs ("ns", file);
+	else
+	  fputs ("ge", file);
 	return;
 
       case GT:
@@ -3101,7 +3113,10 @@ put_condition_code (code, reverse_cc, mo
 	return;
 
       case LT:
-	fputs ("l", file);
+	if (cc_prev_status.flags & CC_NO_OVERFLOW)
+	  fputs ("s", file);
+	else
+	  fputs ("l", file);
 	return;
 
       case GEU:
@@ -4047,6 +4062,18 @@ output_float_compare (insn, operands)
 	    {
 	      output_asm_insn (AS2 (fucomip,%y1,%0), operands);
 	      output_asm_insn (AS1 (fstp, %y0), operands);
+
+	      if (TARGET_IEEE_FP)
+		{
+		  /* It is very tricky. We have to do it right. */
+		  rtx xops [1];
+
+		  xops [0] = gen_rtx_REG (QImode, 0);
+		  output_asm_insn (AS1 (setne,%b0), xops);
+		  output_asm_insn (AS1 (setp,%h0), xops);
+		  output_asm_insn (AS2 (or%B0,%h0,%b0), xops);
+		}
+
 	      return "";
 	    }
 	  else
@@ -4088,6 +4115,17 @@ output_float_compare (insn, operands)
       else if (cc_status.flags & CC_FCOMI) 
 	{
 	  output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
+	  if (unordered_compare && TARGET_IEEE_FP)
+	    {
+	      /* It is very tricky. We have to do it right. */
+	      rtx xops [1];
+
+	      xops [0] = gen_rtx_REG (QImode, 0);
+	      output_asm_insn (AS1 (setne,%b0), xops);
+	      output_asm_insn (AS1 (setp,%h0), xops);
+	      output_asm_insn (AS2 (or%B0,%h0,%b0), xops);
+	    }
+
 	  return "";
 	}
       else
@@ -5123,4 +5161,290 @@ output_strlen_unroll (operands)
   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
 
   return "";
+}
+
+char *
+output_fp_conditional_move (which_alternative, operands)
+     int which_alternative;
+     rtx operands[];
+{
+  if (which_alternative == 0)
+    {
+      /* r <- cond ? arg : r */
+      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
+    }
+  else if (which_alternative == 1)
+    {
+      /* r <- cond ? r : arg */
+      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
+    }
+  else if (which_alternative == 2)
+    {
+      /* r <- cond ? r : arg */
+      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
+      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
+    }
+  else if (which_alternative == 3)
+    {
+      /* r <- cond ? arg1 : arg2 */
+      rtx xops[3];
+
+      xops[0] = gen_label_rtx ();
+      xops[1] = gen_label_rtx ();
+      xops[2] = operands[1];
+
+      output_asm_insn ("j%f2 %l0", xops);
+      if (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM)
+	output_asm_insn (AS1 (fld%z2,%y2), operands);
+      else
+        {
+	  int conval = standard_80387_constant_p (operands[2]);
+    
+	  switch (conval)
+	    {
+	    case 1:
+	      fprintf (asm_out_file, "\tfldz\n");
+	      break;
+	    case 2:
+	      fprintf (asm_out_file, "\tfld1\n");
+	      break;
+	    default:
+#if 1
+	      abort ();
+#else
+	      operands[2] = CONST_DOUBLE_MEM (operands[2]);
+	      if (GET_CODE (operands[2]) != MEM)
+		abort ();
+	      output_asm_insn (AS1 (fld%z2,%y2), operands);
+#endif
+	      break;
+	    }
+	}
+      output_asm_insn ("jmp %l1", xops);
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[0]));
+      if (STACK_REG_P (operands[3]) || GET_CODE (operands[3]) == MEM)
+	  output_asm_insn (AS1 (fld%z3,%y3), operands);
+      else
+	{
+	  int conval = standard_80387_constant_p (operands[2]);
+    
+	  switch (conval)
+	    {
+	    case 1:
+	      fprintf (asm_out_file, "\tfldz\n");
+	      break;
+	    case 2:
+	      fprintf (asm_out_file, "\tfld1\n");
+	      break;
+	    default:
+#if 1
+	      abort ();
+#else
+	      operands[3] = CONST_DOUBLE_MEM (operands[3]);
+	      if (GET_CODE (operands[3]) != MEM)
+		abort ();
+	      output_asm_insn (AS1 (fld%z3,%y3), operands);
+#endif
+	      break;
+	    }
+	}
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[1]));
+    }
+
+  return "";
+}
+
+char *
+output_int_conditional_move (which_alternative, operands)
+     int which_alternative;
+     rtx operands[];
+{
+  int code = GET_CODE (operands[1]);
+
+  if ((code == GT || code == LE)
+      && (cc_prev_status.flags & CC_NO_OVERFLOW))
+    return NULL_PTR;
+
+  if (which_alternative == 0)
+    {
+      /* r <- cond ? arg : r */
+      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
+    }
+  else if (which_alternative == 1)
+    {
+      /* r <- cond ? r : arg */
+      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
+    }
+  else if (which_alternative == 2)
+    {
+      /* r <- cond ? arg1 : arg2 */
+      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
+      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
+    }
+  else if (which_alternative == 3)
+    {
+      /* r <- cond ? arg1 : arg2 */
+      rtx xops[3];
+
+      xops[0] = gen_label_rtx ();
+      xops[1] = gen_label_rtx ();
+      xops[2] = operands[1];
+
+      output_asm_insn ("j%c2 %l0", xops);
+      if (! rtx_equal_p (operands[0], operands[2]))
+	{
+	  if (GET_CODE (operands[0]) == MEM
+	      && GET_CODE (operands[2]) == MEM)
+	    {
+	      output_asm_insn (AS2 (mov%z2,%2,%4), operands);
+	      output_asm_insn (AS2 (mov%z2,%4,%0), operands);
+	    }
+	  else
+	    output_asm_insn (AS2 (mov%z0,%2,%0), operands);
+	}
+      output_asm_insn ("jmp %l1", xops);
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[0]));
+      if (! rtx_equal_p (operands[0], operands[3]))
+	{
+	  if (GET_CODE (operands[0]) == MEM
+	      && GET_CODE (operands[3]) == MEM)
+	    {
+	      output_asm_insn (AS2 (mov%z3,%3,%4), operands);
+	      output_asm_insn (AS2 (mov%z3,%4,%0), operands);
+	    }
+	  else
+	    output_asm_insn (AS2 (mov%z0,%3,%0), operands);
+	}
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[1]));
+    }
+
+  return "";
+}
+
+void
+expand_fp_conditional_move (operands)
+     rtx operands[];
+{
+#undef CONSTANT_DOUBLE_P
+#define CONSTANT_DOUBLE_P(X) (GET_CODE ((X)) == CONST_DOUBLE)
+
+  /* We have 4 cases:
+
+     1. operand 2 is immediate and operand 3 is immediate.
+     2. operand 2 is immediate and operand 3 is non-immediate.
+     3. operand 3 is non-immediate and operand 3 is immediate.
+     4. operand 3 is non-immediate and operand 3 is non-immediate.
+   */
+  if ((reload_in_progress | reload_completed) == 0
+      && ((CONSTANT_DOUBLE_P (operands [2])
+	   && CONSTANT_DOUBLE_P (operands [3]))
+	  || (CONSTANT_DOUBLE_P (operands [2])
+	      && !CONSTANT_DOUBLE_P (operands [3]))
+ 	  || (!CONSTANT_DOUBLE_P (operands [2])
+	      && CONSTANT_DOUBLE_P (operands [3]))))
+    {
+      /* Case 1, 2 and 3. */
+      rtx fp_const, reg, insn, note;
+      int i, start, end;
+      enum machine_mode mode = GET_MODE (operands [0]);
+
+      if (flag_pic)
+	current_function_uses_pic_offset_table = 1;
+
+      /* Case 1. */
+      if (CONSTANT_DOUBLE_P (operands [2])
+	  && CONSTANT_DOUBLE_P (operands [3]))
+	{
+	  start = 2;
+	  end = 3;
+	}
+      else
+	{
+	   /* Case 2 and 3. */
+	   start = CONSTANT_DOUBLE_P (operands [2]) ? 2 : 3;
+	   end = start;
+	}
+
+	for (i = start; i <= end; i++)
+	  {
+	    fp_const = force_const_mem (mode, operands [i]);
+	    reg = gen_reg_rtx (mode);
+
+	    insn = emit_insn (gen_rtx_SET (mode, reg, fp_const));
+	    note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+	    if (note)
+	      XEXP (note, 0) = operands[i];
+	    else
+	      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
+						    operands[i],
+						    REG_NOTES (insn));
+
+	    operands[i] = reg;
+	  }
+    }
+  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+}
+
+void
+expand_int_conditional_move (operands)
+     rtx operands[];
+{
+#undef CONSTANT_INT_P(X)
+#define CONSTANT_INT_P(X) CONSTANT_P(X)
+
+  /* We have 4 cases:
+
+     1. operand 2 is immediate and operand 3 is immediate.
+     2. operand 2 is immediate and operand 3 is non-immediate.
+     3. operand 3 is non-immediate and operand 3 is immediate.
+     4. operand 3 is non-immediate and operand 3 is non-immediate.
+   */
+  if ((reload_in_progress | reload_completed) == 0
+      && ((CONSTANT_INT_P (operands [2])
+	   && CONSTANT_INT_P (operands [3]))
+	  || (CONSTANT_INT_P (operands [2])
+	      && !CONSTANT_INT_P (operands [3]))
+ 	  || (!CONSTANT_INT_P (operands [2])
+	      && CONSTANT_INT_P (operands [3]))))
+    {
+      /* Case 1, 2 and 3. */
+      rtx int_const, reg, insn, note;
+      int i, start, end;
+      enum machine_mode mode = GET_MODE (operands [0]);
+
+      if (flag_pic)
+	current_function_uses_pic_offset_table = 1;
+
+      /* Case 1. */
+      if (CONSTANT_INT_P (operands [2])
+	  && CONSTANT_INT_P (operands [3]))
+	{
+	  start = 2;
+	  end = 3;
+	}
+      else
+	{
+	   /* Case 2 and 3. */
+	   start = CONSTANT_INT_P (operands [2]) ? 2 : 3;
+	   end = start;
+	}
+
+	for (i = start; i <= end; i++)
+	  {
+	    int_const = force_const_mem (mode, operands [i]);
+	    reg = gen_reg_rtx (mode);
+
+	    insn = emit_insn (gen_rtx_SET (mode, reg, int_const));
+	    note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+	    if (note)
+	      XEXP (note, 0) = operands[i];
+	    else
+	      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
+						    operands[i],
+						    REG_NOTES (insn));
+
+	    operands[i] = reg;
+	  }
+    }
+  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
 }
Index: config/i386/i386.md
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.1.1.16
diff -u -p -r1.1.1.16 i386.md
--- i386.md	1998/05/16 23:54:20	1.1.1.16
+++ i386.md	1998/05/18 14:00:00
@@ -7229,260 +7230,114 @@ byte_xor_operation:
 
 /* Conditional move define_insns.  */
 
-;; These are all disabled, because they are buggy.  They are all susceptible
-;; to problems with input reloads clobbering the condition code registers.
-;; It appears the only safe way to write a integer/FP conditional move pattern
-;; is to write one which emits both the compare and the cmov, and which can be
-;; split only after reload.
-
 (define_expand "movsicc"
   [(match_dup 4)
-   (parallel [(set (match_operand 0 "register_operand" "")
+   (set (match_operand 0 "register_operand" "")
 	(if_then_else:SI (match_operand 1 "comparison_operator" "")
 			 (match_operand:SI 2 "general_operand" "")
-			 (match_operand:SI 3 "general_operand" "")))
-   (clobber (match_scratch:SI 4 "=&r"))])]
-  "0 && TARGET_CMOVE"
+			 (match_operand:SI 3 "general_operand" "")))]
+  "TARGET_CMOVE"
   "
 {
-  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+  expand_int_conditional_move (operands);
 }")
 
 (define_expand "movhicc"
   [(match_dup 4)
-   (parallel [(set (match_operand 0 "register_operand" "")
+   (set (match_operand 0 "register_operand" "")
 	(if_then_else:HI (match_operand 1 "comparison_operator" "")
 			 (match_operand:HI 2 "general_operand" "")
-			 (match_operand:HI 3 "general_operand" "")))
-   (clobber (match_scratch:SI 4 "=&r"))])]
-  "0 && TARGET_CMOVE"
+			 (match_operand:HI 3 "general_operand" "")))]
+  "TARGET_CMOVE"
   "
 {
-  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+  expand_int_conditional_move (operands);
 }")
 
 (define_insn "movsicc_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm")
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r")
 	(if_then_else:SI (match_operator 1 "comparison_operator" 
 				[(cc0) (const_int 0)])
-		      (match_operand:SI 2 "general_operand" "rm,0,rm,g")
-		      (match_operand:SI 3 "general_operand" "0,rm,rm,g")))
-   (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
-  "0 && TARGET_CMOVE"
-  "*
-{
-  if (which_alternative == 0)
-    {
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-    }
-  else if (which_alternative == 1)
-    {
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-    }
-  else if (which_alternative == 2)
-    {
-      /* r <- cond ? arg1 : arg2 */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-    }
-  else if (which_alternative == 3)
-    {
-      /* r <- cond ? arg1 : arg2 */
-    rtx xops[3];
-
-    xops[0] = gen_label_rtx ();
-    xops[1] = gen_label_rtx ();
-    xops[2] = operands[1];
-
-    output_asm_insn (\"j%c2 %l0\", xops);
-    if (! rtx_equal_p (operands[0], operands[2]))
-       if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
-         {
-           output_asm_insn (AS2 (mov%z2,%2,%4), operands);
-           output_asm_insn (AS2 (mov%z2,%4,%0), operands);
-         }
-       else
-      output_asm_insn (AS2 (mov%z0,%2,%0), operands);
-    output_asm_insn (\"jmp %l1\", xops);
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
-    if (! rtx_equal_p (operands[0], operands[3]))
-      {
-        if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
-          {
-            output_asm_insn (AS2 (mov%z3,%3,%4), operands);
-            output_asm_insn (AS2 (mov%z3,%4,%0), operands);
-          }
-        else
-      output_asm_insn (AS2 (mov%z0,%3,%0), operands);
-      }
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
-    }  
-  RET;
-}")
+		      (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
+		      (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
+  "TARGET_CMOVE"
+  "* return output_int_conditional_move (which_alternative, operands);")
 
 (define_insn "movhicc_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm")
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r")
 	(if_then_else:HI (match_operator 1 "comparison_operator" 
 				[(cc0) (const_int 0)])
-		      (match_operand:HI 2 "general_operand" "rm,0,rm,g")
-		      (match_operand:HI 3 "general_operand" "0,rm,rm,g")))
-   (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
-  "0 && TARGET_CMOVE"
-  "*
-{
-  if (which_alternative == 0)
-    {
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-    }
-  else if (which_alternative == 1)
-    {
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-    }
-  else if (which_alternative == 2)
-    {
-      /* r <- cond ? arg1 : arg2 */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-    }
-  else if (which_alternative == 3)
-    {
-      /* r <- cond ? arg1 : arg2 */
-    rtx xops[3];
-
-    xops[0] = gen_label_rtx ();
-    xops[1] = gen_label_rtx ();
-    xops[2] = operands[1];
-
-    output_asm_insn (\"j%c2 %l0\", xops);
-    if (! rtx_equal_p (operands[0], operands[2]))
-       if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
-         {
-           output_asm_insn (AS2 (mov%z2,%2,%4), operands);
-           output_asm_insn (AS2 (mov%z2,%4,%0), operands);
-         }
-       else
-      output_asm_insn (AS2 (mov%z0,%2,%0), operands);
-    output_asm_insn (\"jmp %l1\", xops);
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
-    if (! rtx_equal_p (operands[0], operands[3]))
-      {
-        if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
-          {
-            output_asm_insn (AS2 (mov%z3,%3,%4), operands);
-            output_asm_insn (AS2 (mov%z3,%4,%0), operands);
-          }
-        else
-      output_asm_insn (AS2 (mov%z0,%3,%0), operands);
-      }
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
-    }  
-  RET;
-}")
+		      (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
+		      (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
+  "TARGET_CMOVE"
+  "* return output_int_conditional_move (which_alternative, operands);")
+
 ;; We need to disable the FP forms of these since they do not support
 ;; memory as written, but no input reloads are permitted for insns
 ;; that use cc0.  Also, movxfcc is not present.
 
 (define_expand "movsfcc"
   [(match_dup 4)
-   (set (match_operand 0 "register_operand" "")
+   (set (match_operand 0 "register_operand" "t")
 	(if_then_else:SF (match_operand 1 "comparison_operator" "")
-			 (match_operand:SF 2 "register_operand" "")
-			 (match_operand:SF 3 "register_operand" "")))]
-  "0 && TARGET_CMOVE"
+			 (match_operand:SF 2 "general_operand" "")
+			 (match_operand:SF 3 "general_operand" "")))]
+  "TARGET_CMOVE"
   "
 {
-  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+  expand_fp_conditional_move (operands);
 }")
 
 (define_expand "movdfcc"
   [(match_dup 4)
    (set (match_operand 0 "register_operand" "t")
 	(if_then_else:DF (match_operand 1 "comparison_operator" "")
-			 (match_operand:DF 2 "register_operand" "")
-			 (match_operand:DF 3 "register_operand" "")))]
-  "0 && TARGET_CMOVE"
+			 (match_operand:DF 2 "general_operand" "")
+			 (match_operand:DF 3 "general_operand" "")))]
+  "TARGET_CMOVE"
   "
 {
-  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+  expand_fp_conditional_move (operands);
 }")
 
 (define_expand "movxfcc"
   [(match_dup 4)
-   (set (match_operand 0 "register_operand" "")
+   (set (match_operand 0 "register_operand" "t")
 	(if_then_else:XF (match_operand 1 "comparison_operator" "")
-			 (match_operand:XF 2 "register_operand" "")
-			 (match_operand:XF 3 "register_operand" "")))]
-  "0 && TARGET_CMOVE"
+			 (match_operand:XF 2 "general_operand" "")
+			 (match_operand:XF 3 "general_operand" "")))]
+  "TARGET_CMOVE"
   "
 {
-  operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
+  expand_fp_conditional_move (operands);
 }")
 
 (define_insn "movsfcc_1"
-  [(set (match_operand:SF 0 "general_operand" "=f,f,&f")
+  [(set (match_operand:SF 0 "register_operand" "=f,=f,=f,=f")
 	(if_then_else:SF (match_operator 1 "comparison_operator" 
 					 [(cc0) (const_int 0)])
-			 (match_operand:SF 2 "register_operand" "0,f,f")
-			 (match_operand:SF 3 "register_operand" "f,0,f")))]
-  "0 && TARGET_CMOVE"
-  "*
-{
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      break;
+			 (match_operand:SF 2 "nonimmediate_operand" "0,f,f,fm")
+			 (match_operand:SF 3 "nonimmediate_operand" "f,0,f,fm")))]
+  "TARGET_CMOVE"
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
-    case 2:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
-      break;
-    }
-
-  RET;
-}")
-
 (define_insn "movdfcc_1"
-  [(set (match_operand:DF 0 "general_operand" "=f,f,&f")
+  [(set (match_operand:DF 0 "register_operand" "=f,=f,=f,=f")
 	(if_then_else:DF (match_operator 1 "comparison_operator" 
 					 [(cc0) (const_int 0)])
-			 (match_operand:DF 2 "register_operand" "0,f,f")
-			 (match_operand:DF 3 "register_operand" "f,0,f")))]
-  "0 && TARGET_CMOVE"
-  "*
-{
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      break;
-
-    case 2:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
-      break;
-    }
-
-  RET;
-}")
+			 (match_operand:DF 2 "nonimmediate_operand" "0,f,f,fm")
+			 (match_operand:DF 3 "nonimmediate_operand" "f,0,f,fm")))]
+  "TARGET_CMOVE"
+  "* return output_fp_conditional_move (which_alternative, operands);")
+
+(define_insn "movxfcc_1"
+  [(set (match_operand:XF 0 "register_operand" "=f,=f,=f,=f")
+	(if_then_else:XF (match_operator 1 "comparison_operator" 
+				[(cc0) (const_int 0)])
+		      (match_operand:XF 2 "nonimmediate_operand" "0,f,f,fm")
+		      (match_operand:XF 3 "nonimmediate_operand" "f,0,f,fm")))]
+  "TARGET_CMOVE"
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_insn "strlensi_unroll"
   [(set (match_operand:SI 0 "register_operand" "=&r,&r")

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1998-05-18 20:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-05-18 20:07 A new ppro patch for egcs 980518 H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).