This is the mail archive of the gcc@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]

A patch for PPro


> I reported a couple of bugs concerning bootstraping
> egcs-19980428 using "-O6 -march=pentiumpro
>  -mcpu=pentiumpro -fexpensive-optimizations".
> 
> The bootstrap failed due to diffs in all the object files
> between stage2 and stage3.
> 
> I managed to identify that its the compilation of
> init_reg_sets_1() in gcc/regclass.c that results in the
> differences.
> 

Hi,

This patch seems to fix all the PPro bugs I have known. Please
give a try and let me know what you get.

Jim, can you take a look at it? Thanks.

BTW, it is against egcs in CVS on 980509. I will send in some test
cases tomorrow.


H.J.
---
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.
	(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: config/i386/i386.md
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.1.1.15
diff -u -r1.1.1.15 i386.md
--- i386.md	1998/05/09 20:34:36	1.1.1.15
+++ i386.md	1998/05/14 18:22:56
@@ -7225,260 +7226,120 @@
 
 /* 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.
 
+;; 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 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 "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;
-
-    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:SF 2 "nonimmediate_operand" "0,f,f,fFm")
+			 (match_operand:SF 3 "nonimmediate_operand" "f,0,f,fFm")))]
+  "TARGET_CMOVE"
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
 (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,fFm")
+			 (match_operand:DF 3 "nonimmediate_operand" "f,0,f,fFm")))]
+  "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,fFm")
+		      (match_operand:XF 3 "nonimmediate_operand" "f,0,f,fFm")))]
+  "TARGET_CMOVE"
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_insn "strlensi_unroll"
   [(set (match_operand:SI 0 "register_operand" "=&r,&r")
Index: config/i386/i386.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.1.1.15
diff -u -p -r1.1.1.15 i386.c
--- i386.c	1998/05/07 15:46:40	1.1.1.15
+++ i386.c	1998/05/14 19:51:14
@@ -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: reg-stack.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/reg-stack.c,v
retrieving revision 1.1.1.15
diff -u -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:34:48
@@ -2344,6 +2345,13 @@
       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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]