+(define_expand "avx2_extracti128"
+ [(match_operand:V2DI 0 "nonimmediate_operand" "")
+ (match_operand:V4DI 1 "register_operand" "")
+ (match_operand:SI 2 "const_0_to_1_operand" "")]
+ "TARGET_AVX2"
+{
+ rtx (*insn)(rtx, rtx);
+
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ insn = gen_vec_extract_lo_v4di;
+ break;
+ case 1:
+ insn = gen_vec_extract_hi_v4di;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ emit_insn (insn (operands[0], operands[1]));
+ DONE;
+})
+
+(define_expand "avx2_inserti128"
+ [(match_operand:V4DI 0 "register_operand" "")
+ (match_operand:V4DI 1 "register_operand" "")
+ (match_operand:V2DI 2 "nonimmediate_operand" "")
+ (match_operand:SI 3 "const_0_to_1_operand" "")]
+ "TARGET_AVX2"
+{
+ rtx (*insn)(rtx, rtx, rtx);
+
+ switch (INTVAL (operands[3]))
+ {
+ case 0:
+ insn = gen_avx2_vec_set_lo_v4di;
+ break;
+ case 1:
+ insn = gen_avx2_vec_set_hi_v4di;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ emit_insn (insn (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "avx2_ashrvv8si"
+ [(set (match_operand:V8SI 0 "register_operand" "=x")
+ (vec_concat:V8SI
+ (vec_concat:V4SI
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_operand:V8SI 1 "register_operand" "x")
+ (parallel [(const_int 0)]))
+ (vec_select:SI
+ (match_operand:V8SI 2 "nonimmediate_operand" "xm")
+ (parallel [(const_int 0)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 3)])))))
+ (vec_concat:V4SI
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 0)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 3)])))))))]
+ "TARGET_AVX2"
+ "vpsravd\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "OI")])
+
+(define_insn "avx2_ashrvv4si"
+ [(set (match_operand:V4SI 0 "register_operand" "=x")
+ (vec_concat:V4SI
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_operand:V4SI 1 "register_operand" "x")
+ (parallel [(const_int 0)]))
+ (vec_select:SI
+ (match_operand:V4SI 2 "nonimmediate_operand" "xm")
+ (parallel [(const_int 0)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:V2SI
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (ashiftrt:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 3)]))))))]
+ "TARGET_AVX2"
+ "vpsravd\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "TI")])
+
+(define_insn "avx2_<lshift>vv8si"
+ [(set (match_operand:V8SI 0 "register_operand" "=x")
+ (vec_concat:V8SI
+ (vec_concat:V4SI
+ (vec_concat:V2SI
+ (lshift:SI
+ (vec_select:SI
+ (match_operand:V8SI 1 "register_operand" "x")
+ (parallel [(const_int 0)]))
+ (vec_select:SI
+ (match_operand:V8SI 2 "nonimmediate_operand" "xm")
+ (parallel [(const_int 0)])))
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:V2SI
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 3)])))))
+ (vec_concat:V4SI
+ (vec_concat:V2SI
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 0)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 0)])))
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:V2SI
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (lshift:SI
+ (vec_select:SI
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:SI
+ (match_dup 2)
+ (parallel [(const_int 3)])))))))]
+ "TARGET_AVX2"
+ "vp<lshift_insn>vd\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "OI")])
+
+(define_insn "avx2_<lshift>v<mode>"
+ [(set (match_operand:VI4SD_AVX2 0 "register_operand" "=x")
+ (vec_concat:VI4SD_AVX2
+ (vec_concat:<ssehalfvecmode>
+ (lshift:<ssescalarmode>
+ (vec_select:<ssescalarmode>
+ (match_operand:VI4SD_AVX2 1 "register_operand" "x")
+ (parallel [(const_int 0)]))
+ (vec_select:<ssescalarmode>
+ (match_operand:VI4SD_AVX2 2 "nonimmediate_operand" "xm")
+ (parallel [(const_int 0)])))
+ (lshift:<ssescalarmode>
+ (vec_select:<ssescalarmode>
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:<ssescalarmode>
+ (match_dup 2)
+ (parallel [(const_int 1)]))))
+ (vec_concat:<ssehalfvecmode>
+ (lshift:<ssescalarmode>
+ (vec_select:<ssescalarmode>
+ (match_dup 1)
+ (parallel [(const_int 2)]))
+ (vec_select:<ssescalarmode>
+ (match_dup 2)
+ (parallel [(const_int 2)])))
+ (lshift:<ssescalarmode>
+ (vec_select:<ssescalarmode>
+ (match_dup 1)
+ (parallel [(const_int 3)]))
+ (vec_select:<ssescalarmode>
+ (match_dup 2)
+ (parallel [(const_int 3)]))))))]
+ "TARGET_AVX2"
+ "vp<lshift_insn>v<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "avx2_<lshift>vv2di"
+ [(set (match_operand:V2DI 0 "register_operand" "=x")
+ (vec_concat:V2DI
+ (lshift:DI
+ (vec_select:DI
+ (match_operand:V2DI 1 "register_operand" "x")
+ (parallel [(const_int 0)]))
+ (vec_select:DI
+ (match_operand:V2DI 2 "nonimmediate_operand" "xm")
+ (parallel [(const_int 0)])))
+ (lshift:DI
+ (vec_select:DI
+ (match_dup 1)
+ (parallel [(const_int 1)]))
+ (vec_select:DI
+ (match_dup 2)
+ (parallel [(const_int 1)])))))]
+ "TARGET_AVX2"
+ "vp<lshift_insn>vq\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "TI")])
+
+(define_insn "avx_vec_concat<mode>"