aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c15
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md187
4 files changed, 153 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ef5c84..3434003 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+Mon Feb 10 00:29:17 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (vector_move_operand): New predicate.
+ (ix86_expand_vector_move): Be happy about 0.
+ * i386.h (PREDICATE_CODES): Add sse-move_operand.
+ * i386.md (mov*_internal): Add 'C' alternative.
+
Sun Feb 9 23:58:33 CET 2003 Jan Hubicka <jh@suse.cz>
* i386.md (floathi*): Deal with SSE.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b9b2c32..04da441 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3736,6 +3736,19 @@ zero_extended_scalar_load_operand (op, mode)
return 1;
}
+/* Return 1 when OP is operand acceptable for standard SSE move. */
+int
+vector_move_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (nonimmediate_operand (op, mode))
+ return 1;
+ if (GET_MODE (op) != mode && mode != VOIDmode)
+ return 0;
+ return (op == CONST0_RTX (GET_MODE (op)));
+}
+
/* Return 1 if OP is a comparison that can be used in the CMPSS/CMPPS
insns. */
int
@@ -8161,7 +8174,7 @@ ix86_expand_vector_move (mode, operands)
to handle some of them more efficiently. */
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands[0], mode)
- && CONSTANT_P (operands[1]))
+ && CONSTANT_P (operands[1]) && operands[1] != CONST0_RTX (mode))
operands[1] = validize_mem (force_const_mem (mode, operands[1]));
/* Make operand1 a register if it isn't already. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 8373e32..11349f9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3039,6 +3039,7 @@ do { \
{"fp_register_operand", {REG}}, \
{"register_and_not_fp_reg_operand", {REG}}, \
{"zero_extended_scalar_load_operand", {MEM}}, \
+ {"vector_move_operand", {CONST_VECTOR, SUBREG, REG, MEM}}, \
/* A list of predicates that do special things with modes, and so
should not elicit warnings for VOIDmode match_operand. */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a751513..591d7ff 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -18706,10 +18706,13 @@
;; Moves for SSE/MMX regs.
(define_insn "movv4sf_internal"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
- (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
- "movaps\t{%1, %0|%0, %1}"
+ "@
+ xorps\t%0, %0
+ movaps\t{%1, %0|%0, %1}
+ movaps\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
(set_attr "mode" "V4SF")])
@@ -18728,24 +18731,36 @@
})
(define_insn "movv4si_internal"
- [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
- (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
{
- if (get_attr_mode (insn) == MODE_V4SF)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movdqa\t{%1, %0|%0, %1}";
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0")
+ (cond [(eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
(const_string "V4SF")
(const_string "TI"))
- (eq_attr "alternative" "1")
+ (eq_attr "alternative" "2")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0))
@@ -18756,24 +18771,36 @@
(const_string "TI")))])
(define_insn "movv2di_internal"
- [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,m")
- (match_operand:V2DI 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE2"
{
- if (get_attr_mode (insn) == MODE_V4SF)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movdqa\t{%1, %0|%0, %1}";
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0")
+ (cond [(eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
(const_string "V4SF")
(const_string "TI"))
- (eq_attr "alternative" "1")
+ (eq_attr "alternative" "2")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0))
@@ -18798,38 +18825,50 @@
})
(define_insn "movv8qi_internal"
- [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
- (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
+ (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
"TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "movq\t{%1, %0|%0, %1}"
+ "@
+ pxor\t%0, %0
+ movq\t{%1, %0|%0, %1}
+ movq\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxmov")
(set_attr "mode" "DI")])
(define_insn "movv4hi_internal"
- [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
- (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
+ (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
"TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "movq\t{%1, %0|%0, %1}"
+ "@
+ pxor\t%0, %0
+ movq\t{%1, %0|%0, %1}
+ movq\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxmov")
(set_attr "mode" "DI")])
(define_insn "movv2si_internal"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
- (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
+ (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
"TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "movq\t{%1, %0|%0, %1}"
+ "@
+ pxor\t%0, %0
+ movq\t{%1, %0|%0, %1}
+ movq\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_insn "movv2sf_internal"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
- (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
+ (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
"TARGET_3DNOW
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "movq\\t{%1, %0|%0, %1}"
+ "@
+ pxor\t%0, %0
+ movq\t{%1, %0|%0, %1}
+ movq\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
@@ -18846,25 +18885,37 @@
})
(define_insn "movv2df_internal"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
- (match_operand:V2DF 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
- if (get_attr_mode (insn) == MODE_V4SF)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movapd\t{%1, %0|%0, %1}";
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "xorpd\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movapd\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0")
+ (cond [(eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
(const_string "V4SF")
(const_string "V2DF"))
- (eq_attr "alternative" "1")
+ (eq_attr "alternative" "2")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0))
@@ -18875,25 +18926,37 @@
(const_string "V2DF")))])
(define_insn "movv8hi_internal"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
- (match_operand:V8HI 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
- if (get_attr_mode (insn) == MODE_V4SF)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movdqa\t{%1, %0|%0, %1}";
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0")
+ (cond [(eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
(const_string "V4SF")
(const_string "TI"))
- (eq_attr "alternative" "1")
+ (eq_attr "alternative" "2")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0))
@@ -18904,25 +18967,37 @@
(const_string "TI")))])
(define_insn "movv16qi_internal"
- [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
- (match_operand:V16QI 1 "nonimmediate_operand" "xm,x"))]
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
- if (get_attr_mode (insn) == MODE_V4SF)
- return "movaps\t{%1, %0|%0, %1}";
- else
- return "movdqa\t{%1, %0|%0, %1}";
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0")
+ (cond [(eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
(const_string "V4SF")
(const_string "TI"))
- (eq_attr "alternative" "1")
+ (eq_attr "alternative" "2")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
(const_int 0))
@@ -19113,7 +19188,7 @@
(define_insn "movti_internal"
[(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
- (match_operand:TI 1 "general_operand" "C,xm,x"))]
+ (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE && !TARGET_64BIT
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{