aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c42
-rw-r--r--gcc/config/i386/i386.md12
3 files changed, 58 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 263364d..10018db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index bb7d827..cb6c1ba 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 5ad64fa..32a5281 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -17443,7 +17443,7 @@
[(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"
@@ -17457,9 +17457,9 @@
(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"
@@ -17512,7 +17512,7 @@
[(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"
@@ -17526,9 +17526,9 @@
(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"