X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fsse.md;h=393a3161da6ef28549c6080258ee39e54e875ea0;hb=8cae609cdca397a87c1059b07a44ef9b3b63ee53;hp=8ea5bc0048b5d3a7480c1efda35fdf6a12a54c19;hpb=267858a744be0cea0452bc2acbd3b1e95c57dfcf;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 8ea5bc0048b..393a3161da6 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1,5 +1,5 @@ ;; GCC machine description for SSE instructions -;; Copyright (C) 2005, 2006, 2007, 2008 +;; Copyright (C) 2005, 2006, 2007, 2008, 2009 ;; Free Software Foundation, Inc. ;; ;; This file is part of GCC. @@ -26,6 +26,21 @@ ;; All 16-byte vector modes handled by SSE (define_mode_iterator SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF]) +;; 32 byte integral vector modes handled by AVX +(define_mode_iterator AVX256MODEI [V32QI V16HI V8SI V4DI]) + +;; All 32-byte vector modes handled by AVX +(define_mode_iterator AVX256MODE [V32QI V16HI V8SI V4DI V8SF V4DF]) + +;; All QI vector modes handled by AVX +(define_mode_iterator AVXMODEQI [V32QI V16QI]) + +;; All DI vector modes handled by AVX +(define_mode_iterator AVXMODEDI [V4DI V2DI]) + +;; All vector modes handled by AVX +(define_mode_iterator AVXMODE [V16QI V8HI V4SI V2DI V4SF V2DF V32QI V16HI V8SI V4DI V8SF V4DF]) + ;; Mix-n-match (define_mode_iterator SSEMODE12 [V16QI V8HI]) (define_mode_iterator SSEMODE24 [V8HI V4SI]) @@ -36,6 +51,19 @@ (define_mode_iterator SSEMODEF4 [SF DF V4SF V2DF]) (define_mode_iterator SSEMODEF2P [V4SF V2DF]) +(define_mode_iterator AVX256MODEF2P [V8SF V4DF]) +(define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF]) +(define_mode_iterator AVX256MODE4P [V4DI V4DF]) +(define_mode_iterator AVX256MODE8P [V8SI V8SF]) +(define_mode_iterator AVXMODEF2P [V4SF V2DF V8SF V4DF]) +(define_mode_iterator AVXMODEF4P [V4SF V4DF]) +(define_mode_iterator AVXMODEDCVTDQ2PS [V4SF V8SF]) +(define_mode_iterator AVXMODEDCVTPS2DQ [V4SI V8SI]) + +;; Int-float size matches +(define_mode_iterator SSEMODE4S [V4SF V4SI]) +(define_mode_iterator SSEMODE2D [V2DF V2DI]) + ;; Mapping from float mode to required SSE level (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")]) @@ -43,15 +71,68 @@ (define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")]) ;; Mapping of the sse5 suffix -(define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd") (V4SF "ps") (V2DF "pd")]) -(define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd") (V4SF "ss") (V2DF "sd")]) +(define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd") + (V4SF "ps") (V2DF "pd")]) +(define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd") + (V4SF "ss") (V2DF "sd")]) (define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")]) ;; Mapping of the max integer size for sse5 rotate immediate constraint (define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")]) ;; Mapping of vector modes back to the scalar modes -(define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF")]) +(define_mode_attr ssescalarmode [(V4SF "SF") (V2DF "DF") + (V16QI "QI") (V8HI "HI") + (V4SI "SI") (V2DI "DI")]) + +;; Mapping of vector modes to a vector mode of double size +(define_mode_attr ssedoublesizemode [(V2DF "V4DF") (V2DI "V4DI") + (V4SF "V8SF") (V4SI "V8SI")]) + +;; Number of scalar elements in each vector type +(define_mode_attr ssescalarnum [(V4SF "4") (V2DF "2") + (V16QI "16") (V8HI "8") + (V4SI "4") (V2DI "2")]) + +;; Mapping for AVX +(define_mode_attr avxvecmode + [(V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V4SF "V4SF") + (V2DF "V2DF") (V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI") + (V8SF "V8SF") (V4DF "V4DF")]) +(define_mode_attr avxvecpsmode + [(V16QI "V4SF") (V8HI "V4SF") (V4SI "V4SF") (V2DI "V4SF") + (V32QI "V8SF") (V16HI "V8SF") (V8SI "V8SF") (V4DI "V8SF")]) +(define_mode_attr avxhalfvecmode + [(V4SF "V2SF") (V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") + (V4DI "V2DI") (V8SF "V4SF") (V4DF "V2DF")]) +(define_mode_attr avxscalarmode + [(V16QI "QI") (V8HI "HI") (V4SI "SI") (V4SF "SF") (V2DF "DF") + (V8SF "SF") (V4DF "DF")]) +(define_mode_attr avxcvtvecmode + [(V4SF "V4SI") (V8SF "V8SI") (V4SI "V4SF") (V8SI "V8SF")]) +(define_mode_attr avxpermvecmode + [(V2DF "V2DI") (V4SF "V4SI") (V4DF "V4DI") (V8SF "V8SI")]) +(define_mode_attr avxmodesuffixf2c + [(V4SF "s") (V2DF "d") (V8SF "s") (V4DF "d")]) +(define_mode_attr avxmodesuffixp + [(V2DF "pd") (V4SI "si") (V4SF "ps") (V8SF "ps") (V8SI "si") + (V4DF "pd")]) +(define_mode_attr avxmodesuffixs + [(V16QI "b") (V8HI "w") (V4SI "d")]) +(define_mode_attr avxmodesuffix + [(V16QI "") (V32QI "256") (V4SI "") (V4SF "") (V2DF "") + (V8SI "256") (V8SF "256") (V4DF "256")]) + +;; Mapping of immediate bits for blend instructions +(define_mode_attr blendbits + [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")]) + +;; Mapping of immediate bits for vpermil instructions +(define_mode_attr vpermilbits + [(V8SF "255") (V4SF "255") (V4DF "15") (V2DF "3")]) + +;; Mapping of immediate bits for pinsr instructions +(define_mode_attr pinsrbits [(V16QI "32768") (V8HI "128") (V4SI "8")]) ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics. @@ -61,12 +142,53 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_expand "mov" + [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "") + (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))] + "TARGET_AVX" +{ + ix86_expand_vector_move (mode, operands); + DONE; +}) + +(define_insn "*avx_mov_internal" + [(set (match_operand:AVXMODE 0 "nonimmediate_operand" "=x,x ,m") + (match_operand:AVXMODE 1 "nonimmediate_or_sse_const_operand" "C ,xm,x"))] + "TARGET_AVX + && (register_operand (operands[0], mode) + || register_operand (operands[1], mode))" +{ + switch (which_alternative) + { + case 0: + return standard_sse_constant_opcode (insn, operands[1]); + case 1: + case 2: + switch (get_attr_mode (insn)) + { + case MODE_V8SF: + case MODE_V4SF: + return "vmovaps\t{%1, %0|%0, %1}"; + case MODE_V4DF: + case MODE_V2DF: + return "vmovapd\t{%1, %0|%0, %1}"; + default: + return "vmovdqa\t{%1, %0|%0, %1}"; + } + default: + gcc_unreachable (); + } +} + [(set_attr "type" "sselog1,ssemov,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + ;; All of these patterns are enabled for SSE1 as well as SSE2. ;; This is essential for maintaining stable calling conventions. (define_expand "mov" - [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "") - (match_operand:SSEMODEI 1 "nonimmediate_operand" ""))] + [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "") + (match_operand:SSEMODE 1 "nonimmediate_operand" ""))] "TARGET_SSE" { ix86_expand_vector_move (mode, operands); @@ -74,8 +196,8 @@ }) (define_insn "*mov_internal" - [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m") - (match_operand:SSEMODEI 1 "nonimmediate_or_sse_const_operand" "C ,xm,x"))] + [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "=x,x ,m") + (match_operand:SSEMODE 1 "nonimmediate_or_sse_const_operand" "C ,xm,x"))] "TARGET_SSE && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" @@ -86,23 +208,32 @@ return standard_sse_constant_opcode (insn, operands[1]); 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}"; + switch (get_attr_mode (insn)) + { + case MODE_V4SF: + return "movaps\t{%1, %0|%0, %1}"; + case MODE_V2DF: + return "movapd\t{%1, %0|%0, %1}"; + default: + return "movdqa\t{%1, %0|%0, %1}"; + } default: gcc_unreachable (); } } [(set_attr "type" "sselog1,ssemov,ssemov") (set (attr "mode") - (if_then_else - (ior (ior (ne (symbol_ref "optimize_size") (const_int 0)) - (eq (symbol_ref "TARGET_SSE2") (const_int 0))) - (and (eq_attr "alternative" "2") - (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") - (const_int 0)))) - (const_string "V4SF") + (cond [(ior (ior (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)) + (eq (symbol_ref "TARGET_SSE2") (const_int 0))) + (and (eq_attr "alternative" "2") + (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") + (const_int 0)))) + (const_string "V4SF") + (eq (const_string "mode") (const_string "V4SFmode")) + (const_string "V4SF") + (eq (const_string "mode") (const_string "V2DFmode")) + (const_string "V2DF") + ] (const_string "TI")))]) ;; Move a DI from a 32-bit register pair (e.g. %edx:%eax) to an xmm. @@ -140,36 +271,6 @@ gcc_unreachable (); }) -(define_expand "mov" - [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "") - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" ""))] - "TARGET_SSE" -{ - ix86_expand_vector_move (mode, operands); - DONE; -}) - -(define_insn "*movv4sf_internal" - [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m") - (match_operand:V4SF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))] - "TARGET_SSE - && (register_operand (operands[0], V4SFmode) - || register_operand (operands[1], V4SFmode))" -{ - switch (which_alternative) - { - case 0: - return standard_sse_constant_opcode (insn, operands[1]); - case 1: - case 2: - return "movaps\t{%1, %0|%0, %1}"; - default: - gcc_unreachable (); - } -} - [(set_attr "type" "sselog1,ssemov,ssemov") - (set_attr "mode" "V4SF")]) - (define_split [(set (match_operand:V4SF 0 "register_operand" "") (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))] @@ -184,38 +285,6 @@ operands[2] = CONST0_RTX (V4SFmode); }) -(define_insn "*movv2df_internal" - [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m") - (match_operand:V2DF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))] - "TARGET_SSE - && (register_operand (operands[0], V2DFmode) - || register_operand (operands[1], V2DFmode))" -{ - switch (which_alternative) - { - case 0: - return standard_sse_constant_opcode (insn, operands[1]); - 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: - gcc_unreachable (); - } -} - [(set_attr "type" "sselog1,ssemov,ssemov") - (set (attr "mode") - (if_then_else - (ior (ior (ne (symbol_ref "optimize_size") (const_int 0)) - (eq (symbol_ref "TARGET_SSE2") (const_int 0))) - (and (eq_attr "alternative" "2") - (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") - (const_int 0)))) - (const_string "V4SF") - (const_string "V2DF")))]) - (define_split [(set (match_operand:V2DF 0 "register_operand" "") (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))] @@ -227,6 +296,14 @@ }) (define_expand "push1" + [(match_operand:AVX256MODE 0 "register_operand" "")] + "TARGET_AVX" +{ + ix86_expand_push (mode, operands[0]); + DONE; +}) + +(define_expand "push1" [(match_operand:SSEMODE 0 "register_operand" "")] "TARGET_SSE" { @@ -235,6 +312,15 @@ }) (define_expand "movmisalign" + [(set (match_operand:AVX256MODE 0 "nonimmediate_operand" "") + (match_operand:AVX256MODE 1 "nonimmediate_operand" ""))] + "TARGET_AVX" +{ + ix86_expand_vector_move_misalign (mode, operands); + DONE; +}) + +(define_expand "movmisalign" [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "") (match_operand:SSEMODE 1 "nonimmediate_operand" ""))] "TARGET_SSE" @@ -243,6 +329,31 @@ DONE; }) +(define_insn "avx_movup" + [(set (match_operand:AVXMODEF2P 0 "nonimmediate_operand" "=x,m") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm,x")] + UNSPEC_MOVU))] + "AVX_VEC_FLOAT_MODE_P (mode) + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "vmovup\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "sse2_movq128" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_concat:V2DI + (vec_select:DI + (match_operand:V2DI 1 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (const_int 0)))] + "TARGET_SSE2" + "%vmovq\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + (define_insn "_movup" [(set (match_operand:SSEMODEF2P 0 "nonimmediate_operand" "=x,m") (unspec:SSEMODEF2P @@ -254,6 +365,17 @@ [(set_attr "type" "ssemov") (set_attr "mode" "")]) +(define_insn "avx_movdqu" + [(set (match_operand:AVXMODEQI 0 "nonimmediate_operand" "=x,m") + (unspec:AVXMODEQI + [(match_operand:AVXMODEQI 1 "nonimmediate_operand" "xm,x")] + UNSPEC_MOVU))] + "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "vmovdqu\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse2_movdqu" [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m") (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")] @@ -264,6 +386,17 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "avx_movnt" + [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x")] + UNSPEC_MOVNT))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vmovntp\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_movnt" [(set (match_operand:SSEMODEF2P 0 "memory_operand" "=m") (unspec:SSEMODEF2P @@ -274,6 +407,17 @@ [(set_attr "type" "ssemov") (set_attr "mode" "")]) +(define_insn "avx_movnt" + [(set (match_operand:AVXMODEDI 0 "memory_operand" "=m") + (unspec:AVXMODEDI + [(match_operand:AVXMODEDI 1 "register_operand" "x")] + UNSPEC_MOVNT))] + "TARGET_AVX" + "vmovntdq\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse2_movntv2di" [(set (match_operand:V2DI 0 "memory_operand" "=m") (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")] @@ -293,6 +437,17 @@ [(set_attr "type" "ssecvt") (set_attr "mode" "V2DF")]) +(define_insn "avx_lddqu" + [(set (match_operand:AVXMODEQI 0 "register_operand" "=x") + (unspec:AVXMODEQI + [(match_operand:AVXMODEQI 1 "memory_operand" "m")] + UNSPEC_LDDQU))] + "TARGET_AVX" + "vlddqu\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse3_lddqu" [(set (match_operand:V16QI 0 "register_operand" "=x") (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")] @@ -343,83 +498,100 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_expand "neg2" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (neg:SSEMODEF2P (match_operand:SSEMODEF2P 1 "register_operand" "")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_expand_fp_absneg_operator (NEG, mode, operands); DONE;") - -(define_expand "abs2" +(define_expand "2" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (abs:SSEMODEF2P (match_operand:SSEMODEF2P 1 "register_operand" "")))] + (absneg:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "")))] "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_expand_fp_absneg_operator (ABS, mode, operands); DONE;") + "ix86_expand_fp_absneg_operator (, mode, operands); DONE;") + +(define_expand "3" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "") + (plusminus:AVX256MODEF2P + (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "") + (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))] + "AVX256_VEC_FLOAT_MODE_P (mode)" + "ix86_fixup_binary_operands_no_copy (, mode, operands);") + +(define_insn "*avx_3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (plusminus:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode) + && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) -(define_expand "add3" +(define_expand "3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (plus:SSEMODEF2P + (plusminus:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_fixup_binary_operands_no_copy (PLUS, mode, operands);") + "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "*add3" +(define_insn "*3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (plus:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") + (plusminus:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (PLUS, mode, operands)" - "addp\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "")]) -(define_insn "_vmadd3" +(define_insn "*avx_vm3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P - (plus:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0") + (plusminus:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) (match_dup 1) (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (PLUS, V4SFmode, operands)" - "adds\t{%2, %0|%0, %2}" + "AVX128_VEC_FLOAT_MODE_P (mode)" + "vs\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") (set_attr "mode" "")]) -(define_expand "sub3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (minus:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_fixup_binary_operands_no_copy (MINUS, mode, operands);") - -(define_insn "*sub3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (minus:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "subp\t{%2, %0|%0, %2}" - [(set_attr "type" "sseadd") - (set_attr "mode" "")]) - -(define_insn "_vmsub3" +(define_insn "_vm3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P - (minus:SSEMODEF2P + (plusminus:SSEMODEF2P (match_operand:SSEMODEF2P 1 "register_operand" "0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) (match_dup 1) (const_int 1)))] "SSE_VEC_FLOAT_MODE_P (mode)" - "subs\t{%2, %0|%0, %2}" + "s\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "")]) (define_expand "mul3" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "") + (mult:AVX256MODEF2P + (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "") + (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))] + "AVX256_VEC_FLOAT_MODE_P (mode)" + "ix86_fixup_binary_operands_no_copy (MULT, mode, operands);") + +(define_insn "*avx_mul3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (mult:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode) + && ix86_binary_operator_ok (MULT, mode, operands)" + "vmulp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemul") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_expand "mul3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") (mult:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") @@ -438,6 +610,20 @@ [(set_attr "type" "ssemul") (set_attr "mode" "")]) +(define_insn "*avx_vmmul3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (mult:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) + (match_dup 1) + (const_int 1)))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vmuls\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemul") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_vmmul3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P @@ -446,21 +632,54 @@ (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) (match_dup 1) (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (MULT, mode, operands)" + "SSE_VEC_FLOAT_MODE_P (mode)" "muls\t{%2, %0|%0, %2}" [(set_attr "type" "ssemul") (set_attr "mode" "")]) +(define_expand "divv8sf3" + [(set (match_operand:V8SF 0 "register_operand" "") + (div:V8SF (match_operand:V8SF 1 "register_operand" "") + (match_operand:V8SF 2 "nonimmediate_operand" "")))] + "TARGET_AVX" +{ + ix86_fixup_binary_operands_no_copy (DIV, V8SFmode, operands); + + if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size + && flag_finite_math_only && !flag_trapping_math + && flag_unsafe_math_optimizations) + { + ix86_emit_swdivsf (operands[0], operands[1], + operands[2], V8SFmode); + DONE; + } +}) + +(define_expand "divv4df3" + [(set (match_operand:V4DF 0 "register_operand" "") + (div:V4DF (match_operand:V4DF 1 "register_operand" "") + (match_operand:V4DF 2 "nonimmediate_operand" "")))] + "TARGET_AVX" + "ix86_fixup_binary_operands_no_copy (DIV, V4DFmode, operands);") + +(define_insn "avx_div3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (div:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vdivp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssediv") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_expand "divv4sf3" [(set (match_operand:V4SF 0 "register_operand" "") (div:V4SF (match_operand:V4SF 1 "register_operand" "") (match_operand:V4SF 2 "nonimmediate_operand" "")))] "TARGET_SSE" { - ix86_fixup_binary_operands_no_copy (DIV, V4SFmode, operands); - - if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size + if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p () && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { @@ -475,7 +694,18 @@ (div:V2DF (match_operand:V2DF 1 "register_operand" "") (match_operand:V2DF 2 "nonimmediate_operand" "")))] "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (DIV, V2DFmode, operands);") + "") + +(define_insn "*avx_div3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (div:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX128_VEC_FLOAT_MODE_P (mode)" + "vdivp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssediv") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) (define_insn "_div3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") @@ -487,6 +717,20 @@ [(set_attr "type" "ssediv") (set_attr "mode" "")]) +(define_insn "*avx_vmdiv3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (div:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) + (match_dup 1) + (const_int 1)))] + "AVX128_VEC_FLOAT_MODE_P (mode)" + "vdivs\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssediv") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_vmdiv3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P @@ -500,15 +744,39 @@ [(set_attr "type" "ssediv") (set_attr "mode" "")]) +(define_insn "avx_rcpv8sf2" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (unspec:V8SF + [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))] + "TARGET_AVX" + "vrcpps\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_insn "sse_rcpv4sf2" [(set (match_operand:V4SF 0 "register_operand" "=x") (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))] "TARGET_SSE" - "rcpps\t{%1, %0|%0, %1}" + "%vrcpps\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) +(define_insn "*avx_vmrcpv4sf2" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] + UNSPEC_RCP) + (match_operand:V4SF 2 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vrcpss\t{%1, %2, %0|%0, %2, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_vmrcpv4sf2" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_merge:V4SF @@ -521,12 +789,35 @@ [(set_attr "type" "sse") (set_attr "mode" "SF")]) +(define_expand "sqrtv8sf2" + [(set (match_operand:V8SF 0 "register_operand" "") + (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "")))] + "TARGET_AVX" +{ + if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size + && flag_finite_math_only && !flag_trapping_math + && flag_unsafe_math_optimizations) + { + ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 0); + DONE; + } +}) + +(define_insn "avx_sqrtv8sf2" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (sqrt:V8SF (match_operand:V8SF 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vsqrtps\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_expand "sqrtv4sf2" [(set (match_operand:V4SF 0 "register_operand" "") (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))] "TARGET_SSE" { - if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size + if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p () && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { @@ -539,18 +830,42 @@ [(set (match_operand:V4SF 0 "register_operand" "=x") (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))] "TARGET_SSE" - "sqrtps\t{%1, %0|%0, %1}" + "%vsqrtps\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) +(define_insn "sqrtv4df2" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (sqrt:V4DF (match_operand:V4DF 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vsqrtpd\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + (define_insn "sqrtv2df2" [(set (match_operand:V2DF 0 "register_operand" "=x") (sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))] "TARGET_SSE2" - "sqrtpd\t{%1, %0|%0, %1}" + "%vsqrtpd\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V2DF")]) +(define_insn "*avx_vmsqrt2" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (sqrt:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")) + (match_operand:SSEMODEF2P 2 "register_operand" "x") + (const_int 1)))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vsqrts\t{%1, %2, %0|%0, %2, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_vmsqrt2" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P @@ -563,6 +878,26 @@ [(set_attr "type" "sse") (set_attr "mode" "")]) +(define_expand "rsqrtv8sf2" + [(set (match_operand:V8SF 0 "register_operand" "") + (unspec:V8SF + [(match_operand:V8SF 1 "nonimmediate_operand" "")] UNSPEC_RSQRT))] + "TARGET_AVX && TARGET_SSE_MATH" +{ + ix86_emit_swsqrtsf (operands[0], operands[1], V8SFmode, 1); + DONE; +}) + +(define_insn "avx_rsqrtv8sf2" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (unspec:V8SF + [(match_operand:V8SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))] + "TARGET_AVX" + "vrsqrtps\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_expand "rsqrtv4sf2" [(set (match_operand:V4SF 0 "register_operand" "") (unspec:V4SF @@ -578,10 +913,24 @@ (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))] "TARGET_SSE" - "rsqrtps\t{%1, %0|%0, %1}" + "%vrsqrtps\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) +(define_insn "*avx_vmrsqrtv4sf2" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] + UNSPEC_RSQRT) + (match_operand:V4SF 2 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vrsqrtss\t{%1, %2, %0|%0, %2, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_vmrsqrtv4sf2" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_merge:V4SF @@ -598,97 +947,100 @@ ;; isn't really correct, as those rtl operators aren't defined when ;; applied to NaNs. Hopefully the optimizers won't get too smart on us. -(define_expand "smin3" +(define_expand "3" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "") + (smaxmin:AVX256MODEF2P + (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "") + (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))] + "AVX256_VEC_FLOAT_MODE_P (mode)" +{ + if (!flag_finite_math_only) + operands[1] = force_reg (mode, operands[1]); + ix86_fixup_binary_operands_no_copy (, mode, operands); +}) + +(define_expand "3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (smin:SSEMODEF2P + (smaxmin:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] "SSE_VEC_FLOAT_MODE_P (mode)" { if (!flag_finite_math_only) operands[1] = force_reg (mode, operands[1]); - ix86_fixup_binary_operands_no_copy (SMIN, mode, operands); + ix86_fixup_binary_operands_no_copy (, mode, operands); }) -(define_insn "*smin3_finite" +(define_insn "*avx_3_finite" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (smaxmin:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode) && flag_finite_math_only + && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "*3_finite" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (smin:SSEMODEF2P + (smaxmin:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] "SSE_VEC_FLOAT_MODE_P (mode) && flag_finite_math_only - && ix86_binary_operator_ok (SMIN, mode, operands)" - "minp\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "")]) -(define_insn "*smin3" +(define_insn "*avx_3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (smaxmin:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "*3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (smin:SSEMODEF2P + (smaxmin:SSEMODEF2P (match_operand:SSEMODEF2P 1 "register_operand" "0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] "SSE_VEC_FLOAT_MODE_P (mode)" - "minp\t{%2, %0|%0, %2}" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "")]) -(define_insn "_vmsmin3" +(define_insn "*avx_vm3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P - (smin:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0") + (smaxmin:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) (match_dup 1) (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "mins\t{%2, %0|%0, %2}" + "AVX128_VEC_FLOAT_MODE_P (mode)" + "vs\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sse") + (set_attr "prefix" "vex") (set_attr "mode" "")]) -(define_expand "smax3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (smax:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] +(define_insn "_vm3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (smaxmin:SSEMODEF2P + (match_operand:SSEMODEF2P 1 "register_operand" "0") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) + (match_dup 1) + (const_int 1)))] "SSE_VEC_FLOAT_MODE_P (mode)" -{ - if (!flag_finite_math_only) - operands[1] = force_reg (mode, operands[1]); - ix86_fixup_binary_operands_no_copy (SMAX, mode, operands); -}) - -(define_insn "*smax3_finite" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (smax:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] - "SSE_VEC_FLOAT_MODE_P (mode) && flag_finite_math_only - && ix86_binary_operator_ok (SMAX, mode, operands)" - "maxp\t{%2, %0|%0, %2}" - [(set_attr "type" "sseadd") - (set_attr "mode" "")]) - -(define_insn "*smax3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (smax:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "maxp\t{%2, %0|%0, %2}" - [(set_attr "type" "sseadd") - (set_attr "mode" "")]) - -(define_insn "_vmsmax3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (vec_merge:SSEMODEF2P - (smax:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) - (match_dup 1) - (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "maxs\t{%2, %0|%0, %2}" - [(set_attr "type" "sseadd") - (set_attr "mode" "")]) + "s\t{%2, %0|%0, %2}" + [(set_attr "type" "sse") + (set_attr "mode" "")]) ;; These versions of the min/max patterns implement exactly the operations ;; min = (op1 < op2 ? op1 : op2) @@ -696,6 +1048,30 @@ ;; Their operands are not commutative, and thus they may be used in the ;; presence of -0.0 and NaN. +(define_insn "*avx_ieee_smin3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")] + UNSPEC_IEEE_MIN))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vminp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "*avx_ieee_smax3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")] + UNSPEC_IEEE_MAX))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vmaxp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "*ieee_smin3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P @@ -718,6 +1094,48 @@ [(set_attr "type" "sseadd") (set_attr "mode" "")]) +(define_insn "avx_addsubv8sf3" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_merge:V8SF + (plus:V8SF + (match_operand:V8SF 1 "register_operand" "x") + (match_operand:V8SF 2 "nonimmediate_operand" "xm")) + (minus:V8SF (match_dup 1) (match_dup 2)) + (const_int 85)))] + "TARGET_AVX" + "vaddsubps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "avx_addsubv4df3" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_merge:V4DF + (plus:V4DF + (match_operand:V4DF 1 "register_operand" "x") + (match_operand:V4DF 2 "nonimmediate_operand" "xm")) + (minus:V4DF (match_dup 1) (match_dup 2)) + (const_int 5)))] + "TARGET_AVX" + "vaddsubpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + +(define_insn "*avx_addsubv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (plus:V4SF + (match_operand:V4SF 1 "register_operand" "x") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")) + (minus:V4SF (match_dup 1) (match_dup 2)) + (const_int 5)))] + "TARGET_AVX" + "vaddsubps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_insn "sse3_addsubv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_merge:V4SF @@ -732,6 +1150,20 @@ (set_attr "prefix_rep" "1") (set_attr "mode" "V4SF")]) +(define_insn "*avx_addsubv2df3" + [(set (match_operand:V2DF 0 "register_operand" "=x") + (vec_merge:V2DF + (plus:V2DF + (match_operand:V2DF 1 "register_operand" "x") + (match_operand:V2DF 2 "nonimmediate_operand" "xm")) + (minus:V2DF (match_dup 1) (match_dup 2)) + (const_int 1)))] + "TARGET_AVX" + "vaddsubpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF")]) + (define_insn "sse3_addsubv2df3" [(set (match_operand:V2DF 0 "register_operand" "=x") (vec_merge:V2DF @@ -745,93 +1177,164 @@ [(set_attr "type" "sseadd") (set_attr "mode" "V2DF")]) -(define_insn "sse3_haddv4sf3" +(define_insn "avx_hv4df3" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_concat:V4DF + (vec_concat:V2DF + (plusminus:DF + (vec_select:DF + (match_operand:V4DF 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:DF (match_dup 1) (parallel [(const_int 1)]))) + (plusminus:DF + (vec_select:DF (match_dup 1) (parallel [(const_int 2)])) + (vec_select:DF (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2DF + (plusminus:DF + (vec_select:DF + (match_operand:V4DF 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:DF (match_dup 2) (parallel [(const_int 1)]))) + (plusminus:DF + (vec_select:DF (match_dup 2) (parallel [(const_int 2)])) + (vec_select:DF (match_dup 2) (parallel [(const_int 3)]))))))] + "TARGET_AVX" + "vhpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + +(define_insn "avx_hv8sf3" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_concat:V8SF + (vec_concat:V4SF + (vec_concat:V2SF + (plusminus:SF + (vec_select:SF + (match_operand:V8SF 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) + (plusminus:SF + (vec_select:SF (match_dup 1) (parallel [(const_int 2)])) + (vec_select:SF (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2SF + (plusminus:SF + (vec_select:SF + (match_operand:V8SF 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:SF (match_dup 2) (parallel [(const_int 1)]))) + (plusminus:SF + (vec_select:SF (match_dup 2) (parallel [(const_int 2)])) + (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))) + (vec_concat:V4SF + (vec_concat:V2SF + (plusminus:SF + (vec_select:SF (match_dup 1) (parallel [(const_int 4)])) + (vec_select:SF (match_dup 1) (parallel [(const_int 5)]))) + (plusminus:SF + (vec_select:SF (match_dup 1) (parallel [(const_int 6)])) + (vec_select:SF (match_dup 1) (parallel [(const_int 7)])))) + (vec_concat:V2SF + (plusminus:SF + (vec_select:SF (match_dup 2) (parallel [(const_int 4)])) + (vec_select:SF (match_dup 2) (parallel [(const_int 5)]))) + (plusminus:SF + (vec_select:SF (match_dup 2) (parallel [(const_int 6)])) + (vec_select:SF (match_dup 2) (parallel [(const_int 7)])))))))] + "TARGET_AVX" + "vhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "*avx_hv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_concat:V4SF (vec_concat:V2SF - (plus:SF + (plusminus:SF (vec_select:SF - (match_operand:V4SF 1 "register_operand" "0") + (match_operand:V4SF 1 "register_operand" "x") (parallel [(const_int 0)])) (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) - (plus:SF + (plusminus:SF (vec_select:SF (match_dup 1) (parallel [(const_int 2)])) (vec_select:SF (match_dup 1) (parallel [(const_int 3)])))) (vec_concat:V2SF - (plus:SF + (plusminus:SF (vec_select:SF (match_operand:V4SF 2 "nonimmediate_operand" "xm") (parallel [(const_int 0)])) (vec_select:SF (match_dup 2) (parallel [(const_int 1)]))) - (plus:SF + (plusminus:SF (vec_select:SF (match_dup 2) (parallel [(const_int 2)])) (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))] - "TARGET_SSE3" - "haddps\t{%2, %0|%0, %2}" + "TARGET_AVX" + "vhps\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseadd") - (set_attr "prefix_rep" "1") + (set_attr "prefix" "vex") (set_attr "mode" "V4SF")]) -(define_insn "sse3_haddv2df3" - [(set (match_operand:V2DF 0 "register_operand" "=x") - (vec_concat:V2DF - (plus:DF - (vec_select:DF - (match_operand:V2DF 1 "register_operand" "0") - (parallel [(const_int 0)])) - (vec_select:DF (match_dup 1) (parallel [(const_int 1)]))) - (plus:DF - (vec_select:DF - (match_operand:V2DF 2 "nonimmediate_operand" "xm") - (parallel [(const_int 0)])) - (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))] - "TARGET_SSE3" - "haddpd\t{%2, %0|%0, %2}" - [(set_attr "type" "sseadd") - (set_attr "mode" "V2DF")]) - -(define_insn "sse3_hsubv4sf3" +(define_insn "sse3_hv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_concat:V4SF (vec_concat:V2SF - (minus:SF + (plusminus:SF (vec_select:SF (match_operand:V4SF 1 "register_operand" "0") (parallel [(const_int 0)])) (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) - (minus:SF + (plusminus:SF (vec_select:SF (match_dup 1) (parallel [(const_int 2)])) (vec_select:SF (match_dup 1) (parallel [(const_int 3)])))) (vec_concat:V2SF - (minus:SF + (plusminus:SF (vec_select:SF (match_operand:V4SF 2 "nonimmediate_operand" "xm") (parallel [(const_int 0)])) (vec_select:SF (match_dup 2) (parallel [(const_int 1)]))) - (minus:SF + (plusminus:SF (vec_select:SF (match_dup 2) (parallel [(const_int 2)])) (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))] "TARGET_SSE3" - "hsubps\t{%2, %0|%0, %2}" + "hps\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "prefix_rep" "1") (set_attr "mode" "V4SF")]) -(define_insn "sse3_hsubv2df3" +(define_insn "*avx_hv2df3" + [(set (match_operand:V2DF 0 "register_operand" "=x") + (vec_concat:V2DF + (plusminus:DF + (vec_select:DF + (match_operand:V2DF 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:DF (match_dup 1) (parallel [(const_int 1)]))) + (plusminus:DF + (vec_select:DF + (match_operand:V2DF 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))] + "TARGET_AVX" + "vhpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF")]) + +(define_insn "sse3_hv2df3" [(set (match_operand:V2DF 0 "register_operand" "=x") (vec_concat:V2DF - (minus:DF + (plusminus:DF (vec_select:DF (match_operand:V2DF 1 "register_operand" "0") (parallel [(const_int 0)])) (vec_select:DF (match_dup 1) (parallel [(const_int 1)]))) - (minus:DF + (plusminus:DF (vec_select:DF (match_operand:V2DF 2 "nonimmediate_operand" "xm") (parallel [(const_int 0)])) (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))] "TARGET_SSE3" - "hsubpd\t{%2, %0|%0, %2}" + "hpd\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "V2DF")]) @@ -884,6 +1387,48 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_insn "avx_cmpp3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_31_operand" "n")] + UNSPEC_PCMP))] + "TARGET_AVX" + "vcmpp\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_cmps3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "") + (vec_merge:SSEMODEF2P + (unspec:SSEMODEF2P + [(match_operand:SSEMODEF2P 1 "register_operand" "x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_31_operand" "n")] + UNSPEC_PCMP) + (match_dup 1) + (const_int 1)))] + "TARGET_AVX" + "vcmps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +;; We don't promote 128bit vector compare intrinsics. But vectorizer +;; may generate 256bit vector compare instructions. +(define_insn "*avx_maskcmp3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (match_operator:AVXMODEF2P 3 "avx_comparison_float_operator" + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")]))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vcmp%D3p\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_maskcmp3" [(set (match_operand:SSEMODEF4 0 "register_operand" "=x") (match_operator:SSEMODEF4 3 "sse_comparison_operator" @@ -918,8 +1463,9 @@ (match_operand: 1 "nonimmediate_operand" "xm") (parallel [(const_int 0)]))))] "SSE_FLOAT_MODE_P (mode)" - "comis\t{%1, %0|%0, %1}" + "%vcomis\t{%1, %0|%0, %1}" [(set_attr "type" "ssecomi") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "")]) (define_insn "_ucomi" @@ -932,8 +1478,9 @@ (match_operand: 1 "nonimmediate_operand" "xm") (parallel [(const_int 0)]))))] "SSE_FLOAT_MODE_P (mode)" - "ucomis\t{%1, %0|%0, %1}" + "%vucomis\t{%1, %0|%0, %1}" [(set_attr "type" "ssecomi") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "")]) (define_expand "vcond" @@ -958,26 +1505,19 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_expand "and3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (and:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_fixup_binary_operands_no_copy (AND, mode, operands);") - -(define_insn "*and3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (and:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] - "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (AND, V4SFmode, operands)" - "andp\t{%2, %0|%0, %2}" +(define_insn "avx_andnot3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (and:AVXMODEF2P + (not:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "register_operand" "x")) + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode)" + "vandnp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") - (set_attr "mode" "")]) + (set_attr "prefix" "vex") + (set_attr "mode" "")]) -(define_insn "_nand3" +(define_insn "_andnot3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (and:SSEMODEF2P (not:SSEMODEF2P @@ -988,41 +1528,42 @@ [(set_attr "type" "sselog") (set_attr "mode" "")]) -(define_expand "ior3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (ior:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_fixup_binary_operands_no_copy (IOR, mode, operands);") - -(define_insn "*ior3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (ior:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] - "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (IOR, mode, operands)" - "orp\t{%2, %0|%0, %2}" +(define_expand "3" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "") + (plogic:AVX256MODEF2P + (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "") + (match_operand:AVX256MODEF2P 2 "nonimmediate_operand" "")))] + "AVX256_VEC_FLOAT_MODE_P (mode)" + "ix86_fixup_binary_operands_no_copy (, mode, operands);") + +(define_insn "*avx_3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (plogic:AVXMODEF2P + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm")))] + "AVX_VEC_FLOAT_MODE_P (mode) + && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") - (set_attr "mode" "")]) + (set_attr "prefix" "vex") + (set_attr "mode" "")]) -(define_expand "xor3" +(define_expand "3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (xor:SSEMODEF2P + (plogic:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "")))] "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_fixup_binary_operands_no_copy (XOR, mode, operands);") + "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "*xor3" +(define_insn "*3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (xor:SSEMODEF2P + (plogic:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")))] "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (XOR, mode, operands)" - "xorp\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "")]) @@ -1031,17 +1572,19 @@ ;; allocation lossage. These patterns do not allow memory operands ;; because the native instructions read the full 128-bits. -(define_insn "*and3" +(define_insn "*avx_andnot3" [(set (match_operand:MODEF 0 "register_operand" "=x") (and:MODEF - (match_operand:MODEF 1 "register_operand" "0") - (match_operand:MODEF 2 "register_operand" "x")))] - "SSE_FLOAT_MODE_P (mode)" - "andp\t{%2, %0|%0, %2}" + (not:MODEF + (match_operand:MODEF 1 "register_operand" "x")) + (match_operand:MODEF 2 "register_operand" "x")))] + "AVX_FLOAT_MODE_P (mode)" + "vandnp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") + (set_attr "prefix" "vex") (set_attr "mode" "")]) -(define_insn "*nand3" +(define_insn "*andnot3" [(set (match_operand:MODEF 0 "register_operand" "=x") (and:MODEF (not:MODEF @@ -1052,23 +1595,24 @@ [(set_attr "type" "sselog") (set_attr "mode" "")]) -(define_insn "*ior3" +(define_insn "*avx_3" [(set (match_operand:MODEF 0 "register_operand" "=x") - (ior:MODEF - (match_operand:MODEF 1 "register_operand" "0") + (plogic:MODEF + (match_operand:MODEF 1 "register_operand" "x") (match_operand:MODEF 2 "register_operand" "x")))] - "SSE_FLOAT_MODE_P (mode)" - "orp\t{%2, %0|%0, %2}" + "AVX_FLOAT_MODE_P (mode)" + "vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") + (set_attr "prefix" "vex") (set_attr "mode" "")]) -(define_insn "*xor3" +(define_insn "*3" [(set (match_operand:MODEF 0 "register_operand" "=x") - (xor:MODEF + (plogic:MODEF (match_operand:MODEF 1 "register_operand" "0") (match_operand:MODEF 2 "register_operand" "x")))] "SSE_FLOAT_MODE_P (mode)" - "xorp\t{%2, %0|%0, %2}" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "")]) @@ -1098,7 +1642,7 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)" "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1112,8 +1656,8 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -1139,7 +1683,7 @@ (match_dup 1) (const_int 1)))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1154,7 +1698,7 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)" "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1168,8 +1712,8 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -1195,7 +1739,7 @@ (match_dup 1) (const_int 1)))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1212,7 +1756,7 @@ (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm") (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)" "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1226,8 +1770,8 @@ (match_operand:SSEMODEF4 1 "nonimmediate_operand" "") (match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -1253,7 +1797,7 @@ (match_dup 1) (const_int 1)))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1270,7 +1814,7 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)" "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1285,8 +1829,8 @@ (match_operand:SSEMODEF4 2 "nonimmediate_operand" "")) (match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false) + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -1313,7 +1857,7 @@ (match_dup 1) (const_int 1)))] "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" + && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)" "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1351,7 +1895,7 @@ (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1381,11 +1925,11 @@ (unspec:SSEMODEF2P [(minus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "%0,0,x,xm") + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1421,7 +1965,7 @@ (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1454,11 +1998,11 @@ [(minus:SSEMODEF2P (mult:SSEMODEF2P (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")) + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm")) (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1501,7 +2045,7 @@ (match_dup 0) (const_int 0))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1535,13 +2079,13 @@ [(vec_merge:SSEMODEF2P (minus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0") + (match_operand:SSEMODEF2P 1 "register_operand" "0,0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) (match_dup 1) (const_int 1))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1577,12 +2121,12 @@ (minus:SSEMODEF2P (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x") (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0") + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))) (match_dup 1) (const_int 1))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)" "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1618,13 +2162,13 @@ (minus:SSEMODEF2P (mult:SSEMODEF2P (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")) + (match_operand:SSEMODEF2P 1 "register_operand" "0,0")) (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) (match_dup 1) (const_int 1))] UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1670,6 +2214,19 @@ (set_attr "unit" "mmx") (set_attr "mode" "SF")]) +(define_insn "*avx_cvtsi2ss" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (vec_duplicate:V4SF + (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))) + (match_operand:V4SF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_cvtsi2ss" [(set (match_operand:V4SF 0 "register_operand" "=x,x") (vec_merge:V4SF @@ -1684,6 +2241,19 @@ (set_attr "amdfam10_decode" "vector,double") (set_attr "mode" "SF")]) +(define_insn "*avx_cvtsi2ssq" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (vec_duplicate:V4SF + (float:SF (match_operand:DI 2 "nonimmediate_operand" "rm"))) + (match_operand:V4SF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX && TARGET_64BIT" + "vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_cvtsi2ssq" [(set (match_operand:V4SF 0 "register_operand" "=x,x") (vec_merge:V4SF @@ -1706,10 +2276,11 @@ (parallel [(const_int 0)]))] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE" - "cvtss2si\t{%1, %0|%0, %1}" + "%vcvtss2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_insn "sse_cvtss2si_2" @@ -1717,11 +2288,12 @@ (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE" - "cvtss2si\t{%1, %0|%0, %1}" + "%vcvtss2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_insn "sse_cvtss2siq" @@ -1732,10 +2304,11 @@ (parallel [(const_int 0)]))] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE && TARGET_64BIT" - "cvtss2siq\t{%1, %0|%0, %1}" + "%vcvtss2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI")]) (define_insn "sse_cvtss2siq_2" @@ -1743,11 +2316,12 @@ (unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE && TARGET_64BIT" - "cvtss2siq\t{%1, %0|%0, %1}" + "%vcvtss2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI")]) (define_insn "sse_cvttss2si" @@ -1757,11 +2331,12 @@ (match_operand:V4SF 1 "nonimmediate_operand" "x,m") (parallel [(const_int 0)]))))] "TARGET_SSE" - "cvttss2si\t{%1, %0|%0, %1}" + "%vcvttss2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_insn "sse_cvttss2siq" @@ -1771,13 +2346,24 @@ (match_operand:V4SF 1 "nonimmediate_operand" "x,m") (parallel [(const_int 0)]))))] "TARGET_SSE && TARGET_64BIT" - "cvttss2siq\t{%1, %0|%0, %1}" + "%vcvttss2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI")]) +(define_insn "avx_cvtdq2ps" + [(set (match_operand:AVXMODEDCVTDQ2PS 0 "register_operand" "=x") + (float:AVXMODEDCVTDQ2PS + (match_operand: 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvtdq2ps\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse2_cvtdq2ps" [(set (match_operand:V4SF 0 "register_operand" "=x") (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))] @@ -1786,6 +2372,17 @@ [(set_attr "type" "ssecvt") (set_attr "mode" "V4SF")]) +(define_insn "avx_cvtps2dq" + [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x") + (unspec:AVXMODEDCVTPS2DQ + [(match_operand: 1 "nonimmediate_operand" "xm")] + UNSPEC_FIX_NOTRUNC))] + "TARGET_AVX" + "vcvtps2dq\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse2_cvtps2dq" [(set (match_operand:V4SI 0 "register_operand" "=x") (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] @@ -1796,6 +2393,16 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "avx_cvttps2dq" + [(set (match_operand:AVXMODEDCVTPS2DQ 0 "register_operand" "=x") + (fix:AVXMODEDCVTPS2DQ + (match_operand: 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvttps2dq\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse2_cvttps2dq" [(set (match_operand:V4SI 0 "register_operand" "=x") (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))] @@ -1841,6 +2448,19 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_cvtsi2sd" + [(set (match_operand:V2DF 0 "register_operand" "=x") + (vec_merge:V2DF + (vec_duplicate:V2DF + (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))) + (match_operand:V2DF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vcvtsi2sd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "vex") + (set_attr "mode" "DF")]) + (define_insn "sse2_cvtsi2sd" [(set (match_operand:V2DF 0 "register_operand" "=x,x") (vec_merge:V2DF @@ -1855,6 +2475,19 @@ (set_attr "athlon_decode" "double,direct") (set_attr "amdfam10_decode" "vector,double")]) +(define_insn "*avx_cvtsi2sdq" + [(set (match_operand:V2DF 0 "register_operand" "=x") + (vec_merge:V2DF + (vec_duplicate:V2DF + (float:DF (match_operand:DI 2 "nonimmediate_operand" "rm"))) + (match_operand:V2DF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX && TARGET_64BIT" + "vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseicvt") + (set_attr "prefix" "vex") + (set_attr "mode" "DF")]) + (define_insn "sse2_cvtsi2sdq" [(set (match_operand:V2DF 0 "register_operand" "=x,x") (vec_merge:V2DF @@ -1877,10 +2510,11 @@ (parallel [(const_int 0)]))] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE2" - "cvtsd2si\t{%1, %0|%0, %1}" + "%vcvtsd2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_insn "sse2_cvtsd2si_2" @@ -1888,11 +2522,12 @@ (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE2" - "cvtsd2si\t{%1, %0|%0, %1}" + "%vcvtsd2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_insn "sse2_cvtsd2siq" @@ -1903,10 +2538,11 @@ (parallel [(const_int 0)]))] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE2 && TARGET_64BIT" - "cvtsd2siq\t{%1, %0|%0, %1}" + "%vcvtsd2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI")]) (define_insn "sse2_cvtsd2siq_2" @@ -1914,11 +2550,12 @@ (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE2 && TARGET_64BIT" - "cvtsd2siq\t{%1, %0|%0, %1}" + "%vcvtsd2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI")]) (define_insn "sse2_cvttsd2si" @@ -1928,9 +2565,10 @@ (match_operand:V2DF 1 "nonimmediate_operand" "x,m") (parallel [(const_int 0)]))))] "TARGET_SSE2" - "cvttsd2si\t{%1, %0|%0, %1}" + "%vcvttsd2si\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double")]) @@ -1942,13 +2580,23 @@ (match_operand:V2DF 1 "nonimmediate_operand" "x,m") (parallel [(const_int 0)]))))] "TARGET_SSE2 && TARGET_64BIT" - "cvttsd2siq\t{%1, %0|%0, %1}" + "%vcvttsd2siq\t{%1, %0|%0, %1}" [(set_attr "type" "sseicvt") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DI") (set_attr "athlon_decode" "double,vector") (set_attr "amdfam10_decode" "double,double")]) +(define_insn "avx_cvtdq2pd256" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (float:V4DF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvtdq2pd\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + (define_insn "sse2_cvtdq2pd" [(set (match_operand:V2DF 0 "register_operand" "=x") (float:V2DF @@ -1956,10 +2604,21 @@ (match_operand:V4SI 1 "nonimmediate_operand" "xm") (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE2" - "cvtdq2pd\t{%1, %0|%0, %1}" + "%vcvtdq2pd\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V2DF")]) +(define_insn "avx_cvtpd2dq256" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")] + UNSPEC_FIX_NOTRUNC))] + "TARGET_AVX" + "vcvtpd2dq{y}\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + (define_expand "sse2_cvtpd2dq" [(set (match_operand:V4SI 0 "register_operand" "") (vec_concat:V4SI @@ -1976,12 +2635,23 @@ UNSPEC_FIX_NOTRUNC) (match_operand:V2SI 2 "const0_operand" "")))] "TARGET_SSE2" - "cvtpd2dq\t{%1, %0|%0, %1}" + "* return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\" + : \"cvtpd2dq\t{%1, %0|%0, %1}\";" [(set_attr "type" "ssecvt") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI") (set_attr "amdfam10_decode" "double")]) +(define_insn "avx_cvttpd2dq256" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (fix:V4SI (match_operand:V4DF 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvttpd2dq{y}\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + (define_expand "sse2_cvttpd2dq" [(set (match_operand:V4SI 0 "register_operand" "") (vec_concat:V4SI @@ -1996,12 +2666,28 @@ (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")) (match_operand:V2SI 2 "const0_operand" "")))] "TARGET_SSE2" - "cvttpd2dq\t{%1, %0|%0, %1}" + "* return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\" + : \"cvttpd2dq\t{%1, %0|%0, %1}\";" [(set_attr "type" "ssecvt") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI") (set_attr "amdfam10_decode" "double")]) +(define_insn "*avx_cvtsd2ss" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (vec_duplicate:V4SF + (float_truncate:V2SF + (match_operand:V2DF 2 "nonimmediate_operand" "xm"))) + (match_operand:V4SF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse2_cvtsd2ss" [(set (match_operand:V4SF 0 "register_operand" "=x,x") (vec_merge:V4SF @@ -2017,6 +2703,21 @@ (set_attr "amdfam10_decode" "vector,double") (set_attr "mode" "SF")]) +(define_insn "*avx_cvtss2sd" + [(set (match_operand:V2DF 0 "register_operand" "=x") + (vec_merge:V2DF + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) (const_int 1)]))) + (match_operand:V2DF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vcvtss2sd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "DF")]) + (define_insn "sse2_cvtss2sd" [(set (match_operand:V2DF 0 "register_operand" "=x,x") (vec_merge:V2DF @@ -2032,6 +2733,16 @@ (set_attr "amdfam10_decode" "vector,double") (set_attr "mode" "DF")]) +(define_insn "avx_cvtpd2ps256" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (float_truncate:V4SF + (match_operand:V4DF 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvtpd2ps{y}\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_expand "sse2_cvtpd2ps" [(set (match_operand:V4SF 0 "register_operand" "") (vec_concat:V4SF @@ -2048,12 +2759,24 @@ (match_operand:V2DF 1 "nonimmediate_operand" "xm")) (match_operand:V2SF 2 "const0_operand" "")))] "TARGET_SSE2" - "cvtpd2ps\t{%1, %0|%0, %1}" + "* return TARGET_AVX ? \"vcvtpd2ps{x}\t{%1, %0|%0, %1}\" + : \"cvtpd2ps\t{%1, %0|%0, %1}\";" [(set_attr "type" "ssecvt") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF") (set_attr "amdfam10_decode" "double")]) +(define_insn "avx_cvtps2pd256" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (float_extend:V4DF + (match_operand:V4SF 1 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vcvtps2pd\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + (define_insn "sse2_cvtps2pd" [(set (match_operand:V2DF 0 "register_operand" "=x") (float_extend:V2DF @@ -2061,8 +2784,9 @@ (match_operand:V4SF 1 "nonimmediate_operand" "xm") (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE2" - "cvtps2pd\t{%1, %0|%0, %1}" + "%vcvtps2pd\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V2DF") (set_attr "amdfam10_decode" "direct")]) @@ -2229,6 +2953,38 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_expand "sse_movhlps_exp" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "nonimmediate_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")) + (parallel [(const_int 6) + (const_int 7) + (const_int 2) + (const_int 3)])))] + "TARGET_SSE" + "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);") + +(define_insn "*avx_movhlps" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0") + (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x")) + (parallel [(const_int 6) + (const_int 7) + (const_int 2) + (const_int 3)])))] + "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vmovhlps\t{%2, %1, %0|%0, %1, %2} + vmovlps\t{%H2, %1, %0|%0, %1, %H2} + vmovhps\t{%2, %0|%0, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF,V2SF,V2SF")]) + (define_insn "sse_movhlps" [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m") (vec_select:V4SF @@ -2247,6 +3003,38 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V4SF,V2SF,V2SF")]) +(define_expand "sse_movlhps_exp" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "nonimmediate_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) + (const_int 1) + (const_int 4) + (const_int 5)])))] + "TARGET_SSE" + "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);") + +(define_insn "*avx_movlhps" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0") + (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x")) + (parallel [(const_int 0) + (const_int 1) + (const_int 4) + (const_int 5)])))] + "TARGET_AVX && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)" + "@ + vmovlhps\t{%2, %1, %0|%0, %1, %2} + vmovhps\t{%2, %1, %0|%0, %1, %2} + vmovlps\t{%2, %H0|%H0, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF,V2SF,V2SF")]) + (define_insn "sse_movlhps" [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o") (vec_select:V4SF @@ -2265,34 +3053,110 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V4SF,V2SF,V2SF")]) -(define_insn "sse_unpckhps" +(define_insn "avx_unpckhps256" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_select:V8SF + (vec_concat:V16SF + (match_operand:V8SF 1 "register_operand" "x") + (match_operand:V8SF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7) + (const_int 10) (const_int 14) + (const_int 11) (const_int 15)])))] + "TARGET_AVX" + "vunpckhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "*avx_unpckhps" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_select:V4SF (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "0") + (match_operand:V4SF 1 "register_operand" "x") (match_operand:V4SF 2 "nonimmediate_operand" "xm")) (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))] - "TARGET_SSE" - "unpckhps\t{%2, %0|%0, %2}" + "TARGET_AVX" + "vunpckhps\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") + (set_attr "prefix" "vex") (set_attr "mode" "V4SF")]) -(define_insn "sse_unpcklps" +(define_insn "sse_unpckhps" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_select:V4SF (vec_concat:V8SF (match_operand:V4SF 1 "register_operand" "0") (match_operand:V4SF 2 "nonimmediate_operand" "xm")) - (parallel [(const_int 0) (const_int 4) - (const_int 1) (const_int 5)])))] + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] "TARGET_SSE" - "unpcklps\t{%2, %0|%0, %2}" + "unpckhps\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog") + (set_attr "mode" "V4SF")]) + +(define_insn "avx_unpcklps256" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_select:V8SF + (vec_concat:V16SF + (match_operand:V8SF 1 "register_operand" "x") + (match_operand:V8SF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5) + (const_int 8) (const_int 12) + (const_int 9) (const_int 13)])))] + "TARGET_AVX" + "vunpcklps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "*avx_unpcklps" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "x") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "TARGET_AVX" + "vunpcklps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + +(define_insn "sse_unpcklps" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "0") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "TARGET_SSE" + "unpcklps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "V4SF")]) ;; These are modeled with the same vec_concat as the others so that we ;; capture users of shufps that can use the new instructions +(define_insn "avx_movshdup256" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_select:V8SF + (vec_concat:V16SF + (match_operand:V8SF 1 "nonimmediate_operand" "xm") + (match_dup 1)) + (parallel [(const_int 1) (const_int 1) + (const_int 3) (const_int 3) + (const_int 5) (const_int 5) + (const_int 7) (const_int 7)])))] + "TARGET_AVX" + "vmovshdup\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_insn "sse3_movshdup" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_select:V4SF @@ -2304,11 +3168,28 @@ (const_int 7) (const_int 7)])))] "TARGET_SSE3" - "movshdup\t{%1, %0|%0, %1}" + "%vmovshdup\t{%1, %0|%0, %1}" [(set_attr "type" "sse") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) +(define_insn "avx_movsldup256" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_select:V8SF + (vec_concat:V16SF + (match_operand:V8SF 1 "nonimmediate_operand" "xm") + (match_dup 1)) + (parallel [(const_int 0) (const_int 0) + (const_int 2) (const_int 2) + (const_int 4) (const_int 4) + (const_int 6) (const_int 6)])))] + "TARGET_AVX" + "vmovsldup\t{%1, %0|%0, %1}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_insn "sse3_movsldup" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_select:V4SF @@ -2320,11 +3201,66 @@ (const_int 6) (const_int 6)])))] "TARGET_SSE3" - "movsldup\t{%1, %0|%0, %1}" + "%vmovsldup\t{%1, %0|%0, %1}" [(set_attr "type" "sse") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) +(define_expand "avx_shufps256" + [(match_operand:V8SF 0 "register_operand" "") + (match_operand:V8SF 1 "register_operand" "") + (match_operand:V8SF 2 "nonimmediate_operand" "") + (match_operand:SI 3 "const_int_operand" "")] + "TARGET_AVX" +{ + int mask = INTVAL (operands[3]); + emit_insn (gen_avx_shufps256_1 (operands[0], operands[1], operands[2], + GEN_INT ((mask >> 0) & 3), + GEN_INT ((mask >> 2) & 3), + GEN_INT (((mask >> 4) & 3) + 8), + GEN_INT (((mask >> 6) & 3) + 8), + GEN_INT (((mask >> 0) & 3) + 4), + GEN_INT (((mask >> 2) & 3) + 4), + GEN_INT (((mask >> 4) & 3) + 12), + GEN_INT (((mask >> 6) & 3) + 12))); + DONE; +}) + +;; One bit in mask selects 2 elements. +(define_insn "avx_shufps256_1" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_select:V8SF + (vec_concat:V16SF + (match_operand:V8SF 1 "register_operand" "x") + (match_operand:V8SF 2 "nonimmediate_operand" "xm")) + (parallel [(match_operand 3 "const_0_to_3_operand" "") + (match_operand 4 "const_0_to_3_operand" "") + (match_operand 5 "const_8_to_11_operand" "") + (match_operand 6 "const_8_to_11_operand" "") + (match_operand 7 "const_4_to_7_operand" "") + (match_operand 8 "const_4_to_7_operand" "") + (match_operand 9 "const_12_to_15_operand" "") + (match_operand 10 "const_12_to_15_operand" "")])))] + "TARGET_AVX + && (INTVAL (operands[3]) == (INTVAL (operands[7]) - 4) + && INTVAL (operands[4]) == (INTVAL (operands[8]) - 4) + && INTVAL (operands[5]) == (INTVAL (operands[9]) - 4) + && INTVAL (operands[6]) == (INTVAL (operands[10]) - 4))" +{ + int mask; + mask = INTVAL (operands[3]); + mask |= INTVAL (operands[4]) << 2; + mask |= (INTVAL (operands[5]) - 8) << 4; + mask |= (INTVAL (operands[6]) - 8) << 6; + operands[3] = GEN_INT (mask); + + return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_expand "sse_shufps" [(match_operand:V4SF 0 "register_operand" "") (match_operand:V4SF 1 "register_operand" "") @@ -2333,7 +3269,7 @@ "TARGET_SSE" { int mask = INTVAL (operands[3]); - emit_insn (gen_sse_shufps_1 (operands[0], operands[1], operands[2], + emit_insn (gen_sse_shufps_v4sf (operands[0], operands[1], operands[2], GEN_INT ((mask >> 0) & 3), GEN_INT ((mask >> 2) & 3), GEN_INT (((mask >> 4) & 3) + 4), @@ -2341,12 +3277,37 @@ DONE; }) -(define_insn "sse_shufps_1" - [(set (match_operand:V4SF 0 "register_operand" "=x") - (vec_select:V4SF - (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "0") - (match_operand:V4SF 2 "nonimmediate_operand" "xm")) +(define_insn "*avx_shufps_" + [(set (match_operand:SSEMODE4S 0 "register_operand" "=x") + (vec_select:SSEMODE4S + (vec_concat: + (match_operand:SSEMODE4S 1 "register_operand" "x") + (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm")) + (parallel [(match_operand 3 "const_0_to_3_operand" "") + (match_operand 4 "const_0_to_3_operand" "") + (match_operand 5 "const_4_to_7_operand" "") + (match_operand 6 "const_4_to_7_operand" "")])))] + "TARGET_AVX" +{ + int mask = 0; + mask |= INTVAL (operands[3]) << 0; + mask |= INTVAL (operands[4]) << 2; + mask |= (INTVAL (operands[5]) - 4) << 4; + mask |= (INTVAL (operands[6]) - 4) << 6; + operands[3] = GEN_INT (mask); + + return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + +(define_insn "sse_shufps_" + [(set (match_operand:SSEMODE4S 0 "register_operand" "=x") + (vec_select:SSEMODE4S + (vec_concat: + (match_operand:SSEMODE4S 1 "register_operand" "0") + (match_operand:SSEMODE4S 2 "nonimmediate_operand" "xm")) (parallel [(match_operand 3 "const_0_to_3_operand" "") (match_operand 4 "const_0_to_3_operand" "") (match_operand 5 "const_4_to_7_operand" "") @@ -2372,10 +3333,37 @@ (parallel [(const_int 2) (const_int 3)])))] "TARGET_SSE" "@ - movhps\t{%1, %0|%0, %1} - movhlps\t{%1, %0|%0, %1} - movlps\t{%H1, %0|%0, %H1}" + %vmovhps\t{%1, %0|%0, %1} + %vmovhlps\t{%1, %d0|%d0, %1} + %vmovlps\t{%H1, %d0|%d0, %H1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "V2SF,V4SF,V2SF")]) + +(define_expand "sse_loadhps_exp" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "") + (vec_concat:V4SF + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 1)])) + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_SSE" + "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);") + +(define_insn "*avx_loadhps" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o") + (vec_concat:V4SF + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0") + (parallel [(const_int 0) (const_int 1)])) + (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))] + "TARGET_AVX" + "@ + vmovhps\t{%2, %1, %0|%0, %1, %2} + vmovlhps\t{%2, %1, %0|%0, %1, %2} + vmovlps\t{%2, %H0|%H0, %2}" [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") (set_attr "mode" "V2SF,V4SF,V2SF")]) (define_insn "sse_loadhps" @@ -2393,6 +3381,20 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V2SF,V4SF,V2SF")]) +(define_insn "*avx_storelps" + [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x") + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m") + (parallel [(const_int 0) (const_int 1)])))] + "TARGET_AVX" + "@ + vmovlps\t{%1, %0|%0, %1} + vmovaps\t{%1, %0|%0, %1} + vmovlps\t{%1, %0, %0|%0, %0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V2SF,V2DF,V2SF")]) + (define_insn "sse_storelps" [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x") (vec_select:V2SF @@ -2406,6 +3408,32 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V2SF,V4SF,V2SF")]) +(define_expand "sse_loadlps_exp" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "") + (vec_concat:V4SF + (match_operand:V2SF 2 "nonimmediate_operand" "") + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" "") + (parallel [(const_int 2) (const_int 3)]))))] + "TARGET_SSE" + "ix86_fixup_binary_operands (UNKNOWN, V4SFmode, operands);") + +(define_insn "*avx_loadlps" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m") + (vec_concat:V4SF + (match_operand:V2SF 2 "nonimmediate_operand" "x,m,x") + (vec_select:V2SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x,0") + (parallel [(const_int 2) (const_int 3)]))))] + "TARGET_AVX" + "@ + shufps\t{$0xe4, %1, %2, %0|%0, %2, %1, 0xe4} + vmovlps\t{%2, %1, %0|%0, %1, %2} + vmovlps\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF,V2SF,V2SF")]) + (define_insn "sse_loadlps" [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m") (vec_concat:V4SF @@ -2421,6 +3449,18 @@ [(set_attr "type" "sselog,ssemov,ssemov") (set_attr "mode" "V4SF,V2SF,V2SF")]) +(define_insn "*avx_movss" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (match_operand:V4SF 2 "register_operand" "x") + (match_operand:V4SF 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vmovss\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_movss" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_merge:V4SF @@ -2432,6 +3472,16 @@ [(set_attr "type" "ssemov") (set_attr "mode" "SF")]) +(define_insn "*vec_dupv4sf_avx" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_duplicate:V4SF + (match_operand:SF 1 "register_operand" "x")))] + "TARGET_AVX" + "vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_insn "*vec_dupv4sf" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_duplicate:V4SF @@ -2441,10 +3491,47 @@ [(set_attr "type" "sselog1") (set_attr "mode" "V4SF")]) +(define_insn "*vec_concatv2sf_avx" + [(set (match_operand:V2SF 0 "register_operand" "=x,x,x,*y ,*y") + (vec_concat:V2SF + (match_operand:SF 1 "nonimmediate_operand" " x,x,m, x , m") + (match_operand:SF 2 "vector_move_operand" " x,m,C,*ym, C")))] + "TARGET_AVX" + "@ + vunpcklps\t{%2, %1, %0|%0, %1, %2} + vinsertps\t{$0x10, %2, %1, %0|%0, %1, %2, 0x10} + vmovss\t{%1, %0|%0, %1} + punpckldq\t{%2, %0|%0, %2} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov") + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "3,4") + (const_string "orig") + (const_string "vex"))) + (set_attr "mode" "V4SF,V4SF,SF,DI,DI")]) + +;; Although insertps takes register source, we prefer +;; unpcklps with register source since it is shorter. +(define_insn "*vec_concatv2sf_sse4_1" + [(set (match_operand:V2SF 0 "register_operand" "=x,x,x,*y ,*y") + (vec_concat:V2SF + (match_operand:SF 1 "nonimmediate_operand" " 0,0,m, 0 , m") + (match_operand:SF 2 "vector_move_operand" " x,m,C,*ym, C")))] + "TARGET_SSE4_1" + "@ + unpcklps\t{%2, %0|%0, %2} + insertps\t{$0x10, %2, %0|%0, %2, 0x10} + movss\t{%1, %0|%0, %1} + punpckldq\t{%2, %0|%0, %2} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov") + (set_attr "prefix_extra" "*,1,*,*,*") + (set_attr "mode" "V4SF,V4SF,SF,DI,DI")]) + ;; ??? In theory we can match memory for the MMX alternative, but allowing ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE ;; alternatives pretty much forces the MMX alternative to be chosen. -(define_insn "*sse_concatv2sf" +(define_insn "*vec_concatv2sf_sse" [(set (match_operand:V2SF 0 "register_operand" "=x,x,*y,*y") (vec_concat:V2SF (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m") @@ -2458,7 +3545,20 @@ [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov") (set_attr "mode" "V4SF,SF,DI,DI")]) -(define_insn "*sse_concatv4sf" +(define_insn "*vec_concatv4sf_avx" + [(set (match_operand:V4SF 0 "register_operand" "=x,x") + (vec_concat:V4SF + (match_operand:V2SF 1 "register_operand" " x,x") + (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))] + "TARGET_AVX" + "@ + vmovlhps\t{%2, %1, %0|%0, %1, %2} + vmovhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF,V2SF")]) + +(define_insn "*vec_concatv4sf_sse" [(set (match_operand:V4SF 0 "register_operand" "=x,x") (vec_concat:V4SF (match_operand:V2SF 1 "register_operand" " 0,0") @@ -2470,8 +3570,8 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V4SF,V2SF")]) -(define_expand "vec_initv4sf" - [(match_operand:V4SF 0 "register_operand" "") +(define_expand "vec_init" + [(match_operand:SSEMODE 0 "register_operand" "") (match_operand 1 "" "")] "TARGET_SSE" { @@ -2479,6 +3579,23 @@ DONE; }) +(define_insn "*vec_setv4sf_0_avx" + [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,m") + (vec_merge:V4SF + (vec_duplicate:V4SF + (match_operand:SF 2 "general_operand" " x,m,*r,x*rfF")) + (match_operand:V4SF 1 "vector_move_operand" " x,C,C ,0") + (const_int 1)))] + "TARGET_AVX" + "@ + vmovss\t{%2, %1, %0|%0, %1, %2} + vmovss\t{%2, %0|%0, %2} + vmovd\t{%2, %0|%0, %2} + #" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "vec_setv4sf_0" [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,Y2,m") (vec_merge:V4SF @@ -2496,6 +3613,22 @@ (set_attr "mode" "SF")]) ;; A subset is vec_setv4sf. +(define_insn "*vec_setv4sf_avx" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (vec_merge:V4SF + (vec_duplicate:V4SF + (match_operand:SF 2 "nonimmediate_operand" "xm")) + (match_operand:V4SF 1 "register_operand" "x") + (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))] + "TARGET_AVX" +{ + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])) << 4); + return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_insn "*vec_setv4sf_sse4_1" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_merge:V4SF @@ -2512,6 +3645,18 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "V4SF")]) +(define_insn "*avx_insertps" + [(set (match_operand:V4SF 0 "register_operand" "=x") + (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "xm") + (match_operand:V4SF 1 "register_operand" "x") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_INSERTPS))] + "TARGET_AVX" + "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}"; + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_insn "sse4_1_insertps" [(set (match_operand:V4SF 0 "register_operand" "=x") (unspec:V4SF [(match_operand:V4SF 2 "register_operand" "x") @@ -2538,9 +3683,9 @@ DONE; }) -(define_expand "vec_setv4sf" - [(match_operand:V4SF 0 "register_operand" "") - (match_operand:SF 1 "register_operand" "") +(define_expand "vec_set" + [(match_operand:SSEMODE 0 "register_operand" "") + (match_operand: 1 "register_operand" "") (match_operand 2 "const_int_operand" "")] "TARGET_SSE" { @@ -2550,9 +3695,9 @@ }) (define_insn_and_split "*vec_extractv4sf_0" - [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr") + [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r") (vec_select:SF - (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m") + (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m") (parallel [(const_int 0)])))] "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -2568,15 +3713,154 @@ DONE; }) +(define_expand "avx_vextractf128" + [(match_operand: 0 "nonimmediate_operand" "") + (match_operand:AVX256MODE 1 "register_operand" "") + (match_operand:SI 2 "const_0_to_1_operand" "")] + "TARGET_AVX" +{ + switch (INTVAL (operands[2])) + { + case 0: + emit_insn (gen_vec_extract_lo_ (operands[0], operands[1])); + break; + case 1: + emit_insn (gen_vec_extract_hi_ (operands[0], operands[1])); + break; + default: + gcc_unreachable (); + } + DONE; +}) + +(define_insn "vec_extract_lo_" + [(set (match_operand: 0 "nonimmediate_operand" "=x,m") + (vec_select: + (match_operand:AVX256MODE4P 1 "register_operand" "x,x") + (parallel [(const_int 0) (const_int 1)])))] + "TARGET_AVX" + "vextractf128\t{$0x0, %1, %0|%0, %1, 0x0}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_hi_" + [(set (match_operand: 0 "nonimmediate_operand" "=x,m") + (vec_select: + (match_operand:AVX256MODE4P 1 "register_operand" "x,x") + (parallel [(const_int 2) (const_int 3)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_lo_" + [(set (match_operand: 0 "nonimmediate_operand" "=x,m") + (vec_select: + (match_operand:AVX256MODE8P 1 "register_operand" "x,x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_hi_" + [(set (match_operand: 0 "nonimmediate_operand" "=x,m") + (vec_select: + (match_operand:AVX256MODE8P 1 "register_operand" "x,x") + (parallel [(const_int 4) (const_int 5) + (const_int 6) (const_int 7)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_lo_v16hi" + [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m") + (vec_select:V8HI + (match_operand:V16HI 1 "register_operand" "x,x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3) + (const_int 4) (const_int 5) + (const_int 6) (const_int 7)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_hi_v16hi" + [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m") + (vec_select:V8HI + (match_operand:V16HI 1 "register_operand" "x,x") + (parallel [(const_int 8) (const_int 9) + (const_int 10) (const_int 11) + (const_int 12) (const_int 13) + (const_int 14) (const_int 15)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_lo_v32qi" + [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m") + (vec_select:V16QI + (match_operand:V32QI 1 "register_operand" "x,x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3) + (const_int 4) (const_int 5) + (const_int 6) (const_int 7) + (const_int 8) (const_int 9) + (const_int 10) (const_int 11) + (const_int 12) (const_int 13) + (const_int 14) (const_int 15)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_extract_hi_v32qi" + [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m") + (vec_select:V16QI + (match_operand:V32QI 1 "register_operand" "x,x") + (parallel [(const_int 16) (const_int 17) + (const_int 18) (const_int 19) + (const_int 20) (const_int 21) + (const_int 22) (const_int 23) + (const_int 24) (const_int 25) + (const_int 26) (const_int 27) + (const_int 28) (const_int 29) + (const_int 30) (const_int 31)])))] + "TARGET_AVX" + "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "type" "sselog") + (set_attr "memory" "none,store") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_insn "*sse4_1_extractps" [(set (match_operand:SF 0 "nonimmediate_operand" "=rm") (vec_select:SF (match_operand:V4SF 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))] "TARGET_SSE4_1" - "extractps\t{%2, %1, %0|%0, %1, %2}" + "%vextractps\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) (define_insn_and_split "*vec_extract_v4sf_mem" @@ -2595,9 +3879,9 @@ DONE; }) -(define_expand "vec_extractv4sf" - [(match_operand:SF 0 "register_operand" "") - (match_operand:V4SF 1 "register_operand" "") +(define_expand "vec_extract" + [(match_operand: 0 "register_operand" "") + (match_operand:SSEMODE 1 "register_operand" "") (match_operand 2 "const_int_operand" "")] "TARGET_SSE" { @@ -2612,6 +3896,48 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_insn "avx_unpckhpd256" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_select:V4DF + (vec_concat:V8DF + (match_operand:V4DF 1 "register_operand" "x") + (match_operand:V4DF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "TARGET_AVX" + "vunpckhpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + +(define_expand "sse2_unpckhpd_exp" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_SSE2" + "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);") + +(define_insn "*avx_unpckhpd" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" " x,o,x") + (match_operand:V2DF 2 "nonimmediate_operand" " x,x,0")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vunpckhpd\t{%2, %1, %0|%0, %1, %2} + vmovlpd\t{%H1, %2, %0|%0, %2, %H1} + vmovhpd\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF,V1DF,V1DF")]) + (define_insn "sse2_unpckhpd" [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m") (vec_select:V2DF @@ -2628,6 +3954,36 @@ [(set_attr "type" "sselog,ssemov,ssemov") (set_attr "mode" "V2DF,V1DF,V1DF")]) +(define_insn "avx_movddup256" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_select:V4DF + (vec_concat:V8DF + (match_operand:V4DF 1 "nonimmediate_operand" "xm") + (match_dup 1)) + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))] + "TARGET_AVX" + "vmovddup\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + +(define_insn "*avx_movddup" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,o") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" "xm,x") + (match_dup 1)) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + vmovddup\t{%1, %0|%0, %1} + #" + [(set_attr "type" "sselog1,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF")]) + (define_insn "*sse3_movddup" [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,o") (vec_select:V2DF @@ -2660,6 +4016,48 @@ DONE; }) +(define_insn "avx_unpcklpd256" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_select:V4DF + (vec_concat:V8DF + (match_operand:V4DF 1 "register_operand" "x") + (match_operand:V4DF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "TARGET_AVX" + "vunpcklpd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + +(define_expand "sse2_unpcklpd_exp" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_SSE2" + "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);") + +(define_insn "*avx_unpcklpd" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,o") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0") + (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vunpcklpd\t{%2, %1, %0|%0, %1, %2} + vmovhpd\t{%2, %1, %0|%0, %1, %2} + vmovlpd\t{%2, %H0|%H0, %2}" + [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF,V1DF,V1DF")]) + (define_insn "sse2_unpcklpd" [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,o") (vec_select:V2DF @@ -2676,6 +4074,47 @@ [(set_attr "type" "sselog,ssemov,ssemov") (set_attr "mode" "V2DF,V1DF,V1DF")]) +(define_expand "avx_shufpd256" + [(match_operand:V4DF 0 "register_operand" "") + (match_operand:V4DF 1 "register_operand" "") + (match_operand:V4DF 2 "nonimmediate_operand" "") + (match_operand:SI 3 "const_int_operand" "")] + "TARGET_AVX" +{ + int mask = INTVAL (operands[3]); + emit_insn (gen_avx_shufpd256_1 (operands[0], operands[1], operands[2], + GEN_INT (mask & 1), + GEN_INT (mask & 2 ? 5 : 4), + GEN_INT (mask & 4 ? 3 : 2), + GEN_INT (mask & 8 ? 7 : 6))); + DONE; +}) + +(define_insn "avx_shufpd256_1" + [(set (match_operand:V4DF 0 "register_operand" "=x") + (vec_select:V4DF + (vec_concat:V8DF + (match_operand:V4DF 1 "register_operand" "x") + (match_operand:V4DF 2 "nonimmediate_operand" "xm")) + (parallel [(match_operand 3 "const_0_to_1_operand" "") + (match_operand 4 "const_4_to_5_operand" "") + (match_operand 5 "const_2_to_3_operand" "") + (match_operand 6 "const_6_to_7_operand" "")])))] + "TARGET_AVX" +{ + int mask; + mask = INTVAL (operands[3]); + mask |= (INTVAL (operands[4]) - 4) << 1; + mask |= (INTVAL (operands[5]) - 2) << 2; + mask |= (INTVAL (operands[6]) - 6) << 3; + operands[3] = GEN_INT (mask); + + return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + (define_expand "sse2_shufpd" [(match_operand:V2DF 0 "register_operand" "") (match_operand:V2DF 1 "register_operand" "") @@ -2684,18 +4123,140 @@ "TARGET_SSE2" { int mask = INTVAL (operands[3]); - emit_insn (gen_sse2_shufpd_1 (operands[0], operands[1], operands[2], + emit_insn (gen_sse2_shufpd_v2df (operands[0], operands[1], operands[2], GEN_INT (mask & 1), GEN_INT (mask & 2 ? 3 : 2))); DONE; }) -(define_insn "sse2_shufpd_1" - [(set (match_operand:V2DF 0 "register_operand" "=x") - (vec_select:V2DF - (vec_concat:V4DF - (match_operand:V2DF 1 "register_operand" "0") - (match_operand:V2DF 2 "nonimmediate_operand" "xm")) +(define_expand "vec_extract_even" + [(set (match_operand:SSEMODE4S 0 "register_operand" "") + (vec_select:SSEMODE4S + (vec_concat: + (match_operand:SSEMODE4S 1 "register_operand" "") + (match_operand:SSEMODE4S 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6)])))] + "TARGET_SSE") + +(define_expand "vec_extract_odd" + [(set (match_operand:SSEMODE4S 0 "register_operand" "") + (vec_select:SSEMODE4S + (vec_concat: + (match_operand:SSEMODE4S 1 "register_operand" "") + (match_operand:SSEMODE4S 2 "nonimmediate_operand" "")) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7)])))] + "TARGET_SSE") + +(define_expand "vec_extract_even" + [(set (match_operand:SSEMODE2D 0 "register_operand" "") + (vec_select:SSEMODE2D + (vec_concat: + (match_operand:SSEMODE2D 1 "register_operand" "") + (match_operand:SSEMODE2D 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_SSE2") + +(define_expand "vec_extract_odd" + [(set (match_operand:SSEMODE2D 0 "register_operand" "") + (vec_select:SSEMODE2D + (vec_concat: + (match_operand:SSEMODE2D 1 "register_operand" "") + (match_operand:SSEMODE2D 2 "nonimmediate_operand" "")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_SSE2") + +;; punpcklqdq and punpckhqdq are shorter than shufpd. +(define_insn "*avx_punpckhqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_AVX" + "vpunpckhqdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "sse2_punpckhqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_SSE2" + "punpckhqdq\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix_data16" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_punpcklqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_AVX" + "vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "sse2_punpcklqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_SSE2" + "punpcklqdq\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix_data16" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_shufpd_" + [(set (match_operand:SSEMODE2D 0 "register_operand" "=x") + (vec_select:SSEMODE2D + (vec_concat: + (match_operand:SSEMODE2D 1 "register_operand" "x") + (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm")) + (parallel [(match_operand 3 "const_0_to_1_operand" "") + (match_operand 4 "const_2_to_3_operand" "")])))] + "TARGET_AVX" +{ + int mask; + mask = INTVAL (operands[3]); + mask |= (INTVAL (operands[4]) - 2) << 1; + operands[3] = GEN_INT (mask); + + return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V2DF")]) + +(define_insn "sse2_shufpd_" + [(set (match_operand:SSEMODE2D 0 "register_operand" "=x") + (vec_select:SSEMODE2D + (vec_concat: + (match_operand:SSEMODE2D 1 "register_operand" "0") + (match_operand:SSEMODE2D 2 "nonimmediate_operand" "xm")) (parallel [(match_operand 3 "const_0_to_1_operand" "") (match_operand 4 "const_2_to_3_operand" "")])))] "TARGET_SSE2" @@ -2710,18 +4271,38 @@ [(set_attr "type" "sselog") (set_attr "mode" "V2DF")]) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c +(define_insn "*avx_storehpd" + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r") + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,o,o,o") + (parallel [(const_int 1)])))] + "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + vmovhpd\t{%1, %0|%0, %1} + vunpckhpd\t{%1, %1, %0|%0, %1, %1} + # + # + #" + [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov") + (set_attr "prefix" "vex") + (set_attr "mode" "V1DF,V2DF,DF,DF,DF")]) + (define_insn "sse2_storehpd" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x*fr") + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o") + (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o,o,o") (parallel [(const_int 1)])))] "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ movhpd\t{%1, %0|%0, %1} unpckhpd\t%0, %0 + # + # #" - [(set_attr "type" "ssemov,sselog1,ssemov") - (set_attr "mode" "V1DF,V2DF,DF")]) + [(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov") + (set_attr "mode" "V1DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -2734,18 +4315,23 @@ operands[1] = adjust_address (operands[1], DFmode, 8); }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_storelpd" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x*fr") + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m") + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m") (parallel [(const_int 0)])))] "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ - movlpd\t{%1, %0|%0, %1} + %vmovlpd\t{%1, %0|%0, %1} + # + # # #" - [(set_attr "type" "ssemov") - (set_attr "mode" "V1DF,DF,DF")]) + [(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "V1DF,DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -2764,21 +4350,53 @@ DONE; }) +(define_expand "sse2_loadhpd_exp" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "") + (vec_concat:V2DF + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" "") + (parallel [(const_int 0)])) + (match_operand:DF 2 "nonimmediate_operand" "")))] + "TARGET_SSE2" + "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);") + +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c +(define_insn "*avx_loadhpd" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,o,o,o") + (vec_concat:V2DF + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,0,0") + (parallel [(const_int 0)])) + (match_operand:DF 2 "nonimmediate_operand" " m,x,x,*f,r")))] + "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vmovhpd\t{%2, %1, %0|%0, %1, %2} + vunpcklpd\t{%2, %1, %0|%0, %1, %2} + # + # + #" + [(set_attr "type" "ssemov,sselog,ssemov,fmov,imov") + (set_attr "prefix" "vex") + (set_attr "mode" "V1DF,V2DF,DF,DF,DF")]) + (define_insn "sse2_loadhpd" - [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o") + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o,o,o") (vec_concat:V2DF (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0") + (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0,0,0") (parallel [(const_int 0)])) - (match_operand:DF 2 "nonimmediate_operand" " m,x,0,x*fr")))] + (match_operand:DF 2 "nonimmediate_operand" " m,x,0,x,*f,r")))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ movhpd\t{%2, %0|%0, %2} unpcklpd\t{%2, %0|%0, %2} shufpd\t{$1, %1, %0|%0, %1, 1} + # + # #" - [(set_attr "type" "ssemov,sselog,sselog,other") - (set_attr "mode" "V1DF,V2DF,V2DF,DF")]) + [(set_attr "type" "ssemov,sselog,sselog,ssemov,fmov,imov") + (set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -2791,12 +4409,44 @@ operands[0] = adjust_address (operands[0], DFmode, 8); }) +(define_expand "sse2_loadlpd_exp" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "") + (vec_concat:V2DF + (match_operand:DF 2 "nonimmediate_operand" "") + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" "") + (parallel [(const_int 1)]))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);") + +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c +(define_insn "*avx_loadlpd" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,m,m,m") + (vec_concat:V2DF + (match_operand:DF 2 "nonimmediate_operand" " m,m,x,x,x,*f,r") + (vec_select:DF + (match_operand:V2DF 1 "vector_move_operand" " C,x,x,o,0,0,0") + (parallel [(const_int 1)]))))] + "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vmovsd\t{%2, %0|%0, %2} + vmovlpd\t{%2, %1, %0|%0, %1, %2} + vmovsd\t{%2, %1, %0|%0, %1, %2} + vmovhpd\t{%H1, %2, %0|%0, %2, %H1} + # + # + #" + [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov,fmov,imov") + (set_attr "prefix" "vex") + (set_attr "mode" "DF,V1DF,V1DF,V1DF,DF,DF,DF")]) + (define_insn "sse2_loadlpd" - [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,m") + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,m,m,m") (vec_concat:V2DF - (match_operand:DF 2 "nonimmediate_operand" " m,m,x,0,0,x*fr") + (match_operand:DF 2 "nonimmediate_operand" " m,m,x,0,0,x,*f,r") (vec_select:DF - (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0") + (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0,0,0") (parallel [(const_int 1)]))))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ @@ -2805,9 +4455,11 @@ movsd\t{%2, %0|%0, %2} shufpd\t{$2, %2, %0|%0, %2, 2} movhpd\t{%H1, %0|%0, %H1} + # + # #" - [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other") - (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")]) + [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,fmov,imov") + (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -2850,6 +4502,23 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V2SF,V4SF,V2SF")]) +(define_insn "*avx_movsd" + [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m,x,o") + (vec_merge:V2DF + (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,x,0") + (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0,o,x") + (const_int 1)))] + "TARGET_AVX" + "@ + vmovsd\t{%2, %1, %0|%0, %1, %2} + vmovlpd\t{%2, %1, %0|%0, %1, %2} + vmovlpd\t{%2, %0|%0, %2} + vmovhps\t{%H1, %2, %0|%0, %2, %H1} + vmovhps\t{%1, %H0|%H0, %1}" + [(set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "DF,V1DF,V1DF,V1DF,V1DF")]) + (define_insn "sse2_movsd" [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m,x,x,o") (vec_merge:V2DF @@ -2872,8 +4541,9 @@ (vec_duplicate:V2DF (match_operand:DF 1 "nonimmediate_operand" "xm")))] "TARGET_SSE3" - "movddup\t{%1, %0|%0, %1}" + "%vmovddup\t{%1, %0|%0, %1}" [(set_attr "type" "sselog1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DF")]) (define_insn "vec_dupv2df" @@ -2891,10 +4561,25 @@ (match_operand:DF 1 "nonimmediate_operand" "xm") (match_dup 1)))] "TARGET_SSE3" - "movddup\t{%1, %0|%0, %1}" + "%vmovddup\t{%1, %0|%0, %1}" [(set_attr "type" "sselog1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "DF")]) +(define_insn "*vec_concatv2df_avx" + [(set (match_operand:V2DF 0 "register_operand" "=x,x,x") + (vec_concat:V2DF + (match_operand:DF 1 "nonimmediate_operand" " x,x,m") + (match_operand:DF 2 "vector_move_operand" " x,m,C")))] + "TARGET_AVX" + "@ + vunpcklpd\t{%2, %1, %0|%0, %1, %2} + vmovhpd\t{%2, %1, %0|%0, %1, %2} + vmovsd\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "DF,V1DF,DF")]) + (define_insn "*vec_concatv2df" [(set (match_operand:V2DF 0 "register_operand" "=Y2,Y2,Y2,x,x") (vec_concat:V2DF @@ -2910,37 +4595,6 @@ [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov") (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")]) -(define_expand "vec_setv2df" - [(match_operand:V2DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_set (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extractv2df" - [(match_operand:DF 0 "register_operand" "") - (match_operand:V2DF 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_extract (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_initv2df" - [(match_operand:V2DF 0 "register_operand" "") - (match_operand 1 "" "")] - "TARGET_SSE" -{ - ix86_expand_vector_init (false, operands[0], operands[1]); - DONE; -}) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel integral arithmetic @@ -2955,82 +4609,62 @@ "TARGET_SSE2" "operands[2] = force_reg (mode, CONST0_RTX (mode));") -(define_expand "add3" +(define_expand "3" [(set (match_operand:SSEMODEI 0 "register_operand" "") - (plus:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] + (plusminus:SSEMODEI + (match_operand:SSEMODEI 1 "nonimmediate_operand" "") + (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (PLUS, mode, operands);") + "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "*add3" +(define_insn "*avx_3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (plus:SSEMODEI - (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") + (plusminus:SSEMODEI + (match_operand:SSEMODEI 1 "nonimmediate_operand" "x") (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, mode, operands)" - "padd\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_insn "sse2_ssadd3" - [(set (match_operand:SSEMODE12 0 "register_operand" "=x") - (ss_plus:SSEMODE12 - (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (SS_PLUS, mode, operands)" - "padds\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_insn "sse2_usadd3" - [(set (match_operand:SSEMODE12 0 "register_operand" "=x") - (us_plus:SSEMODE12 - (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (US_PLUS, mode, operands)" - "paddus\t{%2, %0|%0, %2}" + "TARGET_AVX && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_expand "sub3" - [(set (match_operand:SSEMODEI 0 "register_operand" "") - (minus:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (MINUS, mode, operands);") - -(define_insn "*sub3" +(define_insn "*3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (minus:SSEMODEI - (match_operand:SSEMODEI 1 "register_operand" "0") + (plusminus:SSEMODEI + (match_operand:SSEMODEI 1 "nonimmediate_operand" "0") (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2" - "psub\t{%2, %0|%0, %2}" + "TARGET_SSE2 && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_sssub3" +(define_expand "sse2_3" + [(set (match_operand:SSEMODE12 0 "register_operand" "") + (sat_plusminus:SSEMODE12 + (match_operand:SSEMODE12 1 "nonimmediate_operand" "") + (match_operand:SSEMODE12 2 "nonimmediate_operand" "")))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (, mode, operands);") + +(define_insn "*avx_3" [(set (match_operand:SSEMODE12 0 "register_operand" "=x") - (ss_minus:SSEMODE12 - (match_operand:SSEMODE12 1 "register_operand" "0") + (sat_plusminus:SSEMODE12 + (match_operand:SSEMODE12 1 "nonimmediate_operand" "x") (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2" - "psubs\t{%2, %0|%0, %2}" + "TARGET_AVX && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "sse2_ussub3" +(define_insn "*sse2_3" [(set (match_operand:SSEMODE12 0 "register_operand" "=x") - (us_minus:SSEMODE12 - (match_operand:SSEMODE12 1 "register_operand" "0") + (sat_plusminus:SSEMODE12 + (match_operand:SSEMODE12 1 "nonimmediate_operand" "0") (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2" - "psubus\t{%2, %0|%0, %2}" + "TARGET_SSE2 && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) @@ -3121,6 +4755,16 @@ "TARGET_SSE2" "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") +(define_insn "*avx_mulv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmullw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*mulv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0") @@ -3144,6 +4788,22 @@ "TARGET_SSE2" "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") +(define_insn "*avxv8hi3_highpart" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (truncate:V8HI + (lshiftrt:V8SI + (mult:V8SI + (sign_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "%x")) + (sign_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) + (const_int 16))))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmulhw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*smulv8hi3_highpart" [(set (match_operand:V8HI 0 "register_operand" "=x") (truncate:V8HI @@ -3173,6 +4833,22 @@ "TARGET_SSE2" "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") +(define_insn "*avx_umulv8hi3_highpart" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (truncate:V8HI + (lshiftrt:V8SI + (mult:V8SI + (zero_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "%x")) + (zero_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) + (const_int 16))))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmulhuw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*umulv8hi3_highpart" [(set (match_operand:V8HI 0 "register_operand" "=x") (truncate:V8HI @@ -3189,7 +4865,38 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_umulv2siv2di3" +(define_expand "sse2_umulv2siv2di3" + [(set (match_operand:V2DI 0 "register_operand" "") + (mult:V2DI + (zero_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)]))) + (zero_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)])))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);") + +(define_insn "*avx_umulv2siv2di3" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (mult:V2DI + (zero_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x") + (parallel [(const_int 0) (const_int 2)]))) + (zero_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) (const_int 2)])))))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)" + "vpmuludq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_umulv2siv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (mult:V2DI (zero_extend:V2DI @@ -3206,25 +4913,127 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse4_1_mulv2siv2di3" +(define_expand "sse4_1_mulv2siv2di3" + [(set (match_operand:V2DI 0 "register_operand" "") + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)])))))] + "TARGET_SSE4_1" + "ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands);") + +(define_insn "*avx_mulv2siv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (mult:V2DI (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "%0") + (match_operand:V4SI 1 "nonimmediate_operand" "%x") (parallel [(const_int 0) (const_int 2)]))) (sign_extend:V2DI (vec_select:V2SI (match_operand:V4SI 2 "nonimmediate_operand" "xm") (parallel [(const_int 0) (const_int 2)])))))] - "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)" - "pmuldq\t{%2, %0|%0, %2}" + "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)" + "vpmuldq\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseimul") - (set_attr "prefix_extra" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "sse2_pmaddwd" - [(set (match_operand:V4SI 0 "register_operand" "=x") +(define_insn "*sse4_1_mulv2siv2di3" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%0") + (parallel [(const_int 0) (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) (const_int 2)])))))] + "TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, V4SImode, operands)" + "pmuldq\t{%2, %0|%0, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_expand "sse2_pmaddwd" + [(set (match_operand:V4SI 0 "register_operand" "") + (plus:V4SI + (mult:V4SI + (sign_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 1 "nonimmediate_operand" "") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6)]))) + (sign_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "nonimmediate_operand" "") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6)])))) + (mult:V4SI + (sign_extend:V4SI + (vec_select:V4HI (match_dup 1) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7)]))) + (sign_extend:V4SI + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7)]))))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") + +(define_insn "*avx_pmaddwd" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (plus:V4SI + (mult:V4SI + (sign_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 1 "nonimmediate_operand" "%x") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6)]))) + (sign_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6)])))) + (mult:V4SI + (sign_extend:V4SI + (vec_select:V4HI (match_dup 1) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7)]))) + (sign_extend:V4SI + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7)]))))))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmaddwd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_pmaddwd" + [(set (match_operand:V4SI 0 "register_operand" "=x") (plus:V4SI (mult:V4SI (sign_extend:V4SI @@ -3270,6 +5079,16 @@ ix86_fixup_binary_operands_no_copy (MULT, V4SImode, operands); }) +(define_insn "*avx_mulv4si3" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x") + (match_operand:V4SI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)" + "vpmulld\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*sse4_1_mulv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%0") @@ -3283,7 +5102,7 @@ ;; We don't have a straight 32-bit parallel multiply on SSE5, so fake it with a ;; multiply/add. In general, we expect the define_split to occur before ;; register allocation, so we have to handle the corner case where the target -;; is used as the base or index register in operands 1/2. +;; is the same as one of the inputs. (define_insn_and_split "*sse5_mulv4si3" [(set (match_operand:V4SI 0 "register_operand" "=&x") (mult:V4SI (match_operand:V4SI 1 "register_operand" "%x") @@ -3371,6 +5190,42 @@ rtx t1, t2, t3, t4, t5, t6, thirtytwo; rtx op0, op1, op2; + if (TARGET_SSE5) + { + /* op1: A,B,C,D, op2: E,F,G,H */ + op0 = operands[0]; + op1 = gen_lowpart (V4SImode, operands[1]); + op2 = gen_lowpart (V4SImode, operands[2]); + t1 = gen_reg_rtx (V4SImode); + t2 = gen_reg_rtx (V4SImode); + t3 = gen_reg_rtx (V4SImode); + t4 = gen_reg_rtx (V2DImode); + t5 = gen_reg_rtx (V2DImode); + + /* t1: B,A,D,C */ + emit_insn (gen_sse2_pshufd_1 (t1, op1, + GEN_INT (1), + GEN_INT (0), + GEN_INT (3), + GEN_INT (2))); + + /* t2: 0 */ + emit_move_insn (t2, CONST0_RTX (V4SImode)); + + /* t3: (B*E),(A*F),(D*G),(C*H) */ + emit_insn (gen_sse5_pmacsdd (t3, t1, op2, t2)); + + /* t4: (B*E)+(A*F), (D*G)+(C*H) */ + emit_insn (gen_sse5_phadddq (t4, t3)); + + /* t5: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */ + emit_insn (gen_ashlv2di3 (t5, t4, GEN_INT (32))); + + /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */ + emit_insn (gen_sse5_pmacsdql (op0, op1, op2, t5)); + DONE; + } + op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; @@ -3490,18 +5345,24 @@ [(match_operand:V2DI 0 "register_operand" "") (match_operand:V4SI 1 "register_operand" "") (match_operand:V4SI 2 "register_operand" "")] - "TARGET_SSE2" + "TARGET_SSE5" { - rtx op1, op2, t1, t2; + rtx t1, t2; - op1 = operands[1]; - op2 = operands[2]; t1 = gen_reg_rtx (V4SImode); t2 = gen_reg_rtx (V4SImode); - emit_insn (gen_vec_interleave_highv4si (t1, op1, op1)); - emit_insn (gen_vec_interleave_highv4si (t2, op2, op2)); - emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2)); + emit_insn (gen_sse2_pshufd_1 (t1, operands[1], + GEN_INT (0), + GEN_INT (2), + GEN_INT (1), + GEN_INT (3))); + emit_insn (gen_sse2_pshufd_1 (t2, operands[2], + GEN_INT (0), + GEN_INT (2), + GEN_INT (1), + GEN_INT (3))); + emit_insn (gen_sse5_mulv2div2di3_high (operands[0], t1, t2)); DONE; }) @@ -3509,18 +5370,25 @@ [(match_operand:V2DI 0 "register_operand" "") (match_operand:V4SI 1 "register_operand" "") (match_operand:V4SI 2 "register_operand" "")] - "TARGET_SSE2" + "TARGET_SSE5" { - rtx op1, op2, t1, t2; + rtx t1, t2; - op1 = operands[1]; - op2 = operands[2]; t1 = gen_reg_rtx (V4SImode); t2 = gen_reg_rtx (V4SImode); - emit_insn (gen_vec_interleave_lowv4si (t1, op1, op1)); - emit_insn (gen_vec_interleave_lowv4si (t2, op2, op2)); - emit_insn (gen_sse2_umulv2siv2di3 (operands[0], t1, t2)); + emit_insn (gen_sse2_pshufd_1 (t1, operands[1], + GEN_INT (0), + GEN_INT (2), + GEN_INT (1), + GEN_INT (3))); + emit_insn (gen_sse2_pshufd_1 (t2, operands[2], + GEN_INT (0), + GEN_INT (2), + GEN_INT (1), + GEN_INT (3))); + emit_insn (gen_sse5_mulv2div2di3_low (operands[0], t1, t2)); + DONE; DONE; }) @@ -3604,6 +5472,17 @@ DONE; }) +(define_insn "*avx_ashr3" + [(set (match_operand:SSEMODE24 0 "register_operand" "=x") + (ashiftrt:SSEMODE24 + (match_operand:SSEMODE24 1 "register_operand" "x") + (match_operand:SI 2 "nonmemory_operand" "xN")))] + "TARGET_AVX" + "vpsra\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseishft") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ashr3" [(set (match_operand:SSEMODE24 0 "register_operand" "=x") (ashiftrt:SSEMODE24 @@ -3615,6 +5494,17 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_lshr3" + [(set (match_operand:SSEMODE248 0 "register_operand" "=x") + (lshiftrt:SSEMODE248 + (match_operand:SSEMODE248 1 "register_operand" "x") + (match_operand:SI 2 "nonmemory_operand" "xN")))] + "TARGET_AVX" + "vpsrl\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseishft") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "lshr3" [(set (match_operand:SSEMODE248 0 "register_operand" "=x") (lshiftrt:SSEMODE248 @@ -3626,6 +5516,17 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_ashl3" + [(set (match_operand:SSEMODE248 0 "register_operand" "=x") + (ashift:SSEMODE248 + (match_operand:SSEMODE248 1 "register_operand" "x") + (match_operand:SI 2 "nonmemory_operand" "xN")))] + "TARGET_AVX" + "vpsll\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseishft") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ashl3" [(set (match_operand:SSEMODE248 0 "register_operand" "=x") (ashift:SSEMODE248 @@ -3657,36 +5558,51 @@ operands[1] = gen_lowpart (TImode, operands[1]); }) -(define_expand "umaxv16qi3" +(define_insn "*avx_3" + [(set (match_operand:SSEMODE124 0 "register_operand" "=x") + (maxmin:SSEMODE124 + (match_operand:SSEMODE124 1 "nonimmediate_operand" "%x") + (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_expand "v16qi3" [(set (match_operand:V16QI 0 "register_operand" "") - (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "") - (match_operand:V16QI 2 "nonimmediate_operand" "")))] + (umaxmin:V16QI + (match_operand:V16QI 1 "nonimmediate_operand" "") + (match_operand:V16QI 2 "nonimmediate_operand" "")))] "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);") + "ix86_fixup_binary_operands_no_copy (, V16QImode, operands);") -(define_insn "*umaxv16qi3" +(define_insn "*v16qi3" [(set (match_operand:V16QI 0 "register_operand" "=x") - (umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0") - (match_operand:V16QI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (UMAX, V16QImode, operands)" - "pmaxub\t{%2, %0|%0, %2}" + (umaxmin:V16QI + (match_operand:V16QI 1 "nonimmediate_operand" "%0") + (match_operand:V16QI 2 "nonimmediate_operand" "xm")))] + "TARGET_SSE2 && ix86_binary_operator_ok (, V16QImode, operands)" + "pb\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_expand "smaxv8hi3" +(define_expand "v8hi3" [(set (match_operand:V8HI 0 "register_operand" "") - (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "") - (match_operand:V8HI 2 "nonimmediate_operand" "")))] + (smaxmin:V8HI + (match_operand:V8HI 1 "nonimmediate_operand" "") + (match_operand:V8HI 2 "nonimmediate_operand" "")))] "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (SMAX, V8HImode, operands);") + "ix86_fixup_binary_operands_no_copy (, V8HImode, operands);") -(define_insn "*smaxv8hi3" +(define_insn "*v8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") - (smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0") - (match_operand:V8HI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (SMAX, V8HImode, operands)" - "pmaxsw\t{%2, %0|%0, %2}" + (smaxmin:V8HI + (match_operand:V8HI 1 "nonimmediate_operand" "%0") + (match_operand:V8HI 2 "nonimmediate_operand" "xm")))] + "TARGET_SSE2 && ix86_binary_operator_ok (, V8HImode, operands)" + "pw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) @@ -3735,13 +5651,13 @@ } }) -(define_insn "*sse4_1_smax3" +(define_insn "*sse4_1_3" [(set (match_operand:SSEMODE14 0 "register_operand" "=x") - (smax:SSEMODE14 + (smaxmin:SSEMODE14 (match_operand:SSEMODE14 1 "nonimmediate_operand" "%0") (match_operand:SSEMODE14 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE4_1 && ix86_binary_operator_ok (SMAX, mode, operands)" - "pmaxs\t{%2, %0|%0, %2}" + "TARGET_SSE4_1 && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -3771,51 +5687,17 @@ } }) -(define_insn "*sse4_1_umax3" +(define_insn "*sse4_1_3" [(set (match_operand:SSEMODE24 0 "register_operand" "=x") - (umax:SSEMODE24 + (umaxmin:SSEMODE24 (match_operand:SSEMODE24 1 "nonimmediate_operand" "%0") (match_operand:SSEMODE24 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE4_1 && ix86_binary_operator_ok (UMAX, mode, operands)" - "pmaxu\t{%2, %0|%0, %2}" + "TARGET_SSE4_1 && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -(define_expand "uminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "") - (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "") - (match_operand:V16QI 2 "nonimmediate_operand" "")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (UMIN, V16QImode, operands);") - -(define_insn "*uminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=x") - (umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0") - (match_operand:V16QI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (UMIN, V16QImode, operands)" - "pminub\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_expand "sminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "") - (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "") - (match_operand:V8HI 2 "nonimmediate_operand" "")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (SMIN, V8HImode, operands);") - -(define_insn "*sminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=x") - (smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0") - (match_operand:V8HI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (SMIN, V8HImode, operands)" - "pminsw\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - (define_expand "smin3" [(set (match_operand:SSEMODE14 0 "register_operand" "") (smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "") @@ -3841,17 +5723,6 @@ } }) -(define_insn "*sse4_1_smin3" - [(set (match_operand:SSEMODE14 0 "register_operand" "=x") - (smin:SSEMODE14 - (match_operand:SSEMODE14 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODE14 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE4_1 && ix86_binary_operator_ok (SMIN, mode, operands)" - "pmins\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_extra" "1") - (set_attr "mode" "TI")]) - (define_expand "umin3" [(set (match_operand:SSEMODE24 0 "register_operand" "") (umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "") @@ -3877,24 +5748,32 @@ } }) -(define_insn "*sse4_1_umin3" - [(set (match_operand:SSEMODE24 0 "register_operand" "=x") - (umin:SSEMODE24 - (match_operand:SSEMODE24 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODE24 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE4_1 && ix86_binary_operator_ok (UMIN, mode, operands)" - "pminu\t{%2, %0|%0, %2}" - [(set_attr "type" "sseiadd") - (set_attr "prefix_extra" "1") - (set_attr "mode" "TI")]) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel integral comparisons ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "sse2_eq3" +(define_expand "sse2_eq3" + [(set (match_operand:SSEMODE124 0 "register_operand" "") + (eq:SSEMODE124 + (match_operand:SSEMODE124 1 "nonimmediate_operand" "") + (match_operand:SSEMODE124 2 "nonimmediate_operand" "")))] + "TARGET_SSE2 && !TARGET_SSE5" + "ix86_fixup_binary_operands_no_copy (EQ, mode, operands);") + +(define_insn "*avx_eq3" + [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") + (eq:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "%x") + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX && ix86_binary_operator_ok (EQ, mode, operands)" + "vpcmpeq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_eq3" [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (eq:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0") @@ -3906,7 +5785,15 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse4_1_eqv2di3" +(define_expand "sse4_1_eqv2di3" + [(set (match_operand:V2DI 0 "register_operand" "") + (eq:V2DI + (match_operand:V2DI 1 "nonimmediate_operand" "") + (match_operand:V2DI 2 "nonimmediate_operand" "")))] + "TARGET_SSE4_1" + "ix86_fixup_binary_operands_no_copy (EQ, V2DImode, operands);") + +(define_insn "*sse4_1_eqv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (eq:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0") @@ -3917,6 +5804,17 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_gt3" + [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") + (gt:SSEMODE1248 + (match_operand:SSEMODE1248 1 "register_operand" "x") + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vpcmpgt\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_gt3" [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (gt:SSEMODE124 @@ -3931,7 +5829,7 @@ (define_insn "sse4_2_gtv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (gt:V2DI - (match_operand:V2DI 1 "nonimmediate_operand" "0") + (match_operand:V2DI 1 "register_operand" "0") (match_operand:V2DI 2 "nonimmediate_operand" "xm")))] "TARGET_SSE4_2" "pcmpgtq\t{%2, %0|%0, %2}" @@ -3991,46 +5889,39 @@ operands[2] = force_reg (mode, gen_rtx_CONST_VECTOR (mode, v)); }) -(define_expand "and3" - [(set (match_operand:SSEMODEI 0 "register_operand" "") - (and:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] - "TARGET_SSE" - "ix86_fixup_binary_operands_no_copy (AND, mode, operands);") +(define_insn "*avx_andnot3" + [(set (match_operand:AVX256MODEI 0 "register_operand" "=x") + (and:AVX256MODEI + (not:AVX256MODEI (match_operand:AVX256MODEI 1 "register_operand" "x")) + (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vandnps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) -(define_insn "*sse_and3" +(define_insn "*sse_andnot3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (and:SSEMODEI - (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") + (and:SSEMODEI + (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0")) (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "(TARGET_SSE && !TARGET_SSE2) - && ix86_binary_operator_ok (AND, mode, operands)" - "andps\t{%2, %0|%0, %2}" + "(TARGET_SSE && !TARGET_SSE2)" + "andnps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "V4SF")]) -(define_insn "*sse2_and3" +(define_insn "*avx_andnot3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") (and:SSEMODEI - (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") + (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "x")) (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (AND, mode, operands)" - "pand\t{%2, %0|%0, %2}" + "TARGET_AVX" + "vpandn\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "*sse_nand3" - [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (and:SSEMODEI - (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0")) - (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "(TARGET_SSE && !TARGET_SSE2)" - "andnps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "sse2_nand3" +(define_insn "sse2_andnot3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") (and:SSEMODEI (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0")) @@ -4041,125 +5932,86 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_expand "andtf3" - [(set (match_operand:TF 0 "register_operand" "") - (and:TF (match_operand:TF 1 "nonimmediate_operand" "") - (match_operand:TF 2 "nonimmediate_operand" "")))] - "TARGET_64BIT" - "ix86_fixup_binary_operands_no_copy (AND, TFmode, operands);") - -(define_insn "*andtf3" - [(set (match_operand:TF 0 "register_operand" "=x") - (and:TF - (match_operand:TF 1 "nonimmediate_operand" "%0") - (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT && ix86_binary_operator_ok (AND, TFmode, operands)" - "pand\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_insn "*nandtf3" +(define_insn "*andnottf3" [(set (match_operand:TF 0 "register_operand" "=x") (and:TF (not:TF (match_operand:TF 1 "register_operand" "0")) (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT" + "TARGET_SSE2" "pandn\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_expand "ior3" +(define_expand "3" [(set (match_operand:SSEMODEI 0 "register_operand" "") - (ior:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] + (plogic:SSEMODEI + (match_operand:SSEMODEI 1 "nonimmediate_operand" "") + (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] "TARGET_SSE" - "ix86_fixup_binary_operands_no_copy (IOR, mode, operands);") + "ix86_fixup_binary_operands_no_copy (, mode, operands);") + +(define_insn "*avx_3" + [(set (match_operand:AVX256MODEI 0 "register_operand" "=x") + (plogic:AVX256MODEI + (match_operand:AVX256MODEI 1 "nonimmediate_operand" "%x") + (match_operand:AVX256MODEI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX + && ix86_binary_operator_ok (, mode, operands)" + "vps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) -(define_insn "*sse_ior3" +(define_insn "*sse_3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (ior:SSEMODEI + (plogic:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] "(TARGET_SSE && !TARGET_SSE2) - && ix86_binary_operator_ok (IOR, mode, operands)" - "orps\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, mode, operands)" + "ps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "V4SF")]) -(define_insn "*sse2_ior3" +(define_insn "*avx_3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (ior:SSEMODEI - (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (IOR, mode, operands)" - "por\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_expand "iortf3" - [(set (match_operand:TF 0 "register_operand" "") - (ior:TF (match_operand:TF 1 "nonimmediate_operand" "") - (match_operand:TF 2 "nonimmediate_operand" "")))] - "TARGET_64BIT" - "ix86_fixup_binary_operands_no_copy (IOR, TFmode, operands);") - -(define_insn "*iortf3" - [(set (match_operand:TF 0 "register_operand" "=x") - (ior:TF - (match_operand:TF 1 "nonimmediate_operand" "%0") - (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT && ix86_binary_operator_ok (IOR, TFmode, operands)" - "por\t{%2, %0|%0, %2}" + (plogic:SSEMODEI + (match_operand:SSEMODEI 1 "nonimmediate_operand" "%x") + (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX + && ix86_binary_operator_ok (, mode, operands)" + "vp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_expand "xor3" - [(set (match_operand:SSEMODEI 0 "register_operand" "") - (xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))] - "TARGET_SSE" - "ix86_fixup_binary_operands_no_copy (XOR, mode, operands);") - -(define_insn "*sse_xor3" - [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (xor:SSEMODEI - (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") - (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "(TARGET_SSE && !TARGET_SSE2) - && ix86_binary_operator_ok (XOR, mode, operands)" - "xorps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "*sse2_xor3" +(define_insn "*sse2_3" [(set (match_operand:SSEMODEI 0 "register_operand" "=x") - (xor:SSEMODEI + (plogic:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0") (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && ix86_binary_operator_ok (XOR, mode, operands)" - "pxor\t{%2, %0|%0, %2}" + "TARGET_SSE2 && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_expand "xortf3" +(define_expand "tf3" [(set (match_operand:TF 0 "register_operand" "") - (xor:TF (match_operand:TF 1 "nonimmediate_operand" "") - (match_operand:TF 2 "nonimmediate_operand" "")))] - "TARGET_64BIT" - "ix86_fixup_binary_operands_no_copy (XOR, TFmode, operands);") + (plogic:TF + (match_operand:TF 1 "nonimmediate_operand" "") + (match_operand:TF 2 "nonimmediate_operand" "")))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (, TFmode, operands);") -(define_insn "*xortf3" +(define_insn "*tf3" [(set (match_operand:TF 0 "register_operand" "=x") - (xor:TF + (plogic:TF (match_operand:TF 1 "nonimmediate_operand" "%0") (match_operand:TF 2 "nonimmediate_operand" "xm")))] - "TARGET_64BIT && ix86_binary_operator_ok (XOR, TFmode, operands)" - "pxor\t{%2, %0|%0, %2}" + "TARGET_SSE2 && ix86_binary_operator_ok (, TFmode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) @@ -4188,6 +6040,12 @@ { rtx op1, op2, h1, l1, h2, l2, h3, l3; + if (TARGET_SSE5) + { + ix86_expand_sse5_pack (operands); + DONE; + } + op1 = gen_lowpart (V16QImode, operands[1]); op2 = gen_lowpart (V16QImode, operands[2]); h1 = gen_reg_rtx (V16QImode); @@ -4223,6 +6081,12 @@ { rtx op1, op2, h1, l1, h2, l2; + if (TARGET_SSE5) + { + ix86_expand_sse5_pack (operands); + DONE; + } + op1 = gen_lowpart (V8HImode, operands[1]); op2 = gen_lowpart (V8HImode, operands[2]); h1 = gen_reg_rtx (V8HImode); @@ -4252,6 +6116,12 @@ { rtx op1, op2, h1, l1; + if (TARGET_SSE5) + { + ix86_expand_sse5_pack (operands); + DONE; + } + op1 = gen_lowpart (V4SImode, operands[1]); op2 = gen_lowpart (V4SImode, operands[2]); h1 = gen_reg_rtx (V4SImode); @@ -4391,19 +6261,85 @@ DONE; }) -(define_insn "sse2_packsswb" - [(set (match_operand:V16QI 0 "register_operand" "=x") - (vec_concat:V16QI - (ss_truncate:V8QI - (match_operand:V8HI 1 "register_operand" "0")) - (ss_truncate:V8QI - (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))] - "TARGET_SSE2" - "packsswb\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - +(define_expand "vec_interleave_highv4sf" + [(set (match_operand:V4SF 0 "register_operand" "") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "TARGET_SSE") + +(define_expand "vec_interleave_lowv4sf" + [(set (match_operand:V4SF 0 "register_operand" "") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "TARGET_SSE") + +(define_expand "vec_interleave_highv2df" + [(set (match_operand:V2DF 0 "register_operand" "") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "register_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")) + (parallel [(const_int 1) + (const_int 3)])))] + "TARGET_SSE2") + +(define_expand "vec_interleave_lowv2df" + [(set (match_operand:V2DF 0 "register_operand" "") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "register_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_SSE2") + +(define_insn "*avx_packsswb" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (vec_concat:V16QI + (ss_truncate:V8QI + (match_operand:V8HI 1 "register_operand" "x")) + (ss_truncate:V8QI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))] + "TARGET_AVX" + "vpacksswb\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "sse2_packsswb" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (vec_concat:V16QI + (ss_truncate:V8QI + (match_operand:V8HI 1 "register_operand" "0")) + (ss_truncate:V8QI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))] + "TARGET_SSE2" + "packsswb\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix_data16" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_packssdw" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (ss_truncate:V4HI + (match_operand:V4SI 1 "register_operand" "x")) + (ss_truncate:V4HI + (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))] + "TARGET_AVX" + "vpackssdw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_packssdw" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -4417,6 +6353,19 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_packuswb" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (vec_concat:V16QI + (us_truncate:V8QI + (match_operand:V8HI 1 "register_operand" "x")) + (us_truncate:V8QI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))] + "TARGET_AVX" + "vpackuswb\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_packuswb" [(set (match_operand:V16QI 0 "register_operand" "=x") (vec_concat:V16QI @@ -4430,6 +6379,26 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_punpckhbw" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 8) (const_int 24) + (const_int 9) (const_int 25) + (const_int 10) (const_int 26) + (const_int 11) (const_int 27) + (const_int 12) (const_int 28) + (const_int 13) (const_int 29) + (const_int 14) (const_int 30) + (const_int 15) (const_int 31)])))] + "TARGET_AVX" + "vpunpckhbw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_punpckhbw" [(set (match_operand:V16QI 0 "register_operand" "=x") (vec_select:V16QI @@ -4450,6 +6419,26 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_punpcklbw" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 16) + (const_int 1) (const_int 17) + (const_int 2) (const_int 18) + (const_int 3) (const_int 19) + (const_int 4) (const_int 20) + (const_int 5) (const_int 21) + (const_int 6) (const_int 22) + (const_int 7) (const_int 23)])))] + "TARGET_AVX" + "vpunpcklbw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_punpcklbw" [(set (match_operand:V16QI 0 "register_operand" "=x") (vec_select:V16QI @@ -4470,6 +6459,22 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_punpckhwd" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 4) (const_int 12) + (const_int 5) (const_int 13) + (const_int 6) (const_int 14) + (const_int 7) (const_int 15)])))] + "TARGET_AVX" + "vpunpckhwd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_punpckhwd" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_select:V8HI @@ -4486,6 +6491,22 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_punpcklwd" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 8) + (const_int 1) (const_int 9) + (const_int 2) (const_int 10) + (const_int 3) (const_int 11)])))] + "TARGET_AVX" + "vpunpcklwd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_punpcklwd" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_select:V8HI @@ -4502,6 +6523,20 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_punpckhdq" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "x") + (match_operand:V4SI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "TARGET_AVX" + "vpunpckhdq\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_punpckhdq" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_select:V4SI @@ -4516,46 +6551,48 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_punpckldq" +(define_insn "*avx_punpckldq" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_select:V4SI (vec_concat:V8SI - (match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 1 "register_operand" "x") (match_operand:V4SI 2 "nonimmediate_operand" "xm")) (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))] - "TARGET_SSE2" - "punpckldq\t{%2, %0|%0, %2}" + "TARGET_AVX" + "vpunpckldq\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "sse2_punpckhqdq" - [(set (match_operand:V2DI 0 "register_operand" "=x") - (vec_select:V2DI - (vec_concat:V4DI - (match_operand:V2DI 1 "register_operand" "0") - (match_operand:V2DI 2 "nonimmediate_operand" "xm")) - (parallel [(const_int 1) - (const_int 3)])))] +(define_insn "sse2_punpckldq" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "0") + (match_operand:V4SI 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] "TARGET_SSE2" - "punpckhqdq\t{%2, %0|%0, %2}" + "punpckldq\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_punpcklqdq" - [(set (match_operand:V2DI 0 "register_operand" "=x") - (vec_select:V2DI - (vec_concat:V4DI - (match_operand:V2DI 1 "register_operand" "0") - (match_operand:V2DI 2 "nonimmediate_operand" "xm")) - (parallel [(const_int 0) - (const_int 2)])))] - "TARGET_SSE2" - "punpcklqdq\t{%2, %0|%0, %2}" +(define_insn "*avx_pinsr" + [(set (match_operand:SSEMODE124 0 "register_operand" "=x") + (vec_merge:SSEMODE124 + (vec_duplicate:SSEMODE124 + (match_operand: 2 "nonimmediate_operand" "rm")) + (match_operand:SSEMODE124 1 "register_operand" "x") + (match_operand:SI 3 "const_pow2_1_to__operand" "n")))] + "TARGET_AVX" +{ + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); + return "vpinsr\t{%3, %k2, %1, %0|%0, %1, %k2, %3}"; +} [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pinsrb" @@ -4607,6 +6644,22 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_pinsrq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_merge:V2DI + (vec_duplicate:V2DI + (match_operand:DI 2 "nonimmediate_operand" "rm")) + (match_operand:V2DI 1 "register_operand" "x") + (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))] + "TARGET_AVX && TARGET_64BIT" +{ + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); + return "vpinsrq\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*sse4_1_pinsrq" [(set (match_operand:V2DI 0 "register_operand" "=x") (vec_merge:V2DI @@ -4614,7 +6667,7 @@ (match_operand:DI 2 "nonimmediate_operand" "rm")) (match_operand:V2DI 1 "register_operand" "0") (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))] - "TARGET_SSE4_1" + "TARGET_SSE4_1 && TARGET_64BIT" { operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); return "pinsrq\t{%3, %2, %0|%0, %2, %3}"; @@ -4630,9 +6683,10 @@ (match_operand:V16QI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")]))))] "TARGET_SSE4_1" - "pextrb\t{%2, %1, %0|%0, %1, %2}" + "%vpextrb\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrb_memory" @@ -4641,9 +6695,10 @@ (match_operand:V16QI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_15_operand" "n")])))] "TARGET_SSE4_1" - "pextrb\t{%2, %1, %0|%0, %1, %2}" + "%vpextrb\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse2_pextrw" @@ -4653,9 +6708,10 @@ (match_operand:V8HI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))] "TARGET_SSE2" - "pextrw\t{%2, %1, %0|%0, %1, %2}" + "%vpextrw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrw_memory" @@ -4664,9 +6720,10 @@ (match_operand:V8HI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")])))] "TARGET_SSE4_1" - "pextrw\t{%2, %1, %0|%0, %1, %2}" + "%vpextrw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrd" @@ -4675,9 +6732,10 @@ (match_operand:V4SI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))] "TARGET_SSE4_1" - "pextrd\t{%2, %1, %0|%0, %1, %2}" + "%vpextrd\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) ;; It must come before *vec_extractv2di_1_sse since it is preferred. @@ -4687,9 +6745,10 @@ (match_operand:V2DI 1 "register_operand" "x") (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))] "TARGET_SSE4_1 && TARGET_64BIT" - "pextrq\t{%2, %1, %0|%0, %1, %2}" + "%vpextrq\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_expand "sse2_pshufd" @@ -4724,10 +6783,11 @@ mask |= INTVAL (operands[5]) << 6; operands[2] = GEN_INT (mask); - return "pshufd\t{%2, %1, %0|%0, %1, %2}"; + return "%vpshufd\t{%2, %1, %0|%0, %1, %2}"; } [(set_attr "type" "sselog1") (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_expand "sse2_pshuflw" @@ -4766,10 +6826,11 @@ mask |= INTVAL (operands[5]) << 6; operands[2] = GEN_INT (mask); - return "pshuflw\t{%2, %1, %0|%0, %1, %2}"; + return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}"; } [(set_attr "type" "sselog") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_expand "sse2_pshufhw" @@ -4808,10 +6869,11 @@ mask |= (INTVAL (operands[5]) - 4) << 6; operands[2] = GEN_INT (mask); - return "pshufhw\t{%2, %1, %0|%0, %1, %2}"; + return "%vpshufhw\t{%2, %1, %0|%0, %1, %2}"; } [(set_attr "type" "sselog") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_expand "sse2_loadd" @@ -4824,6 +6886,22 @@ "TARGET_SSE" "operands[2] = CONST0_RTX (V4SImode);") +(define_insn "*avx_loadld" + [(set (match_operand:V4SI 0 "register_operand" "=x,Yi,x") + (vec_merge:V4SI + (vec_duplicate:V4SI + (match_operand:SI 2 "nonimmediate_operand" "m ,r ,x")) + (match_operand:V4SI 1 "reg_or_0_operand" "C ,C ,x") + (const_int 1)))] + "TARGET_AVX" + "@ + vmovd\t{%2, %0|%0, %2} + vmovd\t{%2, %0|%0, %2} + vmovss\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "TI,TI,V4SF")]) + (define_insn "sse2_loadld" [(set (match_operand:V4SI 0 "register_operand" "=Y2,Yi,x,x") (vec_merge:V4SI @@ -4881,7 +6959,7 @@ "") (define_insn "*sse2_storeq_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=mx,r,r") + [(set (match_operand:DI 0 "nonimmediate_operand" "=mx,*r,r") (vec_select:DI (match_operand:V2DI 1 "nonimmediate_operand" "x,Yi,o") (parallel [(const_int 0)])))] @@ -4889,8 +6967,9 @@ "@ # # - mov{q}\t{%1, %0|%0, %1}" + %vmov{q}\t{%1, %0|%0, %1}" [(set_attr "type" "*,*,imov") + (set_attr "prefix" "*,*,maybe_vex") (set_attr "mode" "*,*,DI")]) (define_insn "*sse2_storeq" @@ -4916,6 +6995,24 @@ operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); }) +(define_insn "*vec_extractv2di_1_rex64_avx" + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r") + (vec_select:DI + (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o,o") + (parallel [(const_int 1)])))] + "TARGET_64BIT + && TARGET_AVX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + vmovhps\t{%1, %0|%0, %1} + vpsrldq\t{$8, %1, %0|%0, %1, 8} + vmovq\t{%H1, %0|%0, %H1} + vmov{q}\t{%H1, %0|%0, %H1}" + [(set_attr "type" "ssemov,sseishft,ssemov,imov") + (set_attr "memory" "*,none,*,*") + (set_attr "prefix" "vex") + (set_attr "mode" "V2SF,TI,TI,DI")]) + (define_insn "*vec_extractv2di_1_rex64" [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x,r") (vec_select:DI @@ -4931,6 +7028,23 @@ (set_attr "memory" "*,none,*,*") (set_attr "mode" "V2SF,TI,TI,DI")]) +(define_insn "*vec_extractv2di_1_avx" + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x") + (vec_select:DI + (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o") + (parallel [(const_int 1)])))] + "!TARGET_64BIT + && TARGET_AVX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + vmovhps\t{%1, %0|%0, %1} + vpsrldq\t{$8, %1, %0|%0, %1, 8} + vmovq\t{%H1, %0|%0, %H1}" + [(set_attr "type" "ssemov,sseishft,ssemov") + (set_attr "memory" "*,none,*") + (set_attr "prefix" "vex") + (set_attr "mode" "V2SF,TI,TI")]) + (define_insn "*vec_extractv2di_1_sse2" [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x") (vec_select:DI @@ -4967,11 +7081,22 @@ (match_operand:SI 1 "register_operand" " Y2,0")))] "TARGET_SSE" "@ - pshufd\t{$0, %1, %0|%0, %1, 0} + %vpshufd\t{$0, %1, %0|%0, %1, 0} shufps\t{$0, %0, %0|%0, %0, 0}" [(set_attr "type" "sselog1") + (set_attr "prefix" "maybe_vex,orig") (set_attr "mode" "TI,V4SF")]) +(define_insn "*vec_dupv2di_avx" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (vec_duplicate:V2DI + (match_operand:DI 1 "register_operand" "x")))] + "TARGET_AVX" + "vpunpcklqdq\t{%1, %1, %0|%0, %1, %1}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "*vec_dupv2di" [(set (match_operand:V2DI 0 "register_operand" "=Y2,x") (vec_duplicate:V2DI @@ -4983,14 +7108,49 @@ [(set_attr "type" "sselog1,ssemov") (set_attr "mode" "TI,V4SF")]) +(define_insn "*vec_concatv2si_avx" + [(set (match_operand:V2SI 0 "register_operand" "=x,x,x ,*y ,*y") + (vec_concat:V2SI + (match_operand:SI 1 "nonimmediate_operand" "x ,x,rm, 0 ,rm") + (match_operand:SI 2 "vector_move_operand" "rm,x,C ,*ym,C")))] + "TARGET_AVX" + "@ + vpinsrd\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1} + vpunpckldq\t{%2, %1, %0|%0, %1, %2} + vmovd\t{%1, %0|%0, %1} + punpckldq\t{%2, %0|%0, %2} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov") + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "3,4") + (const_string "orig") + (const_string "vex"))) + (set_attr "mode" "TI,TI,TI,DI,DI")]) + +(define_insn "*vec_concatv2si_sse4_1" + [(set (match_operand:V2SI 0 "register_operand" "=x,x,x ,*y ,*y") + (vec_concat:V2SI + (match_operand:SI 1 "nonimmediate_operand" "0 ,0,rm, 0 ,rm") + (match_operand:SI 2 "vector_move_operand" "rm,x,C ,*ym,C")))] + "TARGET_SSE4_1" + "@ + pinsrd\t{$0x1, %2, %0|%0, %2, 0x1} + punpckldq\t{%2, %0|%0, %2} + movd\t{%1, %0|%0, %1} + punpckldq\t{%2, %0|%0, %2} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov") + (set_attr "prefix_extra" "1,*,*,*,*") + (set_attr "mode" "TI,TI,TI,DI,DI")]) + ;; ??? In theory we can match memory for the MMX alternative, but allowing ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE ;; alternatives pretty much forces the MMX alternative to be chosen. -(define_insn "*sse2_concatv2si" - [(set (match_operand:V2SI 0 "register_operand" "=Y2, Y2,*y,*y") +(define_insn "*vec_concatv2si_sse2" + [(set (match_operand:V2SI 0 "register_operand" "=x,x ,*y,*y") (vec_concat:V2SI - (match_operand:SI 1 "nonimmediate_operand" " 0 ,rm , 0,rm") - (match_operand:SI 2 "reg_or_0_operand" " Y2,C ,*y, C")))] + (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm") + (match_operand:SI 2 "reg_or_0_operand" " x,C ,*y, C")))] "TARGET_SSE2" "@ punpckldq\t{%2, %0|%0, %2} @@ -5000,7 +7160,7 @@ [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov") (set_attr "mode" "TI,TI,DI,DI")]) -(define_insn "*sse1_concatv2si" +(define_insn "*vec_concatv2si_sse" [(set (match_operand:V2SI 0 "register_operand" "=x,x,*y,*y") (vec_concat:V2SI (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm") @@ -5014,6 +7174,19 @@ [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov") (set_attr "mode" "V4SF,V4SF,DI,DI")]) +(define_insn "*vec_concatv4si_1_avx" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") + (vec_concat:V4SI + (match_operand:V2SI 1 "register_operand" " x,x") + (match_operand:V2SI 2 "nonimmediate_operand" " x,m")))] + "TARGET_AVX" + "@ + vpunpcklqdq\t{%2, %1, %0|%0, %1, %2} + vmovhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "TI,V2SF")]) + (define_insn "*vec_concatv4si_1" [(set (match_operand:V4SI 0 "register_operand" "=Y2,x,x") (vec_concat:V4SI @@ -5027,162 +7200,92 @@ [(set_attr "type" "sselog,ssemov,ssemov") (set_attr "mode" "TI,V4SF,V2SF")]) +(define_insn "*vec_concatv2di_avx" + [(set (match_operand:V2DI 0 "register_operand" "=x,?x,x,x") + (vec_concat:V2DI + (match_operand:DI 1 "nonimmediate_operand" " m,*y,x,x") + (match_operand:DI 2 "vector_move_operand" " C, C,x,m")))] + "!TARGET_64BIT && TARGET_AVX" + "@ + vmovq\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + vpunpcklqdq\t{%2, %1, %0|%0, %1, %2} + vmovhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssemov,ssemov,sselog,ssemov") + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "1") + (const_string "orig") + (const_string "vex"))) + (set_attr "mode" "TI,TI,TI,V2SF")]) + (define_insn "vec_concatv2di" - [(set (match_operand:V2DI 0 "register_operand" "=Y2,?Y2,Y2,x,x,x") + [(set (match_operand:V2DI 0 "register_operand" "=Y2 ,?Y2,Y2,x,x") (vec_concat:V2DI - (match_operand:DI 1 "nonimmediate_operand" " m,*y ,0 ,0,0,m") - (match_operand:DI 2 "vector_move_operand" " C, C,Y2,x,m,0")))] + (match_operand:DI 1 "nonimmediate_operand" " mY2,*y ,0 ,0,0") + (match_operand:DI 2 "vector_move_operand" " C , C,Y2,x,m")))] "!TARGET_64BIT && TARGET_SSE" "@ movq\t{%1, %0|%0, %1} movq2dq\t{%1, %0|%0, %1} punpcklqdq\t{%2, %0|%0, %2} movlhps\t{%2, %0|%0, %2} - movhps\t{%2, %0|%0, %2} - movlps\t{%1, %0|%0, %1}" - [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov") - (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")]) + movhps\t{%2, %0|%0, %2}" + [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov") + (set_attr "mode" "TI,TI,TI,V4SF,V2SF")]) -(define_insn "*vec_concatv2di_rex" - [(set (match_operand:V2DI 0 "register_operand" "=Y2,Yi,!Y2,Y2,x,x,x") +(define_insn "*vec_concatv2di_rex64_avx" + [(set (match_operand:V2DI 0 "register_operand" "=x,x,Yi,!x,x,x") + (vec_concat:V2DI + (match_operand:DI 1 "nonimmediate_operand" " x,m,r ,*y,x,x") + (match_operand:DI 2 "vector_move_operand" "rm,C,C ,C ,x,m")))] + "TARGET_64BIT && TARGET_AVX" + "@ + vpinsrq\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1} + vmovq\t{%1, %0|%0, %1} + vmovq\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + vpunpcklqdq\t{%2, %1, %0|%0, %1, %2} + vmovhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov") + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "3") + (const_string "orig") + (const_string "vex"))) + (set_attr "mode" "TI,TI,TI,TI,TI,V2SF")]) + +(define_insn "*vec_concatv2di_rex64_sse4_1" + [(set (match_operand:V2DI 0 "register_operand" "=x ,x ,Yi,!x,x,x,x") (vec_concat:V2DI - (match_operand:DI 1 "nonimmediate_operand" " m,r ,*y ,0 ,0,0,m") - (match_operand:DI 2 "vector_move_operand" " C,C ,C ,Y2,x,m,0")))] - "TARGET_64BIT" + (match_operand:DI 1 "nonimmediate_operand" " 0 ,mx,r ,*y,0,0,0") + (match_operand:DI 2 "vector_move_operand" " rm,C ,C ,C ,x,x,m")))] + "TARGET_64BIT && TARGET_SSE4_1" "@ + pinsrq\t{$0x1, %2, %0|%0, %2, 0x1} movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1} movq2dq\t{%1, %0|%0, %1} punpcklqdq\t{%2, %0|%0, %2} movlhps\t{%2, %0|%0, %2} - movhps\t{%2, %0|%0, %2} - movlps\t{%1, %0|%0, %1}" - [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,ssemov") - (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF,V2SF")]) + movhps\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov,ssemov") + (set_attr "prefix_extra" "1,*,*,*,*,*,*") + (set_attr "mode" "TI,TI,TI,TI,TI,V4SF,V2SF")]) -(define_expand "vec_setv2di" - [(match_operand:V2DI 0 "register_operand" "") - (match_operand:DI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_set (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extractv2di" - [(match_operand:DI 0 "register_operand" "") - (match_operand:V2DI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_extract (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_initv2di" - [(match_operand:V2DI 0 "register_operand" "") - (match_operand 1 "" "")] - "TARGET_SSE" -{ - ix86_expand_vector_init (false, operands[0], operands[1]); - DONE; -}) - -(define_expand "vec_setv4si" - [(match_operand:V4SI 0 "register_operand" "") - (match_operand:SI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_set (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extractv4si" - [(match_operand:SI 0 "register_operand" "") - (match_operand:V4SI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_extract (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_initv4si" - [(match_operand:V4SI 0 "register_operand" "") - (match_operand 1 "" "")] - "TARGET_SSE" -{ - ix86_expand_vector_init (false, operands[0], operands[1]); - DONE; -}) - -(define_expand "vec_setv8hi" - [(match_operand:V8HI 0 "register_operand" "") - (match_operand:HI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_set (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extractv8hi" - [(match_operand:HI 0 "register_operand" "") - (match_operand:V8HI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_extract (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_initv8hi" - [(match_operand:V8HI 0 "register_operand" "") - (match_operand 1 "" "")] - "TARGET_SSE" -{ - ix86_expand_vector_init (false, operands[0], operands[1]); - DONE; -}) - -(define_expand "vec_setv16qi" - [(match_operand:V16QI 0 "register_operand" "") - (match_operand:QI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_set (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extractv16qi" - [(match_operand:QI 0 "register_operand" "") - (match_operand:V16QI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_SSE" -{ - ix86_expand_vector_extract (false, operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_initv16qi" - [(match_operand:V16QI 0 "register_operand" "") - (match_operand 1 "" "")] - "TARGET_SSE" -{ - ix86_expand_vector_init (false, operands[0], operands[1]); - DONE; -}) +(define_insn "*vec_concatv2di_rex64_sse" + [(set (match_operand:V2DI 0 "register_operand" "=Y2 ,Yi,!Y2,Y2,x,x") + (vec_concat:V2DI + (match_operand:DI 1 "nonimmediate_operand" " mY2,r ,*y ,0 ,0,0") + (match_operand:DI 2 "vector_move_operand" " C ,C ,C ,Y2,x,m")))] + "TARGET_64BIT && TARGET_SSE" + "@ + movq\t{%1, %0|%0, %1} + movq\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + punpcklqdq\t{%2, %0|%0, %2} + movlhps\t{%2, %0|%0, %2} + movhps\t{%2, %0|%0, %2}" + [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov") + (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF")]) (define_expand "vec_unpacku_hi_v16qi" [(match_operand:V8HI 0 "register_operand" "") @@ -5358,7 +7461,54 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "sse2_uavgv16qi3" +(define_expand "sse2_uavgv16qi3" + [(set (match_operand:V16QI 0 "register_operand" "") + (truncate:V16QI + (lshiftrt:V16HI + (plus:V16HI + (plus:V16HI + (zero_extend:V16HI + (match_operand:V16QI 1 "nonimmediate_operand" "")) + (zero_extend:V16HI + (match_operand:V16QI 2 "nonimmediate_operand" ""))) + (const_vector:V16QI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (PLUS, V16QImode, operands);") + +(define_insn "*avx_uavgv16qi3" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (truncate:V16QI + (lshiftrt:V16HI + (plus:V16HI + (plus:V16HI + (zero_extend:V16HI + (match_operand:V16QI 1 "nonimmediate_operand" "%x")) + (zero_extend:V16HI + (match_operand:V16QI 2 "nonimmediate_operand" "xm"))) + (const_vector:V16QI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_AVX && ix86_binary_operator_ok (PLUS, V16QImode, operands)" + "vpavgb\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_uavgv16qi3" [(set (match_operand:V16QI 0 "register_operand" "=x") (truncate:V16QI (lshiftrt:V16HI @@ -5383,7 +7533,46 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_uavgv8hi3" +(define_expand "sse2_uavgv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "") + (truncate:V8HI + (lshiftrt:V8SI + (plus:V8SI + (plus:V8SI + (zero_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "")) + (zero_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" ""))) + (const_vector:V8HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (PLUS, V8HImode, operands);") + +(define_insn "*avx_uavgv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (truncate:V8HI + (lshiftrt:V8SI + (plus:V8SI + (plus:V8SI + (zero_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "%x")) + (zero_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) + (const_vector:V8HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_AVX && ix86_binary_operator_ok (PLUS, V8HImode, operands)" + "vpavgw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_uavgv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (truncate:V8HI (lshiftrt:V8SI @@ -5406,6 +7595,17 @@ ;; The correct representation for this is absolutely enormous, and ;; surely not generally useful. +(define_insn "*avx_psadbw" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm")] + UNSPEC_PSADBW))] + "TARGET_AVX" + "vpsadbw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_psadbw" [(set (match_operand:V2DI 0 "register_operand" "=x") (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0") @@ -5417,14 +7617,26 @@ (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) +(define_insn "avx_movmskp256" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI + [(match_operand:AVX256MODEF2P 1 "register_operand" "x")] + UNSPEC_MOVMSK))] + "AVX256_VEC_FLOAT_MODE_P (mode)" + "vmovmskp\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_movmskp" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:SSEMODEF2P 1 "register_operand" "x")] UNSPEC_MOVMSK))] "SSE_VEC_FLOAT_MODE_P (mode)" - "movmskp\t{%1, %0|%0, %1}" + "%vmovmskp\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "")]) (define_insn "sse2_pmovmskb" @@ -5432,9 +7644,10 @@ (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")] UNSPEC_MOVMSK))] "TARGET_SSE2" - "pmovmskb\t{%1, %0|%0, %1}" + "%vpmovmskb\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_expand "sse2_maskmovdqu" @@ -5454,9 +7667,10 @@ UNSPEC_MASKMOV))] "TARGET_SSE2 && !TARGET_64BIT" ;; @@@ check ordering of operands in intel/nonintel syntax - "maskmovdqu\t{%2, %1|%1, %2}" + "%vmaskmovdqu\t{%2, %1|%1, %2}" [(set_attr "type" "ssecvt") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse2_maskmovdqu_rex64" @@ -5467,25 +7681,28 @@ UNSPEC_MASKMOV))] "TARGET_SSE2 && TARGET_64BIT" ;; @@@ check ordering of operands in intel/nonintel syntax - "maskmovdqu\t{%2, %1|%1, %2}" + "%vmaskmovdqu\t{%2, %1|%1, %2}" [(set_attr "type" "ssecvt") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse_ldmxcsr" [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDMXCSR)] "TARGET_SSE" - "ldmxcsr\t%0" + "%vldmxcsr\t%0" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "load")]) (define_insn "sse_stmxcsr" [(set (match_operand:SI 0 "memory_operand" "=m") (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))] "TARGET_SSE" - "stmxcsr\t%0" + "%vstmxcsr\t%0" [(set_attr "type" "sse") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "store")]) (define_expand "sse_sfence" @@ -5525,7 +7742,7 @@ (define_insn "*sse2_mfence" [(set (match_operand:BLK 0 "" "") (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))] - "TARGET_SSE2" + "TARGET_64BIT || TARGET_SSE2" "mfence" [(set_attr "type" "sse") (set_attr "memory" "unknown")]) @@ -5585,6 +7802,49 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_insn "*avx_phaddwv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (vec_concat:V4HI + (vec_concat:V2HI + (plus:HI + (vec_select:HI + (match_operand:V8HI 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 5)]))) + (plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 7)]))))) + (vec_concat:V4HI + (vec_concat:V2HI + (plus:HI + (vec_select:HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) + (plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 5)]))) + (plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))] + "TARGET_AVX" + "vphaddw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phaddwv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5656,6 +7916,33 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_phadddv4si3" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (vec_concat:V4SI + (vec_concat:V2SI + (plus:SI + (vec_select:SI + (match_operand:V4SI 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 1)]))) + (plus:SI + (vec_select:SI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2SI + (plus:SI + (vec_select:SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:SI (match_dup 2) (parallel [(const_int 1)]))) + (plus:SI + (vec_select:SI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))] + "TARGET_AVX" + "vphaddd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phadddv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_concat:V4SI @@ -5703,14 +7990,14 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) -(define_insn "ssse3_phaddswv8hi3" +(define_insn "*avx_phaddswv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI (vec_concat:V4HI (vec_concat:V2HI (ss_plus:HI (vec_select:HI - (match_operand:V8HI 1 "register_operand" "0") + (match_operand:V8HI 1 "register_operand" "x") (parallel [(const_int 0)])) (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) (ss_plus:HI @@ -5740,33 +8027,76 @@ (ss_plus:HI (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))] - "TARGET_SSSE3" - "phaddsw\t{%2, %0|%0, %2}" + "TARGET_AVX" + "vphaddsw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseiadd") - (set_attr "prefix_data16" "1") - (set_attr "prefix_extra" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "ssse3_phaddswv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (vec_concat:V4HI - (vec_concat:V2HI - (ss_plus:HI - (vec_select:HI - (match_operand:V4HI 1 "register_operand" "0") - (parallel [(const_int 0)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) - (ss_plus:HI - (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) - (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) - (vec_concat:V2HI - (ss_plus:HI - (vec_select:HI - (match_operand:V4HI 2 "nonimmediate_operand" "ym") - (parallel [(const_int 0)])) - (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) - (ss_plus:HI - (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) +(define_insn "ssse3_phaddswv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (vec_concat:V4HI + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI + (match_operand:V8HI 1 "register_operand" "0") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (ss_plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 5)]))) + (ss_plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 7)]))))) + (vec_concat:V4HI + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) + (ss_plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 5)]))) + (ss_plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))] + "TARGET_SSSE3" + "phaddsw\t{%2, %0|%0, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_insn "ssse3_phaddswv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_concat:V4HI + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI + (match_operand:V4HI 1 "register_operand" "0") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (ss_plus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (ss_plus:HI + (vec_select:HI + (match_operand:V4HI 2 "nonimmediate_operand" "ym") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) + (ss_plus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))] "TARGET_SSSE3" "phaddsw\t{%2, %0|%0, %2}" @@ -5774,6 +8104,49 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_phsubwv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (vec_concat:V4HI + (vec_concat:V2HI + (minus:HI + (vec_select:HI + (match_operand:V8HI 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 5)]))) + (minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 7)]))))) + (vec_concat:V4HI + (vec_concat:V2HI + (minus:HI + (vec_select:HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) + (minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 5)]))) + (minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))] + "TARGET_AVX" + "vphsubw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubwv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5845,6 +8218,33 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_phsubdv4si3" + [(set (match_operand:V4SI 0 "register_operand" "=x") + (vec_concat:V4SI + (vec_concat:V2SI + (minus:SI + (vec_select:SI + (match_operand:V4SI 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 1)]))) + (minus:SI + (vec_select:SI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:SI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2SI + (minus:SI + (vec_select:SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:SI (match_dup 2) (parallel [(const_int 1)]))) + (minus:SI + (vec_select:SI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))] + "TARGET_AVX" + "vphsubd\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubdv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_concat:V4SI @@ -5892,6 +8292,49 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_phsubswv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (vec_concat:V4HI + (vec_concat:V2HI + (ss_minus:HI + (vec_select:HI + (match_operand:V8HI 1 "register_operand" "x") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (ss_minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (ss_minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 5)]))) + (ss_minus:HI + (vec_select:HI (match_dup 1) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 1) (parallel [(const_int 7)]))))) + (vec_concat:V4HI + (vec_concat:V2HI + (ss_minus:HI + (vec_select:HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 1)]))) + (ss_minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 2)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) + (vec_concat:V2HI + (ss_minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 4)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 5)]))) + (ss_minus:HI + (vec_select:HI (match_dup 2) (parallel [(const_int 6)])) + (vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))] + "TARGET_AVX" + "vphsubsw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubswv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5963,13 +8406,66 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) -(define_insn "ssse3_pmaddubswv8hi3" +(define_insn "*avx_pmaddubsw128" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (ss_plus:V8HI + (mult:V8HI + (zero_extend:V8HI + (vec_select:V4QI + (match_operand:V16QI 1 "register_operand" "x") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6) + (const_int 8) + (const_int 10) + (const_int 12) + (const_int 14)]))) + (sign_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) + (const_int 2) + (const_int 4) + (const_int 6) + (const_int 8) + (const_int 10) + (const_int 12) + (const_int 14)])))) + (mult:V8HI + (zero_extend:V8HI + (vec_select:V16QI (match_dup 1) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7) + (const_int 9) + (const_int 11) + (const_int 13) + (const_int 15)]))) + (sign_extend:V8HI + (vec_select:V16QI (match_dup 2) + (parallel [(const_int 1) + (const_int 3) + (const_int 5) + (const_int 7) + (const_int 9) + (const_int 11) + (const_int 13) + (const_int 15)]))))))] + "TARGET_AVX" + "vpmaddubsw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "ssse3_pmaddubsw128" [(set (match_operand:V8HI 0 "register_operand" "=x") (ss_plus:V8HI (mult:V8HI (zero_extend:V8HI (vec_select:V4QI - (match_operand:V16QI 1 "nonimmediate_operand" "0") + (match_operand:V16QI 1 "register_operand" "0") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -6017,13 +8513,13 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -(define_insn "ssse3_pmaddubswv4hi3" +(define_insn "ssse3_pmaddubsw" [(set (match_operand:V4HI 0 "register_operand" "=y") (ss_plus:V4HI (mult:V4HI (zero_extend:V4HI (vec_select:V4QI - (match_operand:V8QI 1 "nonimmediate_operand" "0") + (match_operand:V8QI 1 "register_operand" "0") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -6054,7 +8550,50 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) -(define_insn "ssse3_pmulhrswv8hi3" +(define_expand "ssse3_pmulhrswv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "") + (truncate:V8HI + (lshiftrt:V8SI + (plus:V8SI + (lshiftrt:V8SI + (mult:V8SI + (sign_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "")) + (sign_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" ""))) + (const_int 14)) + (const_vector:V8HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSSE3" + "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") + +(define_insn "*avx_pmulhrswv8hi3" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (truncate:V8HI + (lshiftrt:V8SI + (plus:V8SI + (lshiftrt:V8SI + (mult:V8SI + (sign_extend:V8SI + (match_operand:V8HI 1 "nonimmediate_operand" "%x")) + (sign_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) + (const_int 14)) + (const_vector:V8HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmulhrsw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*ssse3_pmulhrswv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (truncate:V8HI (lshiftrt:V8SI @@ -6078,29 +8617,58 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -(define_insn "ssse3_pmulhrswv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") +(define_expand "ssse3_pmulhrswv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "") (truncate:V4HI (lshiftrt:V4SI (plus:V4SI (lshiftrt:V4SI (mult:V4SI (sign_extend:V4SI - (match_operand:V4HI 1 "nonimmediate_operand" "%0")) + (match_operand:V4HI 1 "nonimmediate_operand" "")) (sign_extend:V4SI - (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) + (match_operand:V4HI 2 "nonimmediate_operand" ""))) (const_int 14)) (const_vector:V4HI [(const_int 1) (const_int 1) (const_int 1) (const_int 1)])) (const_int 1))))] - "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)" - "pmulhrsw\t{%2, %0|%0, %2}" - [(set_attr "type" "sseimul") - (set_attr "prefix_extra" "1") - (set_attr "mode" "DI")]) + "TARGET_SSSE3" + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") -(define_insn "ssse3_pshufbv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=x") +(define_insn "*ssse3_pmulhrswv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (lshiftrt:V4SI + (mult:V4SI + (sign_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "%0")) + (sign_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) + (const_int 14)) + (const_vector:V4HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)" + "pmulhrsw\t{%2, %0|%0, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix_extra" "1") + (set_attr "mode" "DI")]) + +(define_insn "*avx_pshufbv16qi3" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm")] + UNSPEC_PSHUFB))] + "TARGET_AVX" + "vpshufb\t{%2, %1, %0|%0, %1, %2}"; + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "ssse3_pshufbv16qi3" + [(set (match_operand:V16QI 0 "register_operand" "=x") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0") (match_operand:V16QI 2 "nonimmediate_operand" "xm")] UNSPEC_PSHUFB))] @@ -6122,6 +8690,18 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_psign3" + [(set (match_operand:SSEMODE124 0 "register_operand" "=x") + (unspec:SSEMODE124 + [(match_operand:SSEMODE124 1 "register_operand" "x") + (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")] + UNSPEC_PSIGN))] + "TARGET_AVX" + "vpsign\t{%2, %1, %0|%0, %1, %2}"; + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_psign3" [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (unspec:SSEMODE124 @@ -6147,6 +8727,21 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_insn "*avx_palignrti" + [(set (match_operand:TI 0 "register_operand" "=x") + (unspec:TI [(match_operand:TI 1 "register_operand" "x") + (match_operand:TI 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")] + UNSPEC_PALIGNR))] + "TARGET_AVX" +{ + operands[3] = GEN_INT (INTVAL (operands[3]) / 8); + return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "sseishft") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_palignrti" [(set (match_operand:TI 0 "register_operand" "=x") (unspec:TI [(match_operand:TI 1 "register_operand" "0") @@ -6182,10 +8777,11 @@ [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))] "TARGET_SSSE3" - "pabs\t{%1, %0|%0, %1}"; + "%vpabs\t{%1, %0|%0, %1}" [(set_attr "type" "sselog1") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "abs2" @@ -6278,12 +8874,37 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_insn "avx_blendp" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (vec_merge:AVXMODEF2P + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm") + (match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:SI 3 "const_0_to__operand" "n")))] + "TARGET_AVX" + "vblendp\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_blendvp" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm") + (match_operand:AVXMODEF2P 3 "register_operand" "x")] + UNSPEC_BLENDV))] + "TARGET_AVX" + "vblendvp\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse4_1_blendp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm") (match_operand:SSEMODEF2P 1 "register_operand" "0") - (match_operand:SI 3 "const_0_to_3_operand" "n")))] + (match_operand:SI 3 "const_0_to__operand" "n")))] "TARGET_SSE4_1" "blendp\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssemov") @@ -6303,6 +8924,19 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "")]) +(define_insn "avx_dpp" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "nonimmediate_operand" "%x") + (match_operand:AVXMODEF2P 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_DP))] + "TARGET_AVX" + "vdpp\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemul") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse4_1_dpp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P @@ -6321,9 +8955,22 @@ (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")] UNSPEC_MOVNTDQA))] "TARGET_SSE4_1" - "movntdqa\t{%1, %0|%0, %1}" + "%vmovntdqa\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "*avx_mpsadbw" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_MPSADBW))] + "TARGET_AVX" + "vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_mpsadbw" @@ -6338,6 +8985,19 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_packusdw" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_concat:V8HI + (us_truncate:V4HI + (match_operand:V4SI 1 "register_operand" "x")) + (us_truncate:V4HI + (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))] + "TARGET_AVX" + "vpackusdw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse4_1_packusdw" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -6351,6 +9011,18 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_pblendvb" + [(set (match_operand:V16QI 0 "register_operand" "=x") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x") + (match_operand:V16QI 2 "nonimmediate_operand" "xm") + (match_operand:V16QI 3 "register_operand" "x")] + UNSPEC_BLENDV))] + "TARGET_AVX" + "vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse4_1_pblendvb" [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x") (unspec:V16QI [(match_operand:V16QI 1 "reg_not_xmm0_operand" "0") @@ -6363,6 +9035,18 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) +(define_insn "*avx_pblendw" + [(set (match_operand:V8HI 0 "register_operand" "=x") + (vec_merge:V8HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (match_operand:V8HI 1 "register_operand" "x") + (match_operand:SI 3 "const_0_to_255_operand" "n")))] + "TARGET_AVX" + "vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse4_1_pblendw" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_merge:V8HI @@ -6380,9 +9064,10 @@ (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")] UNSPEC_PHMINPOSUW))] "TARGET_SSE4_1" - "phminposuw\t{%1, %0|%0, %1}" + "%vphminposuw\t{%1, %0|%0, %1}" [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv8qiv8hi2" @@ -6399,9 +9084,10 @@ (const_int 6) (const_int 7)]))))] "TARGET_SSE4_1" - "pmovsxbw\t{%1, %0|%0, %1}" + "%vpmovsxbw\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv8qiv8hi2" @@ -6419,9 +9105,10 @@ (const_int 6) (const_int 7)]))))] "TARGET_SSE4_1" - "pmovsxbw\t{%1, %0|%0, %1}" + "%vpmovsxbw\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv4qiv4si2" @@ -6434,9 +9121,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovsxbd\t{%1, %0|%0, %1}" + "%vpmovsxbd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv4qiv4si2" @@ -6450,9 +9138,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovsxbd\t{%1, %0|%0, %1}" + "%vpmovsxbd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv2qiv2di2" @@ -6463,9 +9152,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxbq\t{%1, %0|%0, %1}" + "%vpmovsxbq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv2qiv2di2" @@ -6477,9 +9167,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxbq\t{%1, %0|%0, %1}" + "%vpmovsxbq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv4hiv4si2" @@ -6492,9 +9183,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovsxwd\t{%1, %0|%0, %1}" + "%vpmovsxwd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv4hiv4si2" @@ -6508,9 +9200,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovsxwd\t{%1, %0|%0, %1}" + "%vpmovsxwd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv2hiv2di2" @@ -6521,9 +9214,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxwq\t{%1, %0|%0, %1}" + "%vpmovsxwq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv2hiv2di2" @@ -6535,9 +9229,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxwq\t{%1, %0|%0, %1}" + "%vpmovsxwq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_extendv2siv2di2" @@ -6548,9 +9243,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxdq\t{%1, %0|%0, %1}" + "%vpmovsxdq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_extendv2siv2di2" @@ -6562,9 +9258,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovsxdq\t{%1, %0|%0, %1}" + "%vpmovsxdq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv8qiv8hi2" @@ -6581,9 +9278,10 @@ (const_int 6) (const_int 7)]))))] "TARGET_SSE4_1" - "pmovzxbw\t{%1, %0|%0, %1}" + "%vpmovzxbw\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv8qiv8hi2" @@ -6601,9 +9299,10 @@ (const_int 6) (const_int 7)]))))] "TARGET_SSE4_1" - "pmovzxbw\t{%1, %0|%0, %1}" + "%vpmovzxbw\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv4qiv4si2" @@ -6616,9 +9315,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovzxbd\t{%1, %0|%0, %1}" + "%vpmovzxbd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv4qiv4si2" @@ -6632,9 +9332,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovzxbd\t{%1, %0|%0, %1}" + "%vpmovzxbd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv2qiv2di2" @@ -6645,9 +9346,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxbq\t{%1, %0|%0, %1}" + "%vpmovzxbq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv2qiv2di2" @@ -6659,9 +9361,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxbq\t{%1, %0|%0, %1}" + "%vpmovzxbq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv4hiv4si2" @@ -6674,9 +9377,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovzxwd\t{%1, %0|%0, %1}" + "%vpmovzxwd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv4hiv4si2" @@ -6690,9 +9394,10 @@ (const_int 2) (const_int 3)]))))] "TARGET_SSE4_1" - "pmovzxwd\t{%1, %0|%0, %1}" + "%vpmovzxwd\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv2hiv2di2" @@ -6703,9 +9408,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxwq\t{%1, %0|%0, %1}" + "%vpmovzxwq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv2hiv2di2" @@ -6717,9 +9423,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxwq\t{%1, %0|%0, %1}" + "%vpmovzxwq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_zero_extendv2siv2di2" @@ -6730,9 +9437,10 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxdq\t{%1, %0|%0, %1}" + "%vpmovzxdq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_zero_extendv2siv2di2" @@ -6744,24 +9452,62 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE4_1" - "pmovzxdq\t{%1, %0|%0, %1}" + "%vpmovzxdq\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) +;; ptestps/ptestpd are very similar to comiss and ucomiss when +;; setting FLAGS_REG. But it is not a really compare instruction. +(define_insn "avx_vtestp" + [(set (reg:CC FLAGS_REG) + (unspec:CC [(match_operand:AVXMODEF2P 0 "register_operand" "x") + (match_operand:AVXMODEF2P 1 "nonimmediate_operand" "xm")] + UNSPEC_VTESTP))] + "TARGET_AVX" + "vtestp\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecomi") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + ;; ptest is very similar to comiss and ucomiss when setting FLAGS_REG. ;; But it is not a really compare instruction. +(define_insn "avx_ptest256" + [(set (reg:CC FLAGS_REG) + (unspec:CC [(match_operand:V4DI 0 "register_operand" "x") + (match_operand:V4DI 1 "nonimmediate_operand" "xm")] + UNSPEC_PTEST))] + "TARGET_AVX" + "vptest\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecomi") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + (define_insn "sse4_1_ptest" [(set (reg:CC FLAGS_REG) (unspec:CC [(match_operand:V2DI 0 "register_operand" "x") (match_operand:V2DI 1 "nonimmediate_operand" "xm")] UNSPEC_PTEST))] "TARGET_SSE4_1" - "ptest\t{%1, %0|%0, %1}" + "%vptest\t{%1, %0|%0, %1}" [(set_attr "type" "ssecomi") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) +(define_insn "avx_roundp256" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x") + (unspec:AVX256MODEF2P + [(match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "xm") + (match_operand:SI 2 "const_0_to_15_operand" "n")] + UNSPEC_ROUND))] + "TARGET_AVX" + "vroundp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse4_1_roundp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P @@ -6769,9 +9515,25 @@ (match_operand:SI 2 "const_0_to_15_operand" "n")] UNSPEC_ROUND))] "TARGET_ROUND" - "roundp\t{%2, %1, %0|%0, %1, %2}" + "%vroundp\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "ssecvt") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "")]) + +(define_insn "*avx_rounds" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (unspec:SSEMODEF2P + [(match_operand:SSEMODEF2P 2 "register_operand" "x") + (match_operand:SI 3 "const_0_to_15_operand" "n")] + UNSPEC_ROUND) + (match_operand:SSEMODEF2P 1 "register_operand" "x") + (const_int 1)))] + "TARGET_AVX" + "vrounds\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssecvt") + (set_attr "prefix" "vex") (set_attr "mode" "")]) (define_insn "sse4_1_rounds" @@ -6869,10 +9631,11 @@ (match_dup 5)] UNSPEC_PCMPESTR))] "TARGET_SSE4_2" - "pcmpestri\t{%5, %3, %1|%1, %3, %5}" + "%vpcmpestri\t{%5, %3, %1|%1, %3, %5}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6894,10 +9657,11 @@ (match_dup 5)] UNSPEC_PCMPESTR))] "TARGET_SSE4_2" - "pcmpestrm\t{%5, %3, %1|%1, %3, %5}" + "%vpcmpestrm\t{%5, %3, %1|%1, %3, %5}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6914,14 +9678,15 @@ (clobber (match_scratch:SI 1 "= X, X,c,c"))] "TARGET_SSE4_2" "@ - pcmpestrm\t{%6, %4, %2|%2, %4, %6} - pcmpestrm\t{%6, %4, %2|%2, %4, %6} - pcmpestri\t{%6, %4, %2|%2, %4, %6} - pcmpestri\t{%6, %4, %2|%2, %4, %6}" + %vpcmpestrm\t{%6, %4, %2|%2, %4, %6} + %vpcmpestrm\t{%6, %4, %2|%2, %4, %6} + %vpcmpestri\t{%6, %4, %2|%2, %4, %6} + %vpcmpestri\t{%6, %4, %2|%2, %4, %6}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "memory" "none,load,none,load") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn_and_split "sse4_2_pcmpistr" @@ -6985,10 +9750,11 @@ (match_dup 3)] UNSPEC_PCMPISTR))] "TARGET_SSE4_2" - "pcmpistri\t{%3, %2, %1|%1, %2, %3}" + "%vpcmpistri\t{%3, %2, %1|%1, %2, %3}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -7006,10 +9772,11 @@ (match_dup 3)] UNSPEC_PCMPISTR))] "TARGET_SSE4_2" - "pcmpistrm\t{%3, %2, %1|%1, %2, %3}" + "%vpcmpistrm\t{%3, %2, %1|%1, %2, %3}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -7024,14 +9791,15 @@ (clobber (match_scratch:SI 1 "= X, X,c,c"))] "TARGET_SSE4_2" "@ - pcmpistrm\t{%4, %3, %2|%2, %3, %4} - pcmpistrm\t{%4, %3, %2|%2, %3, %4} - pcmpistri\t{%4, %3, %2|%2, %3, %4} - pcmpistri\t{%4, %3, %2|%2, %3, %4}" + %vpcmpistrm\t{%4, %3, %2|%2, %3, %4} + %vpcmpistrm\t{%4, %3, %2|%2, %3, %4} + %vpcmpistri\t{%4, %3, %2|%2, %3, %4} + %vpcmpistri\t{%4, %3, %2|%2, %3, %4}" [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "memory" "none,load,none,load") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -7049,10 +9817,10 @@ [(set (match_operand:V8HI 0 "register_operand" "=x,x,x") (plus:V8HI (mult:V8HI - (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") - (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")) - (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)" + (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,xm") + (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,x")) + (match_operand:V8HI 3 "register_operand" "0,0,0")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)" "@ pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7068,8 +9836,8 @@ (match_operand:V8HI 2 "nonimmediate_operand" "")) (match_operand:V8HI 3 "nonimmediate_operand" "")))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, false, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true) + && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -7086,8 +9854,8 @@ (ss_plus:V8HI (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")) - (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + (match_operand:V8HI 3 "register_operand" "0,0,0")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7105,8 +9873,8 @@ (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")) - (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)" + (match_operand:V4SI 3 "register_operand" "0,0,0")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)" "@ pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7122,8 +9890,8 @@ (match_operand:V4SI 2 "nonimmediate_operand" "")) (match_operand:V4SI 3 "nonimmediate_operand" "")))] "TARGET_SSE5 - && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1) - && ix86_sse5_valid_op_p (operands, insn, 4, false, 2) + && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true) + && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true) && !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[2]) && !reg_mentioned_p (operands[0], operands[3])" @@ -7140,8 +9908,8 @@ (ss_plus:V4SI (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")) - (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + (match_operand:V4SI 3 "register_operand" "0,0,0")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7155,7 +9923,7 @@ (mult:V2DI (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 1) (const_int 3)]))) (vec_select:V2SI @@ -7163,7 +9931,7 @@ (parallel [(const_int 1) (const_int 3)]))) (match_operand:V2DI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7177,7 +9945,7 @@ (mult:V2DI (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 0) (const_int 2)]))) (sign_extend:V2DI @@ -7186,7 +9954,7 @@ (parallel [(const_int 0) (const_int 2)])))) (match_operand:V2DI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7200,7 +9968,7 @@ (mult:V2DI (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 1) (const_int 3)]))) (sign_extend:V2DI @@ -7209,7 +9977,7 @@ (parallel [(const_int 1) (const_int 3)])))) (match_operand:V2DI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7217,13 +9985,94 @@ [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) +(define_insn_and_split "*sse5_pmacsdql_mem" + [(set (match_operand:V2DI 0 "register_operand" "=&x,&x,&x") + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") + (parallel [(const_int 1) + (const_int 3)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") + (parallel [(const_int 1) + (const_int 3)])))) + (match_operand:V2DI 3 "memory_operand" "m,m,m")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)" + "#" + "&& (reload_completed + || (!reg_mentioned_p (operands[0], operands[1]) + && !reg_mentioned_p (operands[0], operands[2])))" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 0) + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 1) + (parallel [(const_int 1) + (const_int 3)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 2) + (parallel [(const_int 1) + (const_int 3)])))) + (match_dup 0)))]) + +;; We don't have a straight 32-bit parallel multiply and extend on SSE5, so +;; fake it with a multiply/add. In general, we expect the define_split to +;; occur before register allocation, so we have to handle the corner case where +;; the target is the same as operands 1/2 +(define_insn_and_split "sse5_mulv2div2di3_low" + [(set (match_operand:V2DI 0 "register_operand" "=&x") + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x") + (parallel [(const_int 1) + (const_int 3)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 1) + (const_int 3)])))))] + "TARGET_SSE5" + "#" + "&& (reload_completed + || (!reg_mentioned_p (operands[0], operands[1]) + && !reg_mentioned_p (operands[0], operands[2])))" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 0) + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 1) + (parallel [(const_int 1) + (const_int 3)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 2) + (parallel [(const_int 1) + (const_int 3)])))) + (match_dup 0)))] +{ + operands[3] = CONST0_RTX (V2DImode); +} + [(set_attr "type" "ssemuladd") + (set_attr "mode" "TI")]) + (define_insn "sse5_pmacsdqh" [(set (match_operand:V2DI 0 "register_operand" "=x,x,x") (plus:V2DI (mult:V2DI (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 0) (const_int 2)]))) (sign_extend:V2DI @@ -7232,7 +10081,7 @@ (parallel [(const_int 0) (const_int 2)])))) (match_operand:V2DI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7240,6 +10089,87 @@ [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) +(define_insn_and_split "*sse5_pmacsdqh_mem" + [(set (match_operand:V2DI 0 "register_operand" "=&x,&x,&x") + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m") + (parallel [(const_int 0) + (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") + (parallel [(const_int 0) + (const_int 2)])))) + (match_operand:V2DI 3 "memory_operand" "m,m,m")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)" + "#" + "&& (reload_completed + || (!reg_mentioned_p (operands[0], operands[1]) + && !reg_mentioned_p (operands[0], operands[2])))" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 0) + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 1) + (parallel [(const_int 0) + (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 2) + (parallel [(const_int 0) + (const_int 2)])))) + (match_dup 0)))]) + +;; We don't have a straight 32-bit parallel multiply and extend on SSE5, so +;; fake it with a multiply/add. In general, we expect the define_split to +;; occur before register allocation, so we have to handle the corner case where +;; the target is the same as either operands[1] or operands[2] +(define_insn_and_split "sse5_mulv2div2di3_high" + [(set (match_operand:V2DI 0 "register_operand" "=&x") + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x") + (parallel [(const_int 0) + (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm") + (parallel [(const_int 0) + (const_int 2)])))))] + "TARGET_SSE5" + "#" + "&& (reload_completed + || (!reg_mentioned_p (operands[0], operands[1]) + && !reg_mentioned_p (operands[0], operands[2])))" + [(set (match_dup 0) + (match_dup 3)) + (set (match_dup 0) + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 1) + (parallel [(const_int 0) + (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_dup 2) + (parallel [(const_int 0) + (const_int 2)])))) + (match_dup 0)))] +{ + operands[3] = CONST0_RTX (V2DImode); +} + [(set_attr "type" "ssemuladd") + (set_attr "mode" "TI")]) + ;; SSE5 parallel integer multiply/add instructions for the intrinisics (define_insn "sse5_pmacsswd" [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") @@ -7247,7 +10177,7 @@ (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 1) (const_int 3) (const_int 5) @@ -7260,7 +10190,7 @@ (const_int 5) (const_int 7)])))) (match_operand:V4SI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7274,7 +10204,7 @@ (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 1) (const_int 3) (const_int 5) @@ -7287,7 +10217,7 @@ (const_int 5) (const_int 7)])))) (match_operand:V4SI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7302,7 +10232,7 @@ (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -7330,7 +10260,7 @@ (const_int 5) (const_int 7)]))))) (match_operand:V4SI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7345,7 +10275,7 @@ (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -7373,7 +10303,7 @@ (const_int 5) (const_int 7)]))))) (match_operand:V4SI 3 "register_operand" "0,0,0")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)" "@ pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3} pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3} @@ -7383,19 +10313,17 @@ ;; SSE5 parallel XMM conditional moves (define_insn "sse5_pcmov_" - [(set (match_operand:SSEMODE 0 "register_operand" "=x,x,x,x,x,x") + [(set (match_operand:SSEMODE 0 "register_operand" "=x,x,x,x") (if_then_else:SSEMODE - (match_operand:SSEMODE 3 "nonimmediate_operand" "0,0,xm,x,0,0") - (match_operand:SSEMODE 1 "vector_move_operand" "x,xm,0,0,C,x") - (match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x,xm,x,C")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + (match_operand:SSEMODE 3 "nonimmediate_operand" "0,0,xm,x") + (match_operand:SSEMODE 1 "vector_move_operand" "x,xm,0,0") + (match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x,xm")))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "@ pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3} pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3} pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3} - pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3} - andps\t{%2, %0|%0, %2} - andnps\t{%1, %0|%0, %1}" + pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg")]) ;; SSE5 horizontal add/subtract instructions @@ -7846,7 +10774,7 @@ (match_operand:V16QI 2 "nonimmediate_operand" "x,xm,xm,x") (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")] UNSPEC_SSE5_PERMUTE))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) @@ -7949,7 +10877,7 @@ (truncate:V2SI (match_operand:V2DI 2 "nonimmediate_operand" "x,xm,xm,x")))) (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) @@ -7962,7 +10890,7 @@ (truncate:V4HI (match_operand:V4SI 2 "nonimmediate_operand" "x,xm,xm,x")))) (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) @@ -7975,7 +10903,7 @@ (truncate:V8QI (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,xm,x")))) (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) @@ -7988,13 +10916,77 @@ (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x") (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")] UNSPEC_SSE5_PERMUTE))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" "perm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "")]) ;; SSE5 packed rotate instructions -(define_insn "rotl3" +(define_expand "rotl3" + [(set (match_operand:SSEMODE1248 0 "register_operand" "") + (rotate:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand")))] + "TARGET_SSE5" +{ + /* If we were given a scalar, convert it to parallel */ + if (! const_0_to__operand (operands[2], SImode)) + { + rtvec vs = rtvec_alloc (); + rtx par = gen_rtx_PARALLEL (mode, vs); + rtx reg = gen_reg_rtx (mode); + rtx op2 = operands[2]; + int i; + + if (GET_MODE (op2) != mode) + { + op2 = gen_reg_rtx (mode); + convert_move (op2, operands[2], false); + } + + for (i = 0; i < ; i++) + RTVEC_ELT (vs, i) = op2; + + emit_insn (gen_vec_init (reg, par)); + emit_insn (gen_sse5_vrotl3 (operands[0], operands[1], reg)); + DONE; + } +}) + +(define_expand "rotr3" + [(set (match_operand:SSEMODE1248 0 "register_operand" "") + (rotatert:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand")))] + "TARGET_SSE5" +{ + /* If we were given a scalar, convert it to parallel */ + if (! const_0_to__operand (operands[2], SImode)) + { + rtvec vs = rtvec_alloc (); + rtx par = gen_rtx_PARALLEL (mode, vs); + rtx neg = gen_reg_rtx (mode); + rtx reg = gen_reg_rtx (mode); + rtx op2 = operands[2]; + int i; + + if (GET_MODE (op2) != mode) + { + op2 = gen_reg_rtx (mode); + convert_move (op2, operands[2], false); + } + + for (i = 0; i < ; i++) + RTVEC_ELT (vs, i) = op2; + + emit_insn (gen_vec_init (reg, par)); + emit_insn (gen_neg2 (neg, reg)); + emit_insn (gen_sse5_vrotl3 (operands[0], operands[1], neg)); + DONE; + } +}) + +(define_insn "sse5_rotl3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (rotate:SSEMODE1248 (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm") @@ -8004,42 +10996,229 @@ [(set_attr "type" "sseishft") (set_attr "mode" "TI")]) -(define_insn "sse5_rotl3" +(define_insn "sse5_rotr3" + [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") + (rotatert:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm") + (match_operand:SI 2 "const_0_to__operand" "n")))] + "TARGET_SSE5" +{ + operands[3] = GEN_INT (( * 8) - INTVAL (operands[2])); + return \"prot\t{%3, %1, %0|%0, %1, %3}\"; +} + [(set_attr "type" "sseishft") + (set_attr "mode" "TI")]) + +(define_expand "vrotr3" + [(match_operand:SSEMODE1248 0 "register_operand" "") + (match_operand:SSEMODE1248 1 "register_operand" "") + (match_operand:SSEMODE1248 2 "register_operand" "")] + "TARGET_SSE5" +{ + rtx reg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (reg, operands[2])); + emit_insn (gen_sse5_vrotl3 (operands[0], operands[1], reg)); + DONE; +}) + +(define_expand "vrotl3" + [(match_operand:SSEMODE1248 0 "register_operand" "") + (match_operand:SSEMODE1248 1 "register_operand" "") + (match_operand:SSEMODE1248 2 "register_operand" "")] + "TARGET_SSE5" +{ + emit_insn (gen_sse5_vrotl3 (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "sse5_vrotl3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x") - (rotate:SSEMODE1248 - (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") - (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x") + (const_int 0)) + (rotate:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") + (match_dup 2)) + (rotatert:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)" "prot\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") (set_attr "mode" "TI")]) -;; SSE5 packed shift instructions. Note negative values for the shift amount -;; convert this into a right shift instead of left shift. For now, model this -;; with an UNSPEC instead of using ashift/lshift since the rest of the x86 does -;; not have the concept of negating the shift amount. Also, there is no LSHIFT +;; SSE5 packed shift instructions. +;; FIXME: add V2DI back in +(define_expand "vlshr3" + [(match_operand:SSEMODE124 0 "register_operand" "") + (match_operand:SSEMODE124 1 "register_operand" "") + (match_operand:SSEMODE124 2 "register_operand" "")] + "TARGET_SSE5" +{ + rtx neg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (neg, operands[2])); + emit_insn (gen_sse5_lshl3 (operands[0], operands[1], neg)); + DONE; +}) + +(define_expand "vashr3" + [(match_operand:SSEMODE124 0 "register_operand" "") + (match_operand:SSEMODE124 1 "register_operand" "") + (match_operand:SSEMODE124 2 "register_operand" "")] + "TARGET_SSE5" +{ + rtx neg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (neg, operands[2])); + emit_insn (gen_sse5_ashl3 (operands[0], operands[1], neg)); + DONE; +}) + +(define_expand "vashl3" + [(match_operand:SSEMODE124 0 "register_operand" "") + (match_operand:SSEMODE124 1 "register_operand" "") + (match_operand:SSEMODE124 2 "register_operand" "")] + "TARGET_SSE5" +{ + emit_insn (gen_sse5_ashl3 (operands[0], operands[1], operands[2])); + DONE; +}) + (define_insn "sse5_ashl3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x") - (unspec:SSEMODE1248 - [(match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") - (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")] - UNSPEC_SSE5_ASHIFT))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x") + (const_int 0)) + (ashift:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") + (match_dup 2)) + (ashiftrt:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)" "psha\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") (set_attr "mode" "TI")]) (define_insn "sse5_lshl3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x,x") - (unspec:SSEMODE1248 - [(match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") - (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x")] - UNSPEC_SSE5_LSHIFT))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm,x") + (const_int 0)) + (ashift:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "x,xm") + (match_dup 2)) + (lshiftrt:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)" "pshl\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") (set_attr "mode" "TI")]) +;; SSE2 doesn't have some shift varients, so define versions for SSE5 +(define_expand "ashlv16qi3" + [(match_operand:V16QI 0 "register_operand" "") + (match_operand:V16QI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")] + "TARGET_SSE5" +{ + rtvec vs = rtvec_alloc (16); + rtx par = gen_rtx_PARALLEL (V16QImode, vs); + rtx reg = gen_reg_rtx (V16QImode); + int i; + for (i = 0; i < 16; i++) + RTVEC_ELT (vs, i) = operands[2]; + + emit_insn (gen_vec_initv16qi (reg, par)); + emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], reg)); + DONE; +}) + +(define_expand "lshlv16qi3" + [(match_operand:V16QI 0 "register_operand" "") + (match_operand:V16QI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")] + "TARGET_SSE5" +{ + rtvec vs = rtvec_alloc (16); + rtx par = gen_rtx_PARALLEL (V16QImode, vs); + rtx reg = gen_reg_rtx (V16QImode); + int i; + for (i = 0; i < 16; i++) + RTVEC_ELT (vs, i) = operands[2]; + + emit_insn (gen_vec_initv16qi (reg, par)); + emit_insn (gen_sse5_lshlv16qi3 (operands[0], operands[1], reg)); + DONE; +}) + +(define_expand "ashrv16qi3" + [(match_operand:V16QI 0 "register_operand" "") + (match_operand:V16QI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")] + "TARGET_SSE5" +{ + rtvec vs = rtvec_alloc (16); + rtx par = gen_rtx_PARALLEL (V16QImode, vs); + rtx reg = gen_reg_rtx (V16QImode); + int i; + rtx ele = ((GET_CODE (operands[2]) == CONST_INT) + ? GEN_INT (- INTVAL (operands[2])) + : operands[2]); + + for (i = 0; i < 16; i++) + RTVEC_ELT (vs, i) = ele; + + emit_insn (gen_vec_initv16qi (reg, par)); + + if (GET_CODE (operands[2]) != CONST_INT) + { + rtx neg = gen_reg_rtx (V16QImode); + emit_insn (gen_negv16qi2 (neg, reg)); + emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], neg)); + } + else + emit_insn (gen_sse5_ashlv16qi3 (operands[0], operands[1], reg)); + + DONE; +}) + +(define_expand "ashrv2di3" + [(match_operand:V2DI 0 "register_operand" "") + (match_operand:V2DI 1 "register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")] + "TARGET_SSE5" +{ + rtvec vs = rtvec_alloc (2); + rtx par = gen_rtx_PARALLEL (V2DImode, vs); + rtx reg = gen_reg_rtx (V2DImode); + rtx ele; + + if (GET_CODE (operands[2]) == CONST_INT) + ele = GEN_INT (- INTVAL (operands[2])); + else if (GET_MODE (operands[2]) != DImode) + { + rtx move = gen_reg_rtx (DImode); + ele = gen_reg_rtx (DImode); + convert_move (move, operands[2], false); + emit_insn (gen_negdi2 (ele, move)); + } + else + { + ele = gen_reg_rtx (DImode); + emit_insn (gen_negdi2 (ele, operands[2])); + } + + RTVEC_ELT (vs, 0) = ele; + RTVEC_ELT (vs, 1) = ele; + emit_insn (gen_vec_initv2di (reg, par)); + emit_insn (gen_sse5_ashlv2di3 (operands[0], operands[1], reg)); + DONE; +}) + ;; SSE5 FRCZ support ;; parallel insns (define_insn "sse5_frcz2" @@ -8218,3 +11397,572 @@ } [(set_attr "type" "ssecmp") (set_attr "mode" "TI")]) + +(define_insn "*avx_aesenc" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESENC))] + "TARGET_AES && TARGET_AVX" + "vaesenc\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "aesenc" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESENC))] + "TARGET_AES" + "aesenc\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_aesenclast" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESENCLAST))] + "TARGET_AES && TARGET_AVX" + "vaesenclast\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "aesenclast" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESENCLAST))] + "TARGET_AES" + "aesenclast\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_aesdec" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESDEC))] + "TARGET_AES && TARGET_AVX" + "vaesdec\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "aesdec" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESDEC))] + "TARGET_AES" + "aesdec\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_insn "*avx_aesdeclast" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESDECLAST))] + "TARGET_AES && TARGET_AVX" + "vaesdeclast\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "aesdeclast" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm")] + UNSPEC_AESDECLAST))] + "TARGET_AES" + "aesdeclast\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_insn "aesimc" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm")] + UNSPEC_AESIMC))] + "TARGET_AES" + "%vaesimc\t{%1, %0|%0, %1}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "aeskeygenassist" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "nonimmediate_operand" "xm") + (match_operand:SI 2 "const_0_to_255_operand" "n")] + UNSPEC_AESKEYGENASSIST))] + "TARGET_AES" + "%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "pclmulqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") + (match_operand:V2DI 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_PCLMUL))] + "TARGET_PCLMUL" + "pclmulqdq\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "mode" "TI")]) + +(define_expand "avx_vzeroall" + [(match_par_dup 0 [(const_int 0)])] + "TARGET_AVX" +{ + int nregs = TARGET_64BIT ? 16 : 8; + int regno; + + operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1)); + + XVECEXP (operands[0], 0, 0) + = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx), + UNSPECV_VZEROALL); + + for (regno = 0; regno < nregs; regno++) + XVECEXP (operands[0], 0, regno + 1) + = gen_rtx_SET (VOIDmode, + gen_rtx_REG (V8SImode, SSE_REGNO (regno)), + CONST0_RTX (V8SImode)); +}) + +(define_insn "*avx_vzeroall" + [(match_parallel 0 "vzeroall_operation" + [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL) + (set (match_operand 1 "register_operand" "=x") + (match_operand 2 "const0_operand" "X"))])] + "TARGET_AVX" + "vzeroall" + [(set_attr "type" "sse") + (set_attr "memory" "none") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + +;; vzeroupper clobbers the upper 128bits of AVX registers. +(define_insn "avx_vzeroupper" + [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER) + (clobber (reg:V8SI XMM0_REG)) + (clobber (reg:V8SI XMM1_REG)) + (clobber (reg:V8SI XMM2_REG)) + (clobber (reg:V8SI XMM3_REG)) + (clobber (reg:V8SI XMM4_REG)) + (clobber (reg:V8SI XMM5_REG)) + (clobber (reg:V8SI XMM6_REG)) + (clobber (reg:V8SI XMM7_REG))] + "TARGET_AVX && !TARGET_64BIT" + "vzeroupper" + [(set_attr "type" "sse") + (set_attr "memory" "none") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + +(define_insn "avx_vzeroupper_rex64" + [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER) + (clobber (reg:V8SI XMM0_REG)) + (clobber (reg:V8SI XMM1_REG)) + (clobber (reg:V8SI XMM2_REG)) + (clobber (reg:V8SI XMM3_REG)) + (clobber (reg:V8SI XMM4_REG)) + (clobber (reg:V8SI XMM5_REG)) + (clobber (reg:V8SI XMM6_REG)) + (clobber (reg:V8SI XMM7_REG)) + (clobber (reg:V8SI XMM8_REG)) + (clobber (reg:V8SI XMM9_REG)) + (clobber (reg:V8SI XMM10_REG)) + (clobber (reg:V8SI XMM11_REG)) + (clobber (reg:V8SI XMM12_REG)) + (clobber (reg:V8SI XMM13_REG)) + (clobber (reg:V8SI XMM14_REG)) + (clobber (reg:V8SI XMM15_REG))] + "TARGET_AVX && TARGET_64BIT" + "vzeroupper" + [(set_attr "type" "sse") + (set_attr "memory" "none") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) + +(define_insn "avx_vpermil" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "xm") + (match_operand:SI 2 "const_0_to__operand" "n")] + UNSPEC_VPERMIL))] + "TARGET_AVX" + "vpermilp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_vpermilvar3" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand: 2 "nonimmediate_operand" "xm")] + UNSPEC_VPERMIL))] + "TARGET_AVX" + "vpermilp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_vperm2f1283" + [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x") + (unspec:AVX256MODE2P + [(match_operand:AVX256MODE2P 1 "register_operand" "x") + (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_VPERMIL2F128))] + "TARGET_AVX" + "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "avx_vbroadcasts" + [(set (match_operand:AVXMODEF4P 0 "register_operand" "=x") + (vec_concat:AVXMODEF4P + (vec_concat: + (match_operand: 1 "memory_operand" "m") + (match_dup 1)) + (vec_concat: + (match_dup 1) + (match_dup 1))))] + "TARGET_AVX" + "vbroadcasts\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_vbroadcastss256" + [(set (match_operand:V8SF 0 "register_operand" "=x") + (vec_concat:V8SF + (vec_concat:V4SF + (vec_concat:V2SF + (match_operand:SF 1 "memory_operand" "m") + (match_dup 1)) + (vec_concat:V2SF + (match_dup 1) + (match_dup 1))) + (vec_concat:V4SF + (vec_concat:V2SF + (match_dup 1) + (match_dup 1)) + (vec_concat:V2SF + (match_dup 1) + (match_dup 1)))))] + "TARGET_AVX" + "vbroadcastss\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + +(define_insn "avx_vbroadcastf128_p256" + [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x") + (vec_concat:AVX256MODEF2P + (match_operand: 1 "memory_operand" "m") + (match_dup 1)))] + "TARGET_AVX" + "vbroadcastf128\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + +(define_expand "avx_vinsertf128" + [(match_operand:AVX256MODE 0 "register_operand" "") + (match_operand:AVX256MODE 1 "register_operand" "") + (match_operand: 2 "nonimmediate_operand" "") + (match_operand:SI 3 "const_0_to_1_operand" "")] + "TARGET_AVX" +{ + switch (INTVAL (operands[3])) + { + case 0: + emit_insn (gen_vec_set_lo_ (operands[0], operands[1], + operands[2])); + break; + case 1: + emit_insn (gen_vec_set_hi_ (operands[0], operands[1], + operands[2])); + break; + default: + gcc_unreachable (); + } + DONE; +}) + +(define_insn "vec_set_lo_" + [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x") + (vec_concat:AVX256MODE4P + (match_operand: 2 "nonimmediate_operand" "xm") + (vec_select: + (match_operand:AVX256MODE4P 1 "register_operand" "x") + (parallel [(const_int 2) (const_int 3)]))))] + "TARGET_AVX" + "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_hi_" + [(set (match_operand:AVX256MODE4P 0 "register_operand" "=x") + (vec_concat:AVX256MODE4P + (vec_select: + (match_operand:AVX256MODE4P 1 "register_operand" "x") + (parallel [(const_int 0) (const_int 1)])) + (match_operand: 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_lo_" + [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x") + (vec_concat:AVX256MODE8P + (match_operand: 2 "nonimmediate_operand" "xm") + (vec_select: + (match_operand:AVX256MODE8P 1 "register_operand" "x") + (parallel [(const_int 4) (const_int 5) + (const_int 6) (const_int 7)]))))] + "TARGET_AVX" + "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_hi_" + [(set (match_operand:AVX256MODE8P 0 "register_operand" "=x") + (vec_concat:AVX256MODE8P + (vec_select: + (match_operand:AVX256MODE8P 1 "register_operand" "x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3)])) + (match_operand: 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_lo_v16hi" + [(set (match_operand:V16HI 0 "register_operand" "=x") + (vec_concat:V16HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm") + (vec_select:V8HI + (match_operand:V16HI 1 "register_operand" "x") + (parallel [(const_int 8) (const_int 9) + (const_int 10) (const_int 11) + (const_int 12) (const_int 13) + (const_int 14) (const_int 15)]))))] + "TARGET_AVX" + "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_hi_v16hi" + [(set (match_operand:V16HI 0 "register_operand" "=x") + (vec_concat:V16HI + (vec_select:V8HI + (match_operand:V16HI 1 "register_operand" "x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3) + (const_int 4) (const_int 5) + (const_int 6) (const_int 7)])) + (match_operand:V8HI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_lo_v32qi" + [(set (match_operand:V32QI 0 "register_operand" "=x") + (vec_concat:V32QI + (match_operand:V16QI 2 "nonimmediate_operand" "xm") + (vec_select:V16QI + (match_operand:V32QI 1 "register_operand" "x") + (parallel [(const_int 16) (const_int 17) + (const_int 18) (const_int 19) + (const_int 20) (const_int 21) + (const_int 22) (const_int 23) + (const_int 24) (const_int 25) + (const_int 26) (const_int 27) + (const_int 28) (const_int 29) + (const_int 30) (const_int 31)]))))] + "TARGET_AVX" + "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "vec_set_hi_v32qi" + [(set (match_operand:V32QI 0 "register_operand" "=x") + (vec_concat:V32QI + (vec_select:V16QI + (match_operand:V32QI 1 "register_operand" "x") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3) + (const_int 4) (const_int 5) + (const_int 6) (const_int 7) + (const_int 8) (const_int 9) + (const_int 10) (const_int 11) + (const_int 12) (const_int 13) + (const_int 14) (const_int 15)])) + (match_operand:V16QI 2 "nonimmediate_operand" "xm")))] + "TARGET_AVX" + "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}" + [(set_attr "type" "sselog") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + +(define_insn "avx_maskloadp" + [(set (match_operand:AVXMODEF2P 0 "register_operand" "=x") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "memory_operand" "m") + (match_operand:AVXMODEF2P 2 "register_operand" "x") + (match_dup 0)] + UNSPEC_MASKLOAD))] + "TARGET_AVX" + "vmaskmovp\t{%1, %2, %0|%0, %2, %1}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx_maskstorep" + [(set (match_operand:AVXMODEF2P 0 "memory_operand" "=m") + (unspec:AVXMODEF2P + [(match_operand:AVXMODEF2P 1 "register_operand" "x") + (match_operand:AVXMODEF2P 2 "register_operand" "x") + (match_dup 0)] + UNSPEC_MASKSTORE))] + "TARGET_AVX" + "vmaskmovp\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sselog1") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "avx__" + [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x,x") + (unspec:AVX256MODE2P + [(match_operand: 1 "nonimmediate_operand" "0,xm")] + UNSPEC_CAST))] + "TARGET_AVX" +{ + switch (which_alternative) + { + case 0: + return ""; + case 1: + switch (get_attr_mode (insn)) + { + case MODE_V8SF: + return "vmovaps\t{%1, %x0|%x0, %1}"; + case MODE_V4DF: + return "vmovapd\t{%1, %x0|%x0, %1}"; + case MODE_OI: + return "vmovdqa\t{%1, %x0|%x0, %1}"; + default: + break; + } + default: + break; + } + gcc_unreachable (); +} + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "") + (set (attr "length") + (if_then_else (eq_attr "alternative" "0") + (const_string "0") + (const_string "*")))]) + +(define_insn "avx__" + [(set (match_operand: 0 "register_operand" "=x,x") + (unspec: + [(match_operand:AVX256MODE2P 1 "nonimmediate_operand" "0,xm")] + UNSPEC_CAST))] + "TARGET_AVX" +{ + switch (which_alternative) + { + case 0: + return ""; + case 1: + switch (get_attr_mode (insn)) + { + case MODE_V8SF: + return "vmovaps\t{%x1, %0|%0, %x1}"; + case MODE_V4DF: + return "vmovapd\t{%x1, %0|%0, %x1}"; + case MODE_OI: + return "vmovdqa\t{%x1, %0|%0, %x1}"; + default: + break; + } + default: + break; + } + gcc_unreachable (); +} + [(set_attr "type" "ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "") + (set (attr "length") + (if_then_else (eq_attr "alternative" "0") + (const_string "0") + (const_string "*")))]) + +(define_expand "vec_init" + [(match_operand:AVX256MODE 0 "register_operand" "") + (match_operand 1 "" "")] + "TARGET_AVX" +{ + ix86_expand_vector_init (false, operands[0], operands[1]); + DONE; +}) + +(define_insn "*vec_concat_avx" + [(set (match_operand:AVX256MODE 0 "register_operand" "=x,x") + (vec_concat:AVX256MODE + (match_operand: 1 "register_operand" "x,x") + (match_operand: 2 "vector_move_operand" "xm,C")))] + "TARGET_AVX" +{ + switch (which_alternative) + { + case 0: + return "vinsertf128\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}"; + case 1: + switch (get_attr_mode (insn)) + { + case MODE_V8SF: + return "vmovaps\t{%1, %x0|%x0, %1}"; + case MODE_V4DF: + return "vmovapd\t{%1, %x0|%x0, %1}"; + default: + return "vmovdqa\t{%1, %x0|%x0, %1}"; + } + default: + gcc_unreachable (); + } +} + [(set_attr "type" "sselog,ssemov") + (set_attr "prefix" "vex") + (set_attr "mode" "")])