aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-09-19 18:14:20 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-09-19 18:14:20 +0200
commit5a1357fbe0ab7a5090d52796850e07b354dcef90 (patch)
tree6d071c208a3917120559d071367d4cfe11f42e0b /gcc
parentdac8a1db734e1ceb04d7decdf038e501bfdf9c06 (diff)
downloadgcc-5a1357fbe0ab7a5090d52796850e07b354dcef90.zip
gcc-5a1357fbe0ab7a5090d52796850e07b354dcef90.tar.gz
gcc-5a1357fbe0ab7a5090d52796850e07b354dcef90.tar.bz2
sse.md (*sse4_1_extractps): Change into define_insn_and_split...
* 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. From-SVN: r178976
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/sse.md48
2 files changed, 43 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 81c4492..5c65c31 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 4567ee9..6b8df03 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -4000,19 +4000,45 @@
(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")