From fdc4b40b65a63548e89fa7c01ffb1370e62f7bb0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 10 Feb 2003 00:30:51 +0100 Subject: [PATCH] i386.c (vector_move_operand): New predicate. * 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. From-SVN: r62612 --- gcc/ChangeLog | 7 ++ gcc/config/i386/i386.c | 15 +++- gcc/config/i386/i386.h | 1 + gcc/config/i386/i386.md | 187 ++++++++++++++++++++++++++++------------ 4 files changed, 153 insertions(+), 57 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ef5c8464cd..34340032206 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Mon Feb 10 00:29:17 CET 2003 Jan Hubicka + + * 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 * i386.md (floathi*): Deal with SSE. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b9b2c32d3da..04da441a710 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 8373e3250a6..11349f99d81 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 a751513bd27..591d7ff1310 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)" { -- 2.30.2