diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 81c4492e571..5c65c31a1bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-09-19 Jakub Jelinek + + * 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 * 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 4567ee920d1..6b8df03b053 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")