OSDN Git Service

* config/i386/sse.md (*sse4_1_extractps): Change into
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Sep 2011 16:14:20 +0000 (16:14 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Sep 2011 16:14:20 +0000 (16:14 +0000)
define_insn_and_split, add =x 0 n and =x x n alternatives
and split them after reload.

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

gcc/ChangeLog
gcc/config/i386/sse.md

index 81c4492..5c65c31 100644 (file)
@@ -1,3 +1,9 @@
+2011-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/i386/sse.md (*sse4_1_extractps): Change into
+       define_insn_and_split, add =x 0 n and =x x n alternatives
+       and split them after reload.
+
 2011-09-19  Alexandre Oliva  <aoliva@redhat.com>
 
        * tree.h (TREE_NOT_CHECK4): Rename from bogus NON_TREE_CHECK4.
index 4567ee9..6b8df03 100644 (file)
    (const_string "OI")
    (const_string "V8SF")))])
 
-(define_insn "*sse4_1_extractps"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=rm")
+(define_insn_and_split "*sse4_1_extractps"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,x,x")
        (vec_select:SF
-         (match_operand:V4SF 1 "register_operand" "x")
-         (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
+         (match_operand:V4SF 1 "register_operand" "x,0,x")
+         (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
   "TARGET_SSE4_1"
-  "%vextractps\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "prefix_data16" "1")
-   (set_attr "prefix_extra" "1")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "maybe_vex")
-   (set_attr "mode" "V4SF")])
+  "@
+   %vextractps\t{%2, %1, %0|%0, %1, %2}
+   #
+   #"
+  "&& reload_completed && SSE_REG_P (operands[0])"
+  [(const_int 0)]
+{
+  rtx dest = gen_rtx_REG (V4SFmode, REGNO (operands[0]));
+  switch (INTVAL (operands[2]))
+    {
+    case 1:
+    case 3:
+      emit_insn (gen_sse_shufps_v4sf (dest, operands[1], operands[1],
+                                     operands[2], operands[2],
+                                     GEN_INT (INTVAL (operands[2]) + 4),
+                                     GEN_INT (INTVAL (operands[2]) + 4)));
+      break;
+    case 2:
+      emit_insn (gen_vec_interleave_highv4sf (dest, operands[1], operands[1]));
+      break;
+    default:
+      /* 0 should be handled by the *vec_extractv4sf_0 pattern above.  */
+      gcc_unreachable ();
+    }
+  DONE;
+}
+  [(set_attr "isa" "*,noavx,avx")
+   (set_attr "type" "sselog,*,*")
+   (set_attr "prefix_data16" "1,*,*")
+   (set_attr "prefix_extra" "1,*,*")
+   (set_attr "length_immediate" "1,*,*")
+   (set_attr "prefix" "maybe_vex,*,*")
+   (set_attr "mode" "V4SF,*,*")])
 
 (define_insn_and_split "*vec_extract_v4sf_mem"
   [(set (match_operand:SF 0 "register_operand" "=x*rf")