PR target/19506
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Jan 2005 23:07:53 +0000 (23:07 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Jan 2005 23:07:53 +0000 (23:07 +0000)
        * config/i386/i386.md (movsfcc_1_sse_max): Use nonimmediate_operand
        in both compare operands.
        (movdfcc_1_sse_max): Likewise.
        (movsfcc_1_sse): Likewise.  Add earlyclobber for scratch.
        (movdfcc_1_sse): Likewise.
        * config/i386/i386.c (ix86_split_sse_movcc): Emit copies into the
        scratch register as needed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94087 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 263364d..10018db 100644 (file)
@@ -1,5 +1,16 @@
 2005-01-22  Richard Henderson  <rth@redhat.com>
 
+       PR target/19506
+       * config/i386/i386.md (movsfcc_1_sse_max): Use nonimmediate_operand
+       in both compare operands.
+       (movdfcc_1_sse_max): Likewise.
+       (movsfcc_1_sse): Likewise.  Add earlyclobber for scratch.
+       (movdfcc_1_sse): Likewise.
+       * config/i386/i386.c (ix86_split_sse_movcc): Emit copies into the
+       scratch register as needed.
+
+2005-01-22  Richard Henderson  <rth@redhat.com>
+
        * config/i386/i386.md (smaxsf3): Fix mnemonic typo.
 
        * config/i386/i386.c (ix86_prepare_fp_compare_args): Fix is_sse test.
index bb7d827..cb6c1ba 100644 (file)
@@ -9920,8 +9920,48 @@ ix86_split_sse_movcc (rtx operands[])
   mode = GET_MODE (dest);
   vmode = GET_MODE (scratch);
 
-  emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
+  /* We need to make sure that the TRUE and FALSE operands are out of the
+     way of the destination.  Marking the destination earlyclobber doesn't
+     work, since we want matching constraints for the actual comparison, so
+     at some point we always wind up having to do a copy ourselves here.
+     We very much prefer the TRUE value to be in SCRATCH.  If it turns out
+     that FALSE overlaps DEST, then we invert the comparison so that we
+     still only have to do one move.  */
+  if (rtx_equal_p (op_false, dest))
+    {
+      enum rtx_code code;
+
+      if (rtx_equal_p (op_true, dest))
+       {
+         /* ??? Really ought not happen.  It means some optimizer managed
+            to prove the operands were identical, but failed to fold the
+            conditional move to a straight move.  Do so here, because 
+            otherwise we'll generate incorrect code.  And since they're
+            both already in the destination register, nothing to do.  */
+         return;
+       }
+
+      x = gen_rtx_REG (mode, REGNO (scratch));
+      emit_move_insn (x, op_false);
+      op_false = op_true;
+      op_true = x;
 
+      code = GET_CODE (cmp);
+      code = reverse_condition_maybe_unordered (code);
+      cmp = gen_rtx_fmt_ee (code, mode, XEXP (cmp, 0), XEXP (cmp, 1));
+    }
+  else if (op_true == CONST0_RTX (mode))
+    ;
+  else if (op_false == CONST0_RTX (mode) && !rtx_equal_p (op_true, dest))
+    ;
+  else
+    {
+      x = gen_rtx_REG (mode, REGNO (scratch));
+      emit_move_insn (x, op_true);
+      op_true = x;
+    }
+
+  emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
   dest = simplify_gen_subreg (vmode, dest, mode, 0);
 
   if (op_false == CONST0_RTX (mode))
index 5ad64fa..32a5281 100644 (file)
   [(set (match_operand:SF 0 "register_operand" "=x")
        (if_then_else:SF
          (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
-                (match_operand:SF 1 "register_operand" "0"))
+                (match_operand:SF 1 "nonimmediate_operand" "0"))
          (match_dup 1)
          (match_dup 2)))]
   "TARGET_SSE_MATH"
          (match_operator:SF 4 "sse_comparison_operator"
            [(match_operand:SF 5 "register_operand" "0,0,0")
             (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
-         (match_operand:SF 2 "reg_or_0_operand" "C,x,1")
+         (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
          (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
-   (clobber (match_scratch:V4SF 1 "=X,X,x"))]
+   (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
   "TARGET_SSE_MATH"
   "#"
   "&& reload_completed"
   [(set (match_operand:DF 0 "register_operand" "=x")
        (if_then_else:DF
          (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
-                (match_operand:DF 1 "register_operand" "0"))
+                (match_operand:DF 1 "nonimmediate_operand" "0"))
          (match_dup 1)
          (match_dup 2)))]
   "TARGET_SSE2 && TARGET_SSE_MATH"
          (match_operator:DF 4 "sse_comparison_operator"
            [(match_operand:DF 5 "register_operand" "0,0,0")
             (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
-         (match_operand:DF 2 "reg_or_0_operand" "C,x,1")
+         (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
          (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
-   (clobber (match_scratch:V2DF 1 "=X,X,x"))]
+   (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
   "TARGET_SSE2 && TARGET_SSE_MATH"
   "#"
   "&& reload_completed"