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]

PPro patch for egcs


Hi, John,

Thanks for your PPro work. It looks great.

Jeff, here is a patch which fixes many others PPro bugs.

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
----
Mon Jun  1 07:38:42 1998  H.J. Lu  (hjl@gnu.org)

	* config/i386/i386.c (output_fp_conditional_move): New function
	to output floating point conditional move.
	(output_int_conditional_move): New function to output integer
	conditional move.

	* config/i386/i386.md (movsicci+5, movhicc+5, movdicc+5): Call
	output_int_conditional_move () to output int conditional move.
	(movsfcc+5, movdfcc+5, movxfcc+5): Call
	output_fp_conditional_move () to output floating point
	conditional move.

Tue May 19 06:51:19 1998  H.J. Lu  (hjl@gnu.org)

	* config/i386/i386.c (notice_update_cc, output_float_compare):
	Enable TARGET_CMOVE support.

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.

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.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.1.1.17
diff -u -p -r1.1.1.17 i386.c
--- i386.c	1998/05/22 14:05:25	1.1.1.17
+++ i386.c	1998/06/01 17:23:03
@@ -48,7 +48,7 @@ Boston, MA 02111-1307, USA. */
@@ -3097,7 +3106,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:
@@ -3109,7 +3121,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:
@@ -3691,7 +3706,7 @@ notice_update_cc (exp)
           if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
 	    {
               cc_status.flags |= CC_IN_80387;
-	      if (0 && TARGET_CMOVE && stack_regs_mentioned_p
+	      if (TARGET_CMOVE && stack_regs_mentioned_p
 		  (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
 		cc_status.flags |= CC_FCOMI;
 	    }
@@ -4021,7 +4036,7 @@ output_float_compare (insn, operands)
   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
   rtx tmp;
 
-  if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
+  if (TARGET_CMOVE && STACK_REG_P (operands[1]))
     {
       cc_status.flags |= CC_FCOMI;
       cc_prev_status.flags &= ~CC_TEST_AX;
@@ -4055,6 +4070,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
@@ -4096,6 +4123,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
@@ -5129,6 +5167,135 @@ output_strlen_unroll (operands)
   output_asm_insn (AS1 (inc%L0,%0), xops);
 
   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,%2,%0), operands);
+    }
+  else if (which_alternative == 1)
+    {
+      /* r <- cond ? r : arg */
+      output_asm_insn (AS2 (fcmov%f1,%3,%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
+	abort ();
+      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
+	abort ();
+      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 */
+      if (GET_MODE (operands [0]) == DImode)
+	{
+	  rtx xops[3];
+
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 0);
+	  xops [1] = operands [1];
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [2], 0);
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
+	}
+      else
+	{
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
+	}
+    }
+  else if (which_alternative == 1)
+    {
+      /* r <- cond ? r : arg */
+      if (GET_MODE (operands [0]) == DImode)
+	{
+	  rtx xops[3];
+
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 0);
+	  xops [1] = operands [1];
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [3], 0);
+	  output_asm_insn (AS2 (cmov%c1,%2,%0), xops);
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [3], 1);
+	  output_asm_insn (AS2 (cmov%c1,%2,%0), xops);
+	}
+      else
+	{
+	  output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
+	}
+    }
+  else if (which_alternative == 2)
+    {
+      /* rm <- cond ? arg1 : arg2 */
+      if (GET_MODE (operands [0]) == DImode)
+	{
+	  rtx xops[4];
+
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 0);
+	  xops [1] = operands [1];
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [2], 0);
+	  xops [3] = gen_rtx_SUBREG (SImode, operands [3], 0);
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
+	  output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
+	  xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
+	  xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
+	  xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1);
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
+	  output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
+	}
+      else
+	{
+	  output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
+	  output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
+	}
+    }
+  else
+    abort ();
 
   return "";
 }
Index: config/i386/i386.md
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.1.1.17
diff -u -p -r1.1.1.17 i386.md
--- i386.md	1998/06/01 14:19:53	1.1.1.17
+++ i386.md	1998/06/01 14:42:17
@@ -7307,35 +7307,7 @@ byte_xor_operation:
 		      (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
 		      (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      break;
-
-    case 2:
-      /* r <- cond ? arg1 : arg2 */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      break;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
-
-  RET;
-}")
+  "* return output_int_conditional_move (which_alternative, operands);")
 
 (define_expand "movhicc"
   [(set (match_operand:HI 0 "register_operand" "")
@@ -7410,36 +7382,8 @@ byte_xor_operation:
 		      (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
 		      (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      break;
-
-    case 2:
-      /* r <- cond ? arg1 : arg2 */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      break;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
+  "* return output_int_conditional_move (which_alternative, operands);")
 
-  RET;
-}")
-
 (define_expand "movsfcc"
   [(set (match_operand:SF 0 "register_operand" "")
 	(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -7512,35 +7456,7 @@ byte_xor_operation:
 		      (match_operand:SF 2 "register_operand" "f,0,f")
 		      (match_operand:SF 3 "register_operand" "0,f,f")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%f1,%3,%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;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
-
-  RET;
-}")
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_expand "movdfcc"
   [(set (match_operand:DF 0 "register_operand" "")
@@ -7614,35 +7530,7 @@ byte_xor_operation:
 		      (match_operand:DF 2 "register_operand" "f,0,f")
 		      (match_operand:DF 3 "register_operand" "0,f,f")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%f1,%3,%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;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
-
-  RET;
-}")
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_expand "movxfcc"
   [(set (match_operand:XF 0 "register_operand" "")
@@ -7716,36 +7604,8 @@ byte_xor_operation:
 		      (match_operand:XF 2 "register_operand" "f,0,f")
 		      (match_operand:XF 3 "register_operand" "0,f,f")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (fcmov%f1,%3,%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;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
+  "* return output_fp_conditional_move (which_alternative, operands);")
 
-  RET;
-}")
-
 (define_expand "movdicc"
   [(set (match_operand:DI 0 "register_operand" "")
 	(if_then_else:DI (match_operand 1 "comparison_operator" "")
@@ -7818,49 +7678,7 @@ byte_xor_operation:
 		      (match_operand:DI 2 "nonimmediate_operand" "ro,0,ro")
 		      (match_operand:DI 3 "nonimmediate_operand" "0,ro,ro")))]
   "TARGET_CMOVE && reload_completed"
-  "*
-{
-  rtx xops[4];
-
-  xops[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  xops[1] = operands[1];
-  xops[2] = REG_P (operands[2])
-		? gen_rtx_REG (SImode, REGNO (operands[2]) + 1)
-		: adj_offsettable_operand (operands[2], 4);
-  xops[3] = REG_P (operands[3])
-		? gen_rtx_REG (SImode, REGNO (operands[3]) + 1)
-		: adj_offsettable_operand (operands[3], 4);
-
-  switch (which_alternative)
-    {
-    case 0:
-      /* r <- cond ? arg : r */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
-      break;
-
-    case 1:
-      /* r <- cond ? r : arg */
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
-      break;
-
-    case 2:
-      /* r <- cond ? arg1 : arg2 */
-      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
-      output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
-      output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
-      break;
-
-    default:
-      abort();
-    /* NOTREACHED */
-      break;
-    }
-
-  RET;
-}")
+  "* return output_int_conditional_move (which_alternative, operands);")
 
 (define_insn "strlensi_unroll"
   [(set (match_operand:SI 0 "register_operand" "=&r,&r")
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/06/01 14:58:56
@@ -2344,6 +2345,15 @@ subst_stack_regs_pat (insn, regstack, pa
       case IF_THEN_ELSE:
 	/* This insn requires the top of stack to be the destination. */
 
+	/* If the comparison operator is an FP comparison operator,
+	   it is handled correctly by compare_for_stack_reg () who
+	   will move the destination to the top of stack. But if the
+	   comparison operator is not an FP comparison operator, we
+	   have to handle it 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]