X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fsse.md;h=9a87cb1f4f944fe502389104057cc5e0b1b81a1c;hb=49fce50b2ea8ff83917581815b997870ee2cb706;hp=e1f316b216d53b3737a1a30decc913b4b45ec458;hpb=9409fce72257b07420763ff6bfe2f47b05712833;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index e1f316b216d..9a87cb1f4f9 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]) @@ -34,27 +49,97 @@ (define_mode_iterator SSEMODE248 [V8HI V4SI V2DI]) (define_mode_iterator SSEMODE1248 [V16QI V8HI V4SI V2DI]) (define_mode_iterator SSEMODEF4 [SF DF V4SF V2DF]) +(define_mode_iterator FMA4MODEF4 [V8SF V4DF]) (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]) + +;; Modes handled by integer vcond pattern +(define_mode_iterator SSEMODE124C8 [V16QI V8HI V4SI + (V2DI "TARGET_SSE4_2")]) + ;; Mapping from float mode to required SSE level (define_mode_attr sse [(SF "sse") (DF "sse2") (V4SF "sse") (V2DF "sse2")]) ;; Mapping from integer vector mode to mnemonic suffix (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")]) +;; Mapping of the fma4 suffix +(define_mode_attr fma4modesuffixf4 [(V8SF "ps") (V4DF "pd")]) +(define_mode_attr ssemodesuffixf2s [(SF "ss") (DF "sd") + (V4SF "ss") (V2DF "sd")]) + +;; Mapping of the avx suffix +(define_mode_attr ssemodesuffixf4 [(SF "ss") (DF "sd") + (V4SF "ps") (V2DF "pd")]) + (define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")]) -;; Mapping of the max integer size for sse5 rotate immediate constraint +;; Mapping of the max integer size for xop 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 avxmodesuffix + [(V16QI "") (V32QI "256") (V4SI "") (V4SF "") (V2DF "") + (V8SI "256") (V8SF "256") (V4DF "256")]) ;; Mapping of immediate bits for blend instructions -(define_mode_attr blendbits [(V4SF "15") (V2DF "3")]) +(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. @@ -64,12 +149,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); @@ -77,8 +203,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))" @@ -89,23 +215,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. @@ -143,36 +278,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" ""))] @@ -187,38 +292,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" ""))] @@ -230,6 +303,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" { @@ -238,6 +319,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" @@ -246,6 +336,32 @@ 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 "movu" "1") + (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 @@ -255,8 +371,21 @@ && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "movup\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") + (set_attr "movu" "1") (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 "movu" "1") + (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,9 +393,21 @@ "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "movdqu\t{%1, %0|%0, %1}" [(set_attr "type" "ssemov") + (set_attr "movu" "1") (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 @@ -277,13 +418,24 @@ [(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")] UNSPEC_MOVNT))] "TARGET_SSE2" "movntdq\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") + [(set_attr "type" "ssemov") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) @@ -293,16 +445,31 @@ UNSPEC_MOVNT))] "TARGET_SSE2" "movnti\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") + [(set_attr "type" "ssemov") + (set_attr "prefix_data16" "0") (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 "movu" "1") + (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")] UNSPEC_LDDQU))] "TARGET_SSE3" "lddqu\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") + [(set_attr "type" "ssemov") + (set_attr "movu" "1") + (set_attr "prefix_data16" "0") (set_attr "prefix_rep" "1") (set_attr "mode" "TI")]) @@ -346,19 +513,34 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_expand "neg2" +(define_expand "2" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (neg: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 (NEG, 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_expand "abs2" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (abs:SSEMODEF2P (match_operand:SSEMODEF2P 1 "register_operand" "")))] - "SSE_VEC_FLOAT_MODE_P (mode)" - "ix86_expand_fp_absneg_operator (ABS, mode, operands); DONE;") +(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 "3" +(define_expand "3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "") (plusminus:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") @@ -366,18 +548,32 @@ "SSE_VEC_FLOAT_MODE_P (mode)" "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "*3" +(define_insn "*3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (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 (, mode, operands)" - "p\t{%2, %0|%0, %2}" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "")]) -(define_insn "_vm3" +(define_insn "*avx_vm3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (plusminus: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)" + "vs\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + +(define_insn "_vm3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P (plusminus:SSEMODEF2P @@ -385,13 +581,32 @@ (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")) (match_dup 1) (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode) - && ix86_binary_operator_ok (, V4SFmode, operands)" - "s\t{%2, %0|%0, %2}" + "SSE_VEC_FLOAT_MODE_P (mode)" + "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" "") @@ -410,6 +625,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 @@ -418,21 +647,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_insn_for_size_p () + && 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) { @@ -447,7 +709,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") @@ -459,6 +732,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 @@ -472,15 +759,40 @@ [(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 "atom_sse_attr" "rcp") + (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 @@ -491,14 +803,38 @@ "TARGET_SSE" "rcpss\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "rcp") (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_insn_for_size_p () + && 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) { @@ -511,18 +847,43 @@ [(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 "atom_sse_attr" "sqrt") + (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 @@ -533,8 +894,29 @@ "SSE_VEC_FLOAT_MODE_P (mode)" "sqrts\t{%1, %0|%0, %1}" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "sqrt") (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 @@ -550,10 +932,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 @@ -571,6 +967,18 @@ ;; applied to NaNs. Hopefully the optimizers won't get too smart on us. (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" "") (smaxmin:SSEMODEF2P (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "") @@ -582,6 +990,18 @@ ix86_fixup_binary_operands_no_copy (, mode, operands); }) +(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") (smaxmin:SSEMODEF2P @@ -593,6 +1013,17 @@ [(set_attr "type" "sseadd") (set_attr "mode" "")]) +(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") (smaxmin:SSEMODEF2P @@ -603,6 +1034,20 @@ [(set_attr "type" "sseadd") (set_attr "mode" "")]) +(define_insn "*avx_vm3" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") + (vec_merge:SSEMODEF2P + (smaxmin: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)" + "vs\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sse") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "_vm3" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P @@ -613,7 +1058,7 @@ (const_int 1)))] "SSE_VEC_FLOAT_MODE_P (mode)" "s\t{%2, %0|%0, %2}" - [(set_attr "type" "sse") + [(set_attr "type" "sseadd") (set_attr "mode" "")]) ;; These versions of the min/max patterns implement exactly the operations @@ -622,6 +1067,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 @@ -644,6 +1113,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 170)))] + "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 10)))] + "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 10)))] + "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 @@ -651,13 +1162,27 @@ (match_operand:V4SF 1 "register_operand" "0") (match_operand:V4SF 2 "nonimmediate_operand" "xm")) (minus:V4SF (match_dup 1) (match_dup 2)) - (const_int 5)))] + (const_int 10)))] "TARGET_SSE3" "addsubps\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (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 2)))] + "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 @@ -665,13 +1190,111 @@ (match_operand:V2DF 1 "register_operand" "0") (match_operand:V2DF 2 "nonimmediate_operand" "xm")) (minus:V2DF (match_dup 1) (match_dup 2)) - (const_int 1)))] + (const_int 2)))] "TARGET_SSE3" "addsubpd\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") + (set_attr "atom_unit" "complex") (set_attr "mode" "V2DF")]) -(define_insn "sse3_hv4sf3" +(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 + (plusminus:SF + (vec_select:SF + (match_operand:V4SF 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:V4SF 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)]))))))] + "TARGET_AVX" + "vhps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseadd") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + +(define_insn "sse3_hv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_concat:V4SF (vec_concat:V2SF @@ -693,12 +1316,32 @@ (vec_select:SF (match_dup 2) (parallel [(const_int 2)])) (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))] "TARGET_SSE3" - "hps\t{%2, %0|%0, %2}" + "hps\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_rep" "1") (set_attr "mode" "V4SF")]) -(define_insn "sse3_hv2df3" +(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 (plusminus:DF @@ -712,7 +1355,7 @@ (parallel [(const_int 0)])) (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))] "TARGET_SSE3" - "hpd\t{%2, %0|%0, %2}" + "hpd\t{%2, %0|%0, %2}" [(set_attr "type" "sseadd") (set_attr "mode" "V2DF")]) @@ -765,15 +1408,61 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(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 "length_immediate" "1") + (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 "length_immediate" "1") + (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 "length_immediate" "1") + (set_attr "mode" "")]) + (define_insn "_maskcmp3" [(set (match_operand:SSEMODEF4 0 "register_operand" "=x") (match_operator:SSEMODEF4 3 "sse_comparison_operator" [(match_operand:SSEMODEF4 1 "register_operand" "0") (match_operand:SSEMODEF4 2 "nonimmediate_operand" "xm")]))] - "(SSE_FLOAT_MODE_P (mode) || SSE_VEC_FLOAT_MODE_P (mode)) - && !TARGET_SSE5" + "!TARGET_XOP + && (SSE_FLOAT_MODE_P (mode) || SSE_VEC_FLOAT_MODE_P (mode))" "cmp%D3\t{%2, %0|%0, %2}" [(set_attr "type" "ssecmp") + (set_attr "length_immediate" "1") (set_attr "mode" "")]) (define_insn "_vmmaskcmp3" @@ -784,9 +1473,10 @@ (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm")]) (match_dup 1) (const_int 1)))] - "SSE_VEC_FLOAT_MODE_P (mode) && !TARGET_SSE5" + "SSE_VEC_FLOAT_MODE_P (mode)" "cmp%D3s\t{%2, %0|%0, %2}" [(set_attr "type" "ssecmp") + (set_attr "length_immediate" "1") (set_attr "mode" "")]) (define_insn "_comi" @@ -799,8 +1489,14 @@ (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 "prefix_rep" "0") + (set (attr "prefix_data16") + (if_then_else (eq_attr "mode" "DF") + (const_string "1") + (const_string "0"))) (set_attr "mode" "")]) (define_insn "_ucomi" @@ -813,8 +1509,14 @@ (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 "prefix_rep" "0") + (set (attr "prefix_data16") + (if_then_else (eq_attr "mode" "DF") + (const_string "1") + (const_string "0"))) (set_attr "mode" "")]) (define_expand "vcond" @@ -827,10 +1529,9 @@ (match_operand:SSEMODEF2P 2 "general_operand" "")))] "SSE_VEC_FLOAT_MODE_P (mode)" { - if (ix86_expand_fp_vcond (operands)) - DONE; - else - FAIL; + bool ok = ix86_expand_fp_vcond (operands); + gcc_assert (ok); + DONE; }) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -839,26 +1540,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, mode, 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 @@ -869,60 +1563,81 @@ [(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_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 "*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_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" "")]) +(define_expand "copysign3" + [(set (match_dup 4) + (and:SSEMODEF2P + (not:SSEMODEF2P (match_dup 3)) + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" ""))) + (set (match_dup 5) + (and:SSEMODEF2P (match_dup 3) + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" ""))) + (set (match_operand:SSEMODEF2P 0 "register_operand" "") + (ior:SSEMODEF2P (match_dup 4) (match_dup 5)))] + "SSE_VEC_FLOAT_MODE_P (mode)" +{ + operands[3] = ix86_build_signbit_mask (mode, 1, 0); + + operands[4] = gen_reg_rtx (mode); + operands[5] = gen_reg_rtx (mode); +}) + ;; Also define scalar versions. These are used for abs, neg, and ;; conditional move. Using subregs into vector modes causes register ;; 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 @@ -933,29 +1648,30 @@ [(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" "")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; SSE5 floating point multiply/accumulate instructions This includes the +;; FMA4 floating point multiply/accumulate instructions This includes the ;; scalar version of the instructions as well as the vector ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -971,16 +1687,168 @@ ;; (set (reg2) (mult (reg1) (mem (addr2)))) ;; (set (reg3) (plus (reg2) (mem (addr3)))) -(define_insn "sse5_fmadd4" - [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x") +(define_insn "fma4_fmadd4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x,x") + (plus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm,x")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x,x")))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) + +;; Split fmadd with two memory operands into a load and the fmadd. +(define_split + [(set (match_operand:FMA4MODEF4 0 "register_operand" "") + (plus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "")))] + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" + [(const_int 0)] +{ + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fmadd4256 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +}) + +;; Floating multiply and subtract +;; Allow two memory operands the same as fmadd +(define_insn "fma4_fmsub4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x,x") + (minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm,x")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x,x")))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) + +;; Split fmsub with two memory operands into a load and the fmsub. +(define_split + [(set (match_operand:FMA4MODEF4 0 "register_operand" "") + (minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "")))] + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" + [(const_int 0)] +{ + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fmsub4256 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +}) + +;; Floating point negative multiply and add +;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b) +;; Note operands are out of order to simplify call to ix86_fma4_valid_p +;; Allow two memory operands to help in optimizing. +(define_insn "fma4_fnmadd4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x,x") + (minus:FMA4MODEF4 + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x,x") + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm,x"))))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) + +;; Split fnmadd with two memory operands into a load and the fnmadd. +(define_split + [(set (match_operand:FMA4MODEF4 0 "register_operand" "") + (minus:FMA4MODEF4 + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "") + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" ""))))] + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" + [(const_int 0)] +{ + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fnmadd4256 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +}) + +;; Floating point negative multiply and subtract +;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c +;; Allow 2 memory operands to help with optimization +(define_insn "fma4_fnmsub4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x") + (minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (neg:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x")) + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x")))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) + +;; Split fnmsub with two memory operands into a load and the fmsub. +(define_split + [(set (match_operand:FMA4MODEF4 0 "register_operand" "") + (minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (neg:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "")) + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "")))] + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false) + && ix86_fma4_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])" + [(const_int 0)] +{ + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fnmsub4256 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +}) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_insn "fma4_fmadd4" + [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x") (plus:SSEMODEF4 (mult:SSEMODEF4 - (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm") - (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)" - "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (match_operand:SSEMODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,x")) + (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,x")))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -992,16 +1860,16 @@ (match_operand:SSEMODEF4 1 "nonimmediate_operand" "") (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) + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, mode); - emit_insn (gen_sse5_fmadd4 (operands[0], operands[1], + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fmadd4 (operands[0], operands[1], operands[2], operands[3])); DONE; }) @@ -1009,34 +1877,34 @@ ;; For the scalar operations, use operand1 for the upper words that aren't ;; modified, so restrict the forms that are generated. ;; Scalar version of fmadd -(define_insn "sse5_vmfmadd4" +(define_insn "fma4_vmfmadd4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (vec_merge:SSEMODEF2P (plus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0") + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) - (match_dup 1) + (match_dup 0) (const_int 1)))] - "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) ;; Floating multiply and subtract ;; Allow two memory operands the same as fmadd -(define_insn "sse5_fmsub4" - [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x") +(define_insn "fma4_fmsub4" + [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x") (minus:SSEMODEF4 (mult:SSEMODEF4 - (match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm") - (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)" - "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (match_operand:SSEMODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,x")) + (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,x")))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1048,16 +1916,16 @@ (match_operand:SSEMODEF4 1 "nonimmediate_operand" "") (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) + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, mode); - emit_insn (gen_sse5_fmsub4 (operands[0], operands[1], + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fmsub4 (operands[0], operands[1], operands[2], operands[3])); DONE; }) @@ -1065,36 +1933,36 @@ ;; For the scalar operations, use operand1 for the upper words that aren't ;; modified, so restrict the forms that are generated. ;; Scalar version of fmsub -(define_insn "sse5_vmfmsub4" +(define_insn "fma4_vmfmsub4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (vec_merge:SSEMODEF2P (minus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0") + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) - (match_dup 1) + (match_dup 0) (const_int 1)))] - "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) ;; Floating point negative multiply and add ;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b) -;; Note operands are out of order to simplify call to ix86_sse5_valid_p +;; Note operands are out of order to simplify call to ix86_fma4_valid_p ;; Allow two memory operands to help in optimizing. -(define_insn "sse5_fnmadd4" - [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x,x") +(define_insn "fma4_fnmadd4" + [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x,x") (minus:SSEMODEF4 - (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0") + (match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,x") (mult:SSEMODEF4 - (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)" - "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (match_operand:SSEMODEF4 1 "nonimmediate_operand" "x,x,xm") + (match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,x"))))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1106,16 +1974,16 @@ (mult:SSEMODEF4 (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) + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, mode); - emit_insn (gen_sse5_fnmadd4 (operands[0], operands[1], + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fnmadd4 (operands[0], operands[1], operands[2], operands[3])); DONE; }) @@ -1123,36 +1991,36 @@ ;; For the scalar operations, use operand1 for the upper words that aren't ;; modified, so restrict the forms that are generated. ;; Scalar version of fnmadd -(define_insn "sse5_vmfnmadd4" +(define_insn "fma4_vmfnmadd4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (vec_merge:SSEMODEF2P (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" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))) - (match_dup 1) + (match_dup 0) (const_int 1)))] - "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) ;; Floating point negative multiply and subtract ;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c ;; Allow 2 memory operands to help with optimization -(define_insn "sse5_fnmsub4" +(define_insn "fma4_fnmsub4" [(set (match_operand:SSEMODEF4 0 "register_operand" "=x,x") (minus:SSEMODEF4 (mult:SSEMODEF4 (neg:SSEMODEF4 - (match_operand:SSEMODEF4 1 "nonimmediate_operand" "0,0")) + (match_operand:SSEMODEF4 1 "nonimmediate_operand" "x,x")) (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)" - "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) @@ -1165,16 +2033,16 @@ (match_operand:SSEMODEF4 1 "nonimmediate_operand" "")) (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) + "TARGET_FMA4 + && !ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, mode); - emit_insn (gen_sse5_fnmsub4 (operands[0], operands[1], + ix86_expand_fma4_multiple_memory (operands, 4, mode); + emit_insn (gen_fma4_fnmsub4 (operands[0], operands[1], operands[2], operands[3])); DONE; }) @@ -1182,336 +2050,557 @@ ;; For the scalar operations, use operand1 for the upper words that aren't ;; modified, so restrict the forms that are generated. ;; Scalar version of fnmsub -(define_insn "sse5_vmfnmsub4" +(define_insn "fma4_vmfnmsub4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (vec_merge:SSEMODEF2P (minus:SSEMODEF2P (mult:SSEMODEF2P (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")) + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x")) (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) - (match_dup 1) + (match_dup 0) (const_int 1)))] - "TARGET_SSE5 && TARGET_FUSED_MADD - && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)" - "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -;; The same instructions using an UNSPEC to allow the intrinsic to be used -;; even if the user used -mno-fused-madd -;; Parallel instructions. During instruction generation, just default -;; to registers, and let combine later build the appropriate instruction. -(define_expand "sse5i_fmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (unspec:SSEMODEF2P - [(plus:SSEMODEF2P - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" ""))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_fmadd4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn "fma4i_fmadd4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x") + (unspec:FMA4MODEF4 + [(plus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) -(define_insn "*sse5i_fmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x") - (unspec:SSEMODEF2P - [(plus:SSEMODEF2P - (mult:SSEMODEF2P - (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)" - "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" +(define_insn "fma4i_fmsub4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x") + (unspec:FMA4MODEF4 + [(minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -(define_expand "sse5i_fmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (unspec:SSEMODEF2P - [(minus:SSEMODEF2P - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" ""))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_fmsub4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) +(define_insn "fma4i_fnmadd4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x") + (unspec:FMA4MODEF4 + [(minus:FMA4MODEF4 + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x") + (mult:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x") + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm")))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) -(define_insn "*sse5i_fmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x") - (unspec:SSEMODEF2P - [(minus:SSEMODEF2P - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_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)" - "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" +(define_insn "fma4i_fnmsub4256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x,x") + (unspec:FMA4MODEF4 + [(minus:FMA4MODEF4 + (mult:FMA4MODEF4 + (neg:FMA4MODEF4 + (match_operand:FMA4MODEF4 1 "nonimmediate_operand" "x,x")) + (match_operand:FMA4MODEF4 2 "nonimmediate_operand" "x,xm")) + (match_operand:FMA4MODEF4 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Rewrite (- (a * b) + c) into the canonical form: c - (a * b) -;; Note operands are out of order to simplify call to ix86_sse5_valid_p -(define_expand "sse5i_fnmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") +(define_insn "fma4i_fmadd4" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P - [(minus:SSEMODEF2P - (match_operand:SSEMODEF2P 3 "register_operand" "") + [(plus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" "")))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_fnmadd4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) + (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) -(define_insn "*sse5i_fnmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x") +(define_insn "fma4i_fmsub4" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(minus:SSEMODEF2P - (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0") (mult:SSEMODEF2P - (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)" - "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) + (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -;; Rewrite (- (a * b) - c) into the canonical form: ((-a) * b) - c -(define_expand "sse5i_fnmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") +(define_insn "fma4i_fnmadd4" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(minus:SSEMODEF2P + (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x") (mult:SSEMODEF2P - (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "")) - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" ""))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_fnmsub4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x") + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "")]) -(define_insn "*sse5i_fnmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x") +(define_insn "fma4i_fnmsub4" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(minus:SSEMODEF2P (mult:SSEMODEF2P (neg:SSEMODEF2P - (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)" - "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "x,x")) + (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) + (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -;; Scalar instructions -(define_expand "sse5i_vmfmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (unspec:SSEMODEF2P - [(vec_merge:SSEMODEF2P - (plus:SSEMODEF2P - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" "")) - (match_dup 1) - (const_int 0))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_vmfmadd4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) - ;; For the scalar operations, use operand1 for the upper words that aren't ;; modified, so restrict the forms that are accepted. -(define_insn "*sse5i_vmfmadd4" +(define_insn "fma4i_vmfmadd4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(vec_merge:SSEMODEF2P (plus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "0,0") + (match_operand:SSEMODEF2P 1 "register_operand" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) (match_dup 0) - (const_int 0))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + (const_int 1))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -(define_expand "sse5i_vmfmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") +(define_insn "fma4i_vmfmsub4" + [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(vec_merge:SSEMODEF2P (minus:SSEMODEF2P (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" "")) - (match_dup 0) - (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_vmfmsub4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) - -(define_insn "*sse5i_vmfmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") - (unspec:SSEMODEF2P - [(vec_merge:SSEMODEF2P - (minus:SSEMODEF2P - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0") + (match_operand:SSEMODEF2P 1 "register_operand" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) - (match_dup 1) + (match_dup 0) (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -;; Note operands are out of order to simplify call to ix86_sse5_valid_p -(define_expand "sse5i_vmfnmadd4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (unspec:SSEMODEF2P - [(vec_merge:SSEMODEF2P - (minus:SSEMODEF2P - (match_operand:SSEMODEF2P 3 "register_operand" "") - (mult:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "") - (match_operand:SSEMODEF2P 2 "register_operand" ""))) - (match_dup 1) - (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_vmfnmadd4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) - -(define_insn "*sse5i_vmfnmadd4" +(define_insn "fma4i_vmfnmadd4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(vec_merge:SSEMODEF2P (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" "x,x") (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))) - (match_dup 1) + (match_dup 0) (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, true)" + "vfnmadd\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) -(define_expand "sse5i_vmfnmsub4" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (unspec:SSEMODEF2P - [(vec_merge:SSEMODEF2P - (minus:SSEMODEF2P - (mult:SSEMODEF2P - (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "register_operand" "")) - (match_operand:SSEMODEF2P 2 "register_operand" "")) - (match_operand:SSEMODEF2P 3 "register_operand" "")) - (match_dup 1) - (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5" -{ - /* If we have -mfused-madd, emit the normal insn rather than the UNSPEC */ - if (TARGET_FUSED_MADD) - { - emit_insn (gen_sse5_vmfnmsub4 (operands[0], operands[1], - operands[2], operands[3])); - DONE; - } -}) - -(define_insn "*sse5i_vmfnmsub4" +(define_insn "fma4i_vmfnmsub4" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x") (unspec:SSEMODEF2P [(vec_merge:SSEMODEF2P (minus:SSEMODEF2P (mult:SSEMODEF2P (neg:SSEMODEF2P - (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")) + (match_operand:SSEMODEF2P 1 "register_operand" "x,x")) (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")) (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")) - (match_dup 1) + (match_dup 0) (const_int 1))] - UNSPEC_SSE5_INTRINSIC))] - "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)" - "fnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vfnmsub\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; +;; FMA4 Parallel floating point multiply addsub and subadd operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn "fma4_fmaddsubv8sf4" + [(set (match_operand:V8SF 0 "register_operand" "=x,x") + (vec_merge:V8SF + (plus:V8SF + (mult:V8SF + (match_operand:V8SF 1 "nonimmediate_operand" "x,x") + (match_operand:V8SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V8SF 3 "nonimmediate_operand" "xm,x")) + (minus:V8SF + (mult:V8SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 170)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V8SF")]) + +(define_insn "fma4_fmaddsubv4df4" + [(set (match_operand:V4DF 0 "register_operand" "=x,x") + (vec_merge:V4DF + (plus:V4DF + (mult:V4DF + (match_operand:V4DF 1 "nonimmediate_operand" "x,x") + (match_operand:V4DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4DF 3 "nonimmediate_operand" "xm,x")) + (minus:V4DF + (mult:V4DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 10)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4DF")]) + +(define_insn "fma4_fmaddsubv4sf4" + [(set (match_operand:V4SF 0 "register_operand" "=x,x") + (vec_merge:V4SF + (plus:V4SF + (mult:V4SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x") + (match_operand:V4SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4SF 3 "nonimmediate_operand" "xm,x")) + (minus:V4SF + (mult:V4SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 10)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4SF")]) + +(define_insn "fma4_fmaddsubv2df4" + [(set (match_operand:V2DF 0 "register_operand" "=x,x") + (vec_merge:V2DF + (plus:V2DF + (mult:V2DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x") + (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V2DF 3 "nonimmediate_operand" "xm,x")) + (minus:V2DF + (mult:V2DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 2)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V2DF")]) + +(define_insn "fma4_fmsubaddv8sf4" + [(set (match_operand:V8SF 0 "register_operand" "=x,x") + (vec_merge:V8SF + (plus:V8SF + (mult:V8SF + (match_operand:V8SF 1 "nonimmediate_operand" "x,x") + (match_operand:V8SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V8SF 3 "nonimmediate_operand" "xm,x")) + (minus:V8SF + (mult:V8SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 85)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V8SF")]) + +(define_insn "fma4_fmsubaddv4df4" + [(set (match_operand:V4DF 0 "register_operand" "=x,x") + (vec_merge:V4DF + (plus:V4DF + (mult:V4DF + (match_operand:V4DF 1 "nonimmediate_operand" "x,x") + (match_operand:V4DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4DF 3 "nonimmediate_operand" "xm,x")) + (minus:V4DF + (mult:V4DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 5)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4DF")]) + +(define_insn "fma4_fmsubaddv4sf4" + [(set (match_operand:V4SF 0 "register_operand" "=x,x") + (vec_merge:V4SF + (plus:V4SF + (mult:V4SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x") + (match_operand:V4SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4SF 3 "nonimmediate_operand" "xm,x")) + (minus:V4SF + (mult:V4SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 5)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4SF")]) + +(define_insn "fma4_fmsubaddv2df4" + [(set (match_operand:V2DF 0 "register_operand" "=x,x") + (vec_merge:V2DF + (plus:V2DF + (mult:V2DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x") + (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V2DF 3 "nonimmediate_operand" "xm,x")) + (minus:V2DF + (mult:V2DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 1)))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V2DF")]) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn "fma4i_fmaddsubv8sf4" + [(set (match_operand:V8SF 0 "register_operand" "=x,x") + (unspec:V8SF + [(vec_merge:V8SF + (plus:V8SF + (mult:V8SF + (match_operand:V8SF 1 "nonimmediate_operand" "x,x") + (match_operand:V8SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V8SF 3 "nonimmediate_operand" "xm,x")) + (minus:V8SF + (mult:V8SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 170))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V8SF")]) + +(define_insn "fma4i_fmaddsubv4df4" + [(set (match_operand:V4DF 0 "register_operand" "=x,x") + (unspec:V4DF + [(vec_merge:V4DF + (plus:V4DF + (mult:V4DF + (match_operand:V4DF 1 "nonimmediate_operand" "x,x") + (match_operand:V4DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4DF 3 "nonimmediate_operand" "xm,x")) + (minus:V4DF + (mult:V4DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 10))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4DF")]) + +(define_insn "fma4i_fmaddsubv4sf4" + [(set (match_operand:V4SF 0 "register_operand" "=x,x") + (unspec:V4SF + [(vec_merge:V4SF + (plus:V4SF + (mult:V4SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x") + (match_operand:V4SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4SF 3 "nonimmediate_operand" "xm,x")) + (minus:V4SF + (mult:V4SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 10))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4SF")]) + +(define_insn "fma4i_fmaddsubv2df4" + [(set (match_operand:V2DF 0 "register_operand" "=x,x") + (unspec:V2DF + [(vec_merge:V2DF + (plus:V2DF + (mult:V2DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x") + (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V2DF 3 "nonimmediate_operand" "xm,x")) + (minus:V2DF + (mult:V2DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 2))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmaddsubpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V2DF")]) + +(define_insn "fma4i_fmsubaddv8sf4" + [(set (match_operand:V8SF 0 "register_operand" "=x,x") + (unspec:V8SF + [(vec_merge:V8SF + (plus:V8SF + (mult:V8SF + (match_operand:V8SF 1 "nonimmediate_operand" "x,x") + (match_operand:V8SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V8SF 3 "nonimmediate_operand" "xm,x")) + (minus:V8SF + (mult:V8SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 85))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V8SF")]) + +(define_insn "fma4i_fmsubaddv4df4" + [(set (match_operand:V4DF 0 "register_operand" "=x,x") + (unspec:V4DF + [(vec_merge:V4DF + (plus:V4DF + (mult:V4DF + (match_operand:V4DF 1 "nonimmediate_operand" "x,x") + (match_operand:V4DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4DF 3 "nonimmediate_operand" "xm,x")) + (minus:V4DF + (mult:V4DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 5))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4DF")]) + +(define_insn "fma4i_fmsubaddv4sf4" + [(set (match_operand:V4SF 0 "register_operand" "=x,x") + (unspec:V4SF + [(vec_merge:V4SF + (plus:V4SF + (mult:V4SF + (match_operand:V4SF 1 "nonimmediate_operand" "x,x") + (match_operand:V4SF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V4SF 3 "nonimmediate_operand" "xm,x")) + (minus:V4SF + (mult:V4SF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 5))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V4SF")]) + +(define_insn "fma4i_fmsubaddv2df4" + [(set (match_operand:V2DF 0 "register_operand" "=x,x") + (unspec:V2DF + [(vec_merge:V2DF + (plus:V2DF + (mult:V2DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x") + (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")) + (match_operand:V2DF 3 "nonimmediate_operand" "xm,x")) + (minus:V2DF + (mult:V2DF + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (const_int 1))] + UNSPEC_FMA4_INTRINSIC))] + "TARGET_FMA4 + && ix86_fma4_valid_op_p (operands, insn, 4, true, 2, true)" + "vfmsubaddpd\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "V2DF")]) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; Parallel single-precision floating point conversion operations ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1549,6 +2638,20 @@ "cvttps2pi\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "unit" "mmx") + (set_attr "prefix_rep" "0") + (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" @@ -1565,6 +2668,20 @@ (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 "length_vex" "4") + (set_attr "prefix" "vex") + (set_attr "mode" "SF")]) + (define_insn "sse_cvtsi2ssq" [(set (match_operand:V4SF 0 "register_operand" "=x,x") (vec_merge:V4SF @@ -1575,6 +2692,7 @@ "TARGET_SSE && TARGET_64BIT" "cvtsi2ssq\t{%2, %0|%0, %2}" [(set_attr "type" "sseicvt") + (set_attr "prefix_rex" "1") (set_attr "athlon_decode" "vector,double") (set_attr "amdfam10_decode" "vector,double") (set_attr "mode" "SF")]) @@ -1587,10 +2705,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" @@ -1598,11 +2717,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" @@ -1613,10 +2733,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" @@ -1624,11 +2745,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" @@ -1638,11 +2760,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" @@ -1652,13 +2775,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")))] @@ -1667,6 +2801,42 @@ [(set_attr "type" "ssecvt") (set_attr "mode" "V4SF")]) +(define_expand "sse2_cvtudq2ps" + [(set (match_dup 5) + (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" ""))) + (set (match_dup 6) + (lt:V4SF (match_dup 5) (match_dup 3))) + (set (match_dup 7) + (and:V4SF (match_dup 6) (match_dup 4))) + (set (match_operand:V4SF 0 "register_operand" "") + (plus:V4SF (match_dup 5) (match_dup 7)))] + "TARGET_SSE2" +{ + REAL_VALUE_TYPE TWO32r; + rtx x; + int i; + + real_ldexp (&TWO32r, &dconst1, 32); + x = const_double_from_real_value (TWO32r, SFmode); + + operands[3] = force_reg (V4SFmode, CONST0_RTX (V4SFmode)); + operands[4] = force_reg (V4SFmode, ix86_build_const_vector (SFmode, 1, x)); + + for (i = 5; i < 8; i++) + operands[i] = gen_reg_rtx (V4SFmode); +}) + +(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")] @@ -1677,6 +2847,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")))] @@ -1684,6 +2864,7 @@ "cvttps2dq\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix_rep" "1") + (set_attr "prefix_data16" "0") (set_attr "mode" "TI")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1699,6 +2880,7 @@ "cvtpi2pd\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "unit" "mmx,*") + (set_attr "prefix_data16" "1,*") (set_attr "mode" "V2DF")]) (define_insn "sse2_cvtpd2pi" @@ -1722,6 +2904,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 @@ -1736,6 +2931,20 @@ (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 "length_vex" "4") + (set_attr "prefix" "vex") + (set_attr "mode" "DF")]) + (define_insn "sse2_cvtsi2sdq" [(set (match_operand:V2DF 0 "register_operand" "=x,x") (vec_merge:V2DF @@ -1746,6 +2955,7 @@ "TARGET_SSE2 && TARGET_64BIT" "cvtsi2sdq\t{%2, %0|%0, %2}" [(set_attr "type" "sseicvt") + (set_attr "prefix_rex" "1") (set_attr "mode" "DF") (set_attr "athlon_decode" "double,direct") (set_attr "amdfam10_decode" "vector,double")]) @@ -1758,10 +2968,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" @@ -1769,11 +2980,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" @@ -1784,10 +2996,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" @@ -1795,11 +3008,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" @@ -1809,9 +3023,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")]) @@ -1823,13 +3038,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 @@ -1837,10 +3062,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 @@ -1857,12 +3093,24 @@ 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_data16" "0") + (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 @@ -1877,12 +3125,27 @@ (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 @@ -1898,6 +3161,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 @@ -1913,6 +3191,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 @@ -1929,12 +3217,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 @@ -1942,9 +3242,11 @@ (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 "prefix_data16" "0") (set_attr "amdfam10_decode" "direct")]) (define_expand "vec_unpacks_hi_v4sf" @@ -2037,9 +3339,7 @@ (match_dup 2) (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE2" -{ - operands[2] = gen_reg_rtx (V4SImode); -}) + "operands[2] = gen_reg_rtx (V4SImode);") (define_expand "vec_unpacks_float_lo_v4si" [(set (match_operand:V2DF 0 "register_operand" "") @@ -2049,6 +3349,71 @@ (parallel [(const_int 0) (const_int 1)]))))] "TARGET_SSE2") +(define_expand "vec_unpacku_float_hi_v4si" + [(set (match_dup 5) + (vec_select:V4SI + (match_operand:V4SI 1 "nonimmediate_operand" "") + (parallel [(const_int 2) + (const_int 3) + (const_int 2) + (const_int 3)]))) + (set (match_dup 6) + (float:V2DF + (vec_select:V2SI + (match_dup 5) + (parallel [(const_int 0) (const_int 1)])))) + (set (match_dup 7) + (lt:V2DF (match_dup 6) (match_dup 3))) + (set (match_dup 8) + (and:V2DF (match_dup 7) (match_dup 4))) + (set (match_operand:V2DF 0 "register_operand" "") + (plus:V2DF (match_dup 6) (match_dup 8)))] + "TARGET_SSE2" +{ + REAL_VALUE_TYPE TWO32r; + rtx x; + int i; + + real_ldexp (&TWO32r, &dconst1, 32); + x = const_double_from_real_value (TWO32r, DFmode); + + operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode)); + operands[4] = force_reg (V2DFmode, ix86_build_const_vector (DFmode, 1, x)); + + operands[5] = gen_reg_rtx (V4SImode); + + for (i = 6; i < 9; i++) + operands[i] = gen_reg_rtx (V2DFmode); +}) + +(define_expand "vec_unpacku_float_lo_v4si" + [(set (match_dup 5) + (float:V2DF + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 1)])))) + (set (match_dup 6) + (lt:V2DF (match_dup 5) (match_dup 3))) + (set (match_dup 7) + (and:V2DF (match_dup 6) (match_dup 4))) + (set (match_operand:V2DF 0 "register_operand" "") + (plus:V2DF (match_dup 5) (match_dup 7)))] + "TARGET_SSE2" +{ + REAL_VALUE_TYPE TWO32r; + rtx x; + int i; + + real_ldexp (&TWO32r, &dconst1, 32); + x = const_double_from_real_value (TWO32r, DFmode); + + operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode)); + operands[4] = force_reg (V2DFmode, ix86_build_const_vector (DFmode, 1, x)); + + for (i = 5; i < 8; i++) + operands[i] = gen_reg_rtx (V2DFmode); +}) + (define_expand "vec_pack_trunc_v2df" [(match_operand:V4SF 0 "register_operand" "") (match_operand:V2DF 1 "nonimmediate_operand" "") @@ -2110,6 +3475,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 @@ -2128,24 +3525,86 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V4SF,V2SF,V2SF")]) -(define_insn "sse_movlhps" +(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" " 0,0,0") + (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_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)" + "TARGET_AVX && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)" "@ - movlhps\t{%2, %0|%0, %2} - movhps\t{%2, %0|%0, %2} - movlps\t{%2, %H0|%H0, %2}" + 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 + (vec_concat:V8SF + (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0") + (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x")) + (parallel [(const_int 0) + (const_int 1) + (const_int 4) + (const_int 5)])))] + "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)" + "@ + movlhps\t{%2, %0|%0, %2} + movhps\t{%2, %0|%0, %2} + movlps\t{%2, %H0|%H0, %2}" + [(set_attr "type" "ssemov") + (set_attr "mode" "V4SF,V2SF,V2SF")]) + +(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 10) + (const_int 3) (const_int 11) + (const_int 6) (const_int 14) + (const_int 7) (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" "x") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "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_unpckhps" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_select:V4SF @@ -2159,6 +3618,36 @@ [(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 8) + (const_int 1) (const_int 9) + (const_int 4) (const_int 12) + (const_int 5) (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 @@ -2174,6 +3663,22 @@ ;; 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 @@ -2185,11 +3690,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 @@ -2201,11 +3723,67 @@ (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 "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "V8SF")]) + (define_expand "sse_shufps" [(match_operand:V4SF 0 "register_operand" "") (match_operand:V4SF 1 "register_operand" "") @@ -2214,7 +3792,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), @@ -2222,12 +3800,38 @@ 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 "length_immediate" "1") + (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" "") @@ -2244,6 +3848,7 @@ return "shufps\t{%3, %2, %0|%0, %2, %3}"; } [(set_attr "type" "sselog") + (set_attr "length_immediate" "1") (set_attr "mode" "V4SF")]) (define_insn "sse_storehps" @@ -2253,10 +3858,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" @@ -2274,6 +3906,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 @@ -2287,6 +3933,33 @@ [(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 "length_immediate" "1,*,*") + (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 @@ -2300,8 +3973,21 @@ movlps\t{%2, %0|%0, %2} movlps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "length_immediate" "1,*,*") (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 @@ -2313,6 +3999,17 @@ [(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 "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "V4SF")]) + (define_insn "*vec_dupv4sf" [(set (match_operand:V4SF 0 "register_operand" "=x") (vec_duplicate:V4SF @@ -2320,12 +4017,54 @@ "TARGET_SSE" "shufps\t{$0, %0, %0|%0, %0, 0}" [(set_attr "type" "sselog1") + (set_attr "length_immediate" "1") (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 "length_immediate" "*,1,*,*,*") + (set_attr "prefix_extra" "*,1,*,*,*") + (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_data16" "*,1,*,*,*") + (set_attr "prefix_extra" "*,1,*,*,*") + (set_attr "length_immediate" "*,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") @@ -2339,7 +4078,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") @@ -2351,8 +4103,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" { @@ -2360,6 +4112,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 @@ -2377,6 +4146,24 @@ (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_extra" "1") + (set_attr "length_immediate" "1") + (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 @@ -2390,7 +4177,23 @@ return "insertps\t{%3, %2, %0|%0, %2, %3}"; } [(set_attr "type" "sselog") + (set_attr "prefix_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "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 "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "V4SF")]) (define_insn "sse4_1_insertps" @@ -2402,7 +4205,9 @@ "TARGET_SSE4_1" "insertps\t{%3, %2, %0|%0, %2, %3}"; [(set_attr "type" "sselog") + (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "V4SF")]) (define_split @@ -2419,9 +4224,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" { @@ -2431,9 +4236,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]))" "#" @@ -2449,15 +4254,172 @@ 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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (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_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "V4SF")]) (define_insn_and_split "*vec_extract_v4sf_mem" @@ -2476,9 +4438,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" { @@ -2493,6 +4455,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 1) (const_int 5) + (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 @@ -2507,9 +4511,24 @@ movlpd\t{%H1, %0|%0, %H1} movhpd\t{%1, %0|%0, %1}" [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "prefix_data16" "*,1,1") (set_attr "mode" "V2DF,V1DF,V1DF")]) -(define_insn "*sse3_movddup" +(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 @@ -2517,7 +4536,23 @@ (match_dup 1)) (parallel [(const_int 0) (const_int 2)])))] - "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "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 + (vec_concat:V4DF + (match_operand:V2DF 1 "nonimmediate_operand" "xm,x") + (match_dup 1)) + (parallel [(const_int 0) + (const_int 2)])))] + "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ movddup\t{%1, %0|%0, %1} #" @@ -2541,6 +4576,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 2) (const_int 6)])))] + "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 @@ -2555,8 +4632,51 @@ movhpd\t{%2, %0|%0, %2} movlpd\t{%2, %H0|%H0, %2}" [(set_attr "type" "sselog,ssemov,ssemov") + (set_attr "prefix_data16" "*,1,1") (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 "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "V4DF")]) + (define_expand "sse2_shufpd" [(match_operand:V2DF 0 "register_operand" "") (match_operand:V2DF 1 "register_operand" "") @@ -2565,18 +4685,141 @@ "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 "length_immediate" "1") + (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" @@ -2589,20 +4832,42 @@ return "shufpd\t{%3, %2, %0|%0, %2, %3}"; } [(set_attr "type" "sselog") + (set_attr "length_immediate" "1") (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 "prefix_data16" "1,*,*,*,*") + (set_attr "mode" "V1DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -2615,18 +4880,24 @@ 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_data16" "1,*,*,*,*") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "V1DF,DF,DF,DF,DF")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -2645,21 +4916,55 @@ 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 "prefix_data16" "1,*,*,*,*,*") + (set_attr "length_immediate" "*,*,1,*,*,*") + (set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -2672,12 +4977,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]))" "@ @@ -2686,9 +5023,13 @@ 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 "prefix_data16" "*,1,*,*,1,*,*,*") + (set_attr "length_immediate" "*,*,*,1,*,*,*,*") + (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")]) (define_split [(set (match_operand:V2DF 0 "memory_operand" "") @@ -2731,6 +5072,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 @@ -2746,6 +5104,8 @@ movhps\t{%H1, %0|%0, %H1} movhps\t{%1, %H0|%H0, %1}" [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov") + (set_attr "prefix_data16" "*,1,1,*,*,*") + (set_attr "length_immediate" "*,*,*,1,*,*") (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")]) (define_insn "*vec_dupv2df_sse3" @@ -2753,8 +5113,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" @@ -2772,10 +5133,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 @@ -2789,39 +5165,9 @@ movlhps\t{%2, %0|%0, %2} movhps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov") + (set_attr "prefix_data16" "*,1,*,*,*") (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 @@ -2836,82 +5182,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")]) @@ -2921,45 +5247,14 @@ (mult:V16QI (match_operand:V16QI 1 "register_operand" "") (match_operand:V16QI 2 "register_operand" "")))] "TARGET_SSE2 - && !(reload_completed || reload_in_progress)" + && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] { - rtx t[12], op0, op[3]; + rtx t[12]; int i; - if (TARGET_SSE5) - { - /* On SSE5, we can take advantage of the pperm instruction to pack and - unpack the bytes. Unpack data such that we've got a source byte in - each low byte of each word. We don't care what goes into the high - byte, so put 0 there. */ - for (i = 0; i < 6; ++i) - t[i] = gen_reg_rtx (V8HImode); - - for (i = 0; i < 2; i++) - { - op[0] = t[i]; - op[1] = operands[i+1]; - ix86_expand_sse5_unpack (op, true, true); /* high bytes */ - - op[0] = t[i+2]; - ix86_expand_sse5_unpack (op, true, false); /* low bytes */ - } - - /* Multiply words. */ - emit_insn (gen_mulv8hi3 (t[4], t[0], t[1])); /* high bytes */ - emit_insn (gen_mulv8hi3 (t[5], t[2], t[3])); /* low bytes */ - - /* Pack the low byte of each word back into a single xmm */ - op[0] = operands[0]; - op[1] = t[5]; - op[2] = t[4]; - ix86_expand_sse5_pack (op); - DONE; - } - for (i = 0; i < 12; ++i) t[i] = gen_reg_rtx (V16QImode); @@ -2990,8 +5285,7 @@ emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8])); /* ........ACEGIKMO */ emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8])); /* ........BDFHJLNP */ - op0 = operands[0]; - emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10])); /* ABCDEFGHIJKLMNOP */ + emit_insn (gen_sse2_punpcklbw (operands[0], t[11], t[10])); /* ABCDEFGHIJKLMNOP */ DONE; }) @@ -3002,6 +5296,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") @@ -3025,6 +5329,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 @@ -3054,25 +5374,72 @@ "TARGET_SSE2" "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);") -(define_insn "*umulv8hi3_highpart" +(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" "%0")) + (match_operand:V8HI 1 "nonimmediate_operand" "%x")) (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) (const_int 16))))] - "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)" - "pmulhuw\t{%2, %0|%0, %2}" + "TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "vpmulhuw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseimul") - (set_attr "prefix_data16" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "sse2_umulv2siv2di3" - [(set (match_operand:V2DI 0 "register_operand" "=x") - (mult:V2DI +(define_insn "*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" "%0")) + (zero_extend:V8SI + (match_operand:V8HI 2 "nonimmediate_operand" "xm"))) + (const_int 16))))] + "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)" + "pmulhuw\t{%2, %0|%0, %2}" + [(set_attr "type" "sseimul") + (set_attr "prefix_data16" "1") + (set_attr "mode" "TI")]) + +(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 (vec_select:V2SI (match_operand:V4SI 1 "nonimmediate_operand" "%0") @@ -3087,7 +5454,39 @@ (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" "%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_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 "*sse4_1_mulv2siv2di3" [(set (match_operand:V2DI 0 "register_operand" "=x") (mult:V2DI (sign_extend:V2DI @@ -3104,7 +5503,78 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -(define_insn "sse2_pmaddwd" +(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 @@ -3138,6 +5608,7 @@ "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)" "pmaddwd\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "simul") (set_attr "prefix_data16" "1") (set_attr "mode" "TI")]) @@ -3147,10 +5618,21 @@ (match_operand:V4SI 2 "register_operand" "")))] "TARGET_SSE2" { - if (TARGET_SSE4_1 || TARGET_SSE5) + if (TARGET_SSE4_1 || TARGET_XOP) 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_extra" "1") + (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") @@ -3161,37 +5643,12 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -;; 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. -(define_insn_and_split "*sse5_mulv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=&x") - (mult:V4SI (match_operand:V4SI 1 "register_operand" "%x") - (match_operand:V4SI 2 "nonimmediate_operand" "xm")))] - "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:V4SI (mult:V4SI (match_dup 1) - (match_dup 2)) - (match_dup 0)))] -{ - operands[3] = CONST0_RTX (V4SImode); -} - [(set_attr "type" "ssemuladd") - (set_attr "mode" "TI")]) - (define_insn_and_split "*sse2_mulv4si3" [(set (match_operand:V4SI 0 "register_operand" "") (mult:V4SI (match_operand:V4SI 1 "register_operand" "") (match_operand:V4SI 2 "register_operand" "")))] - "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_SSE5 - && !(reload_completed || reload_in_progress)" + "TARGET_SSE2 && !TARGET_SSE4_1 && !TARGET_XOP + && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] @@ -3244,7 +5701,7 @@ (mult:V2DI (match_operand:V2DI 1 "register_operand" "") (match_operand:V2DI 2 "register_operand" "")))] "TARGET_SSE2 - && !(reload_completed || reload_in_progress)" + && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] @@ -3252,6 +5709,42 @@ rtx t1, t2, t3, t4, t5, t6, thirtytwo; rtx op0, op1, op2; + if (TARGET_XOP) + { + /* 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_xop_pmacsdd (t3, t1, op2, t2)); + + /* t4: (B*E)+(A*F), (D*G)+(C*H) */ + emit_insn (gen_xop_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_xop_pmacsdql (op0, op1, op2, t5)); + DONE; + } + op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; @@ -3371,18 +5864,24 @@ [(match_operand:V2DI 0 "register_operand" "") (match_operand:V4SI 1 "register_operand" "") (match_operand:V4SI 2 "register_operand" "")] - "TARGET_SSE2" + "TARGET_XOP" { - 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_xop_mulv2div2di3_high (operands[0], t1, t2)); DONE; }) @@ -3390,18 +5889,24 @@ [(match_operand:V2DI 0 "register_operand" "") (match_operand:V4SI 1 "register_operand" "") (match_operand:V4SI 2 "register_operand" "")] - "TARGET_SSE2" + "TARGET_XOP" { - 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_xop_mulv2div2di3_low (operands[0], t1, t2)); DONE; }) @@ -3485,6 +5990,21 @@ 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 "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) + (set_attr "mode" "TI")]) + (define_insn "ashr3" [(set (match_operand:SSEMODE24 0 "register_operand" "=x") (ashiftrt:SSEMODE24 @@ -3494,6 +6014,25 @@ "psra\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") (set_attr "prefix_data16" "1") + (set (attr "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) + (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 "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) (set_attr "mode" "TI")]) (define_insn "lshr3" @@ -3505,6 +6044,25 @@ "psrl\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") (set_attr "prefix_data16" "1") + (set (attr "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) + (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 "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) (set_attr "mode" "TI")]) (define_insn "ashl3" @@ -3516,6 +6074,10 @@ "psll\t{%2, %0|%0, %2}" [(set_attr "type" "sseishft") (set_attr "prefix_data16" "1") + (set (attr "length_immediate") + (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "1") + (const_string "0"))) (set_attr "mode" "TI")]) (define_expand "vec_shl_" @@ -3538,6 +6100,23 @@ operands[1] = gen_lowpart (TImode, operands[1]); }) +(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_extra") + (if_then_else + (ne (symbol_ref "mode != (( == SMAX || == SMIN) ? V8HImode : V16QImode)") + (const_int 0)) + (const_string "1") + (const_string "0"))) + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_expand "v16qi3" [(set (match_operand:V16QI 0 "register_operand" "") (umaxmin:V16QI @@ -3723,19 +6302,50 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(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_XOP " + "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_extra") + (if_then_else (match_operand:V2DI 0 "" "") + (const_string "1") + (const_string "*"))) + (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") (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && !TARGET_SSE5 + "TARGET_SSE2 && !TARGET_XOP && ix86_binary_operator_ok (EQ, mode, operands)" "pcmpeq\t{%2, %0|%0, %2}" [(set_attr "type" "ssecmp") (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") @@ -3746,12 +6356,27 @@ (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_extra") + (if_then_else (match_operand:V2DI 0 "" "") + (const_string "1") + (const_string "*"))) + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "sse2_gt3" [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (gt:SSEMODE124 (match_operand:SSEMODE124 1 "register_operand" "0") (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 && !TARGET_SSE5" + "TARGET_SSE2 && !TARGET_XOP" "pcmpgt\t{%2, %0|%0, %2}" [(set_attr "type" "ssecmp") (set_attr "prefix_data16" "1") @@ -3760,43 +6385,42 @@ (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}" [(set_attr "type" "ssecmp") + (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) (define_expand "vcond" - [(set (match_operand:SSEMODEI 0 "register_operand" "") - (if_then_else:SSEMODEI + [(set (match_operand:SSEMODE124C8 0 "register_operand" "") + (if_then_else:SSEMODE124C8 (match_operator 3 "" - [(match_operand:SSEMODEI 4 "nonimmediate_operand" "") - (match_operand:SSEMODEI 5 "nonimmediate_operand" "")]) - (match_operand:SSEMODEI 1 "general_operand" "") - (match_operand:SSEMODEI 2 "general_operand" "")))] + [(match_operand:SSEMODE124C8 4 "nonimmediate_operand" "") + (match_operand:SSEMODE124C8 5 "nonimmediate_operand" "")]) + (match_operand:SSEMODE124C8 1 "general_operand" "") + (match_operand:SSEMODE124C8 2 "general_operand" "")))] "TARGET_SSE2" { - if (ix86_expand_int_vcond (operands)) - DONE; - else - FAIL; + bool ok = ix86_expand_int_vcond (operands); + gcc_assert (ok); + DONE; }) (define_expand "vcondu" - [(set (match_operand:SSEMODEI 0 "register_operand" "") - (if_then_else:SSEMODEI + [(set (match_operand:SSEMODE124C8 0 "register_operand" "") + (if_then_else:SSEMODE124C8 (match_operator 3 "" - [(match_operand:SSEMODEI 4 "nonimmediate_operand" "") - (match_operand:SSEMODEI 5 "nonimmediate_operand" "")]) - (match_operand:SSEMODEI 1 "general_operand" "") - (match_operand:SSEMODEI 2 "general_operand" "")))] + [(match_operand:SSEMODE124C8 4 "nonimmediate_operand" "") + (match_operand:SSEMODE124C8 5 "nonimmediate_operand" "")]) + (match_operand:SSEMODE124C8 1 "general_operand" "") + (match_operand:SSEMODE124C8 2 "general_operand" "")))] "TARGET_SSE2" { - if (ix86_expand_int_vcond (operands)) - DONE; - else - FAIL; + bool ok = ix86_expand_int_vcond (operands); + gcc_assert (ok); + DONE; }) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3820,46 +6444,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")) @@ -3870,125 +6487,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") + (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" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*sse2_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_SSE2 && ix86_binary_operator_ok (IOR, mode, operands)" - "por\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 "iortf3" +(define_expand "tf3" [(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);") + (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 "*iortf3" +(define_insn "*tf3" [(set (match_operand:TF 0 "register_operand" "=x") - (ior:TF + (plogic: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}" - [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") - (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" - [(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_SSE2 && ix86_binary_operator_ok (XOR, mode, operands)" - "pxor\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "prefix_data16" "1") - (set_attr "mode" "TI")]) - -(define_expand "xortf3" - [(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);") - -(define_insn "*xortf3" - [(set (match_operand:TF 0 "register_operand" "=x") - (xor: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")]) @@ -4220,6 +6798,59 @@ DONE; }) +(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 @@ -4233,6 +6864,19 @@ (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 @@ -4246,6 +6890,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 @@ -4259,6 +6916,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 @@ -4279,6 +6956,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 @@ -4299,6 +6996,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 @@ -4315,6 +7028,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 @@ -4331,6 +7060,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 @@ -4345,46 +7088,53 @@ (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_extra") + (if_then_else (match_operand:V8HI 0 "register_operand" "") + (const_string "0") + (const_string "1"))) + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pinsrb" @@ -4401,6 +7151,7 @@ } [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_insn "*sse2_pinsrw" @@ -4417,6 +7168,7 @@ } [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) ;; It must come before sse2_loadld since it is preferred. @@ -4434,6 +7186,25 @@ } [(set_attr "type" "sselog") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "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_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pinsrq" @@ -4443,13 +7214,15 @@ (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}"; } [(set_attr "type" "sselog") + (set_attr "prefix_rex" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrb" @@ -4459,9 +7232,11 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrb_memory" @@ -4470,9 +7245,11 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse2_pextrw" @@ -4482,9 +7259,11 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrw_memory" @@ -4493,9 +7272,11 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse4_1_pextrd" @@ -4504,9 +7285,11 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) ;; It must come before *vec_extractv2di_1_sse since it is preferred. @@ -4516,9 +7299,12 @@ (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_rex" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_expand "sse2_pshufd" @@ -4553,10 +7339,12 @@ 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" "maybe_vex") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_expand "sse2_pshuflw" @@ -4595,10 +7383,13 @@ 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_data16" "0") (set_attr "prefix_rep" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_expand "sse2_pshufhw" @@ -4637,10 +7428,13 @@ 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_data16" "0") + (set_attr "prefix" "maybe_vex") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_expand "sse2_loadd" @@ -4653,6 +7447,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 @@ -4710,7 +7520,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)])))] @@ -4718,8 +7528,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" @@ -4745,6 +7556,25 @@ 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 "length_immediate" "*,1,*,*") + (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 @@ -4757,9 +7587,29 @@ movq\t{%H1, %0|%0, %H1} mov{q}\t{%H1, %0|%0, %H1}" [(set_attr "type" "ssemov,sseishft,ssemov,imov") + (set_attr "length_immediate" "*,1,*,*") + (set_attr "atom_unit" "*,sishuf,*,*") (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 "length_immediate" "*,1,*") + (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 @@ -4772,6 +7622,8 @@ psrldq\t{$8, %0|%0, 8} movq\t{%H1, %0|%0, %H1}" [(set_attr "type" "ssemov,sseishft,ssemov") + (set_attr "length_immediate" "*,1,*") + (set_attr "atom_unit" "*,sishuf,*") (set_attr "memory" "*,none,*") (set_attr "mode" "V2SF,TI,TI")]) @@ -4796,11 +7648,23 @@ (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 "length_immediate" "1") (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 @@ -4812,14 +7676,52 @@ [(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_extra" "1,*,*,*,*") + (set_attr "length_immediate" "1,*,*,*,*") + (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 "length_immediate" "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} @@ -4829,7 +7731,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") @@ -4843,6 +7745,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 @@ -4856,162 +7771,97 @@ [(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" " 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" " 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_extra" "1,*,*,*,*,*") + (set_attr "length_immediate" "1,*,*,*,*,*") + (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" " 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")]) - -(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; -}) + movhps\t{%2, %0|%0, %2}" + [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov,ssemov") + (set_attr "prefix_rex" "1,*,1,*,*,*,*") + (set_attr "prefix_extra" "1,*,*,*,*,*,*") + (set_attr "length_immediate" "1,*,*,*,*,*,*") + (set_attr "mode" "TI,TI,TI,TI,TI,V4SF,V2SF")]) + +(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 "prefix_rex" "*,1,*,*,*,*") + (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF")]) (define_expand "vec_unpacku_hi_v16qi" [(match_operand:V8HI 0 "register_operand" "") @@ -5020,8 +7870,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, true); else ix86_expand_sse_unpack (operands, true, true); DONE; @@ -5034,8 +7882,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, true); else ix86_expand_sse_unpack (operands, false, true); DONE; @@ -5048,8 +7894,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, false); else ix86_expand_sse_unpack (operands, true, false); DONE; @@ -5062,8 +7906,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, false); else ix86_expand_sse_unpack (operands, false, false); DONE; @@ -5076,8 +7918,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, true); else ix86_expand_sse_unpack (operands, true, true); DONE; @@ -5090,8 +7930,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, true); else ix86_expand_sse_unpack (operands, false, true); DONE; @@ -5104,8 +7942,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, false); else ix86_expand_sse_unpack (operands, true, false); DONE; @@ -5118,8 +7954,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, false); else ix86_expand_sse_unpack (operands, false, false); DONE; @@ -5132,8 +7966,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, true); else ix86_expand_sse_unpack (operands, true, true); DONE; @@ -5146,8 +7978,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, true); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, true); else ix86_expand_sse_unpack (operands, false, true); DONE; @@ -5160,8 +7990,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, true, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, true, false); else ix86_expand_sse_unpack (operands, true, false); DONE; @@ -5174,8 +8002,6 @@ { if (TARGET_SSE4_1) ix86_expand_sse4_unpack (operands, false, false); - else if (TARGET_SSE5) - ix86_expand_sse5_unpack (operands, false, false); else ix86_expand_sse_unpack (operands, false, false); DONE; @@ -5187,7 +8013,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 @@ -5212,7 +8085,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 @@ -5235,6 +8147,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") @@ -5243,17 +8166,30 @@ "TARGET_SSE2" "psadbw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "simul") (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}" - [(set_attr "type" "ssecvt") + "%vmovmskp\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "")]) (define_insn "sse2_pmovmskb" @@ -5261,9 +8197,10 @@ (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")] UNSPEC_MOVMSK))] "TARGET_SSE2" - "pmovmskb\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") + "%vpmovmskb\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") (set_attr "prefix_data16" "1") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "SI")]) (define_expand "sse2_maskmovdqu" @@ -5283,9 +8220,12 @@ UNSPEC_MASKMOV))] "TARGET_SSE2 && !TARGET_64BIT" ;; @@@ check ordering of operands in intel/nonintel syntax - "maskmovdqu\t{%2, %1|%1, %2}" - [(set_attr "type" "ssecvt") + "%vmaskmovdqu\t{%2, %1|%1, %2}" + [(set_attr "type" "ssemov") (set_attr "prefix_data16" "1") + ;; The implicit %rdi operand confuses default length_vex computation. + (set_attr "length_vex" "3") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn "*sse2_maskmovdqu_rex64" @@ -5296,25 +8236,33 @@ UNSPEC_MASKMOV))] "TARGET_SSE2 && TARGET_64BIT" ;; @@@ check ordering of operands in intel/nonintel syntax - "maskmovdqu\t{%2, %1|%1, %2}" - [(set_attr "type" "ssecvt") + "%vmaskmovdqu\t{%2, %1|%1, %2}" + [(set_attr "type" "ssemov") (set_attr "prefix_data16" "1") + ;; The implicit %rdi operand confuses default length_vex computation. + (set (attr "length_vex") + (symbol_ref ("REGNO (operands[2]) >= FIRST_REX_SSE_REG ? 3 + 1 : 2 + 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 "atom_sse_attr" "mxcsr") + (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 "atom_sse_attr" "mxcsr") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "store")]) (define_expand "sse_sfence" @@ -5332,6 +8280,8 @@ "TARGET_SSE || TARGET_3DNOW_A" "sfence" [(set_attr "type" "sse") + (set_attr "length_address" "0") + (set_attr "atom_sse_attr" "fence") (set_attr "memory" "unknown")]) (define_insn "sse2_clflush" @@ -5340,6 +8290,7 @@ "TARGET_SSE2" "clflush\t%a0" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "fence") (set_attr "memory" "unknown")]) (define_expand "sse2_mfence" @@ -5354,9 +8305,11 @@ (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 "length_address" "0") + (set_attr "atom_sse_attr" "fence") (set_attr "memory" "unknown")]) (define_expand "sse2_lfence" @@ -5374,6 +8327,8 @@ "TARGET_SSE2" "lfence" [(set_attr "type" "sse") + (set_attr "length_address" "0") + (set_attr "atom_sse_attr" "lfence") (set_attr "memory" "unknown")]) (define_insn "sse3_mwait" @@ -5414,6 +8369,50 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phaddwv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5454,6 +8453,7 @@ "TARGET_SSSE3" "phaddw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5482,9 +8482,39 @@ "TARGET_SSSE3" "phaddw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phadddv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_concat:V4SI @@ -5509,6 +8539,7 @@ "TARGET_SSSE3" "phaddd\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5529,17 +8560,63 @@ "TARGET_SSSE3" "phaddd\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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 + (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_AVX" + "vphaddsw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "sseiadd") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(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 @@ -5572,6 +8649,7 @@ "TARGET_SSSE3" "phaddsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5600,9 +8678,55 @@ "TARGET_SSSE3" "phaddsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubwv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5643,6 +8767,7 @@ "TARGET_SSSE3" "phsubw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5671,9 +8796,39 @@ "TARGET_SSSE3" "phsubw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubdv4si3" [(set (match_operand:V4SI 0 "register_operand" "=x") (vec_concat:V4SI @@ -5698,6 +8853,7 @@ "TARGET_SSSE3" "phsubd\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5718,9 +8874,55 @@ "TARGET_SSSE3" "phsubd\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_phsubswv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI @@ -5761,6 +8963,7 @@ "TARGET_SSSE3" "phsubsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) @@ -5789,16 +8992,72 @@ "TARGET_SSSE3" "phsubsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "complex") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (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) @@ -5842,17 +9101,18 @@ "TARGET_SSSE3" "pmaddubsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "simul") (set_attr "prefix_data16" "1") (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) @@ -5880,10 +9140,56 @@ "TARGET_SSSE3" "pmaddubsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseiadd") + (set_attr "atom_unit" "simul") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + +(define_insn "*ssse3_pmulhrswv8hi3" [(set (match_operand:V8HI 0 "register_operand" "=x") (truncate:V8HI (lshiftrt:V8SI @@ -5907,7 +9213,25 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "TI")]) -(define_insn "ssse3_pmulhrswv4hi3" +(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" "")) + (sign_extend:V4SI + (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_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + +(define_insn "*ssse3_pmulhrswv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") (truncate:V4HI (lshiftrt:V4SI @@ -5926,8 +9250,21 @@ "pmulhrsw\t{%2, %0|%0, %2}" [(set_attr "type" "sseimul") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (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") @@ -5949,8 +9286,22 @@ "pshufb\t{%2, %0|%0, %2}"; [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "TI")]) + (define_insn "ssse3_psign3" [(set (match_operand:SSEMODE124 0 "register_operand" "=x") (unspec:SSEMODE124 @@ -5974,8 +9325,26 @@ "psign\t{%2, %0|%0, %2}"; [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (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_extra" "1") + (set_attr "length_immediate" "1") + (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") @@ -5988,8 +9357,10 @@ return "palignr\t{%3, %2, %0|%0, %2, %3}"; } [(set_attr "type" "sseishft") + (set_attr "atom_unit" "sishuf") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_insn "ssse3_palignrdi" @@ -6004,17 +9375,21 @@ return "palignr\t{%3, %2, %0|%0, %2, %3}"; } [(set_attr "type" "sseishft") + (set_attr "atom_unit" "sishuf") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (set_attr "mode" "DI")]) (define_insn "abs2" [(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" @@ -6023,7 +9398,9 @@ "TARGET_SSSE3" "pabs\t{%1, %0|%0, %1}"; [(set_attr "type" "sselog1") + (set_attr "prefix_rep" "0") (set_attr "prefix_extra" "1") + (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)")) (set_attr "mode" "DI")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -6064,6 +9441,7 @@ "extrq\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "sse") (set_attr "prefix_data16" "1") + (set_attr "length_immediate" "2") (set_attr "mode" "TI")]) (define_insn "sse4a_extrq" @@ -6087,7 +9465,9 @@ "TARGET_SSE4A" "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}" [(set_attr "type" "sseins") + (set_attr "prefix_data16" "0") (set_attr "prefix_rep" "1") + (set_attr "length_immediate" "2") (set_attr "mode" "TI")]) (define_insn "sse4a_insertq" @@ -6098,6 +9478,7 @@ "TARGET_SSE4A" "insertq\t{%2, %0|%0, %2}" [(set_attr "type" "sseins") + (set_attr "prefix_data16" "0") (set_attr "prefix_rep" "1") (set_attr "mode" "TI")]) @@ -6107,6 +9488,35 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse4_1_blendp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P @@ -6116,7 +9526,9 @@ "TARGET_SSE4_1" "blendp\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssemov") + (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "")]) (define_insn "sse4_1_blendvp" @@ -6129,9 +9541,25 @@ "TARGET_SSE4_1" "blendvp\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssemov") + (set_attr "prefix_data16" "1") (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "mode" "")]) + (define_insn "sse4_1_dpp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P @@ -6142,7 +9570,9 @@ "TARGET_SSE4_1" "dpp\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssemul") + (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "")]) (define_insn "sse4_1_movntdqa" @@ -6150,9 +9580,24 @@ (unspec:V2DI [(match_operand:V2DI 1 "memory_operand" "m")] UNSPEC_MOVNTDQA))] "TARGET_SSE4_1" - "movntdqa\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") + "%vmovntdqa\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 "*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 "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_insn "sse4_1_mpsadbw" @@ -6165,6 +9610,21 @@ "mpsadbw\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "sselog1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "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_extra" "1") + (set_attr "prefix" "vex") (set_attr "mode" "TI")]) (define_insn "sse4_1_packusdw" @@ -6180,6 +9640,20 @@ (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_extra" "1") + (set_attr "length_immediate" "1") + (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") @@ -6192,6 +9666,20 @@ (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 "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + (define_insn "sse4_1_pblendw" [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_merge:V8HI @@ -6202,6 +9690,7 @@ "pblendw\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) (define_insn "sse4_1_phminposuw" @@ -6209,9 +9698,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" @@ -6228,9 +9718,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" @@ -6248,9 +9739,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" @@ -6263,9 +9755,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" @@ -6279,9 +9772,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" @@ -6292,9 +9786,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" @@ -6306,9 +9801,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" @@ -6321,9 +9817,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" @@ -6337,9 +9834,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" @@ -6350,9 +9848,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" @@ -6364,9 +9863,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" @@ -6377,9 +9877,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" @@ -6391,9 +9892,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" @@ -6410,9 +9912,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" @@ -6430,9 +9933,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" @@ -6445,9 +9949,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" @@ -6461,9 +9966,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" @@ -6474,9 +9980,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" @@ -6488,9 +9995,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" @@ -6503,9 +10011,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" @@ -6519,9 +10028,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" @@ -6532,9 +10042,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" @@ -6546,9 +10057,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" @@ -6559,9 +10071,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" @@ -6573,24 +10086,66 @@ (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_extra" "1") + (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_extra" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "")]) + (define_insn "sse4_1_roundp" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P @@ -6598,9 +10153,29 @@ (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_data16" "1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "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_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") (set_attr "mode" "")]) (define_insn "sse4_1_rounds" @@ -6615,7 +10190,9 @@ "TARGET_ROUND" "rounds\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssecvt") + (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "mode" "")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -6650,7 +10227,7 @@ (match_dup 6)] UNSPEC_PCMPESTR))] "TARGET_SSE4_2 - && !(reload_completed || reload_in_progress)" + && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] @@ -6677,6 +10254,7 @@ [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6698,10 +10276,12 @@ (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 "length_immediate" "1") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6723,10 +10303,12 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6743,14 +10325,16 @@ (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 "length_immediate" "1") (set_attr "memory" "none,load,none,load") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) (define_insn_and_split "sse4_2_pcmpistr" @@ -6773,7 +10357,7 @@ (match_dup 4)] UNSPEC_PCMPISTR))] "TARGET_SSE4_2 - && !(reload_completed || reload_in_progress)" + && can_create_pseudo_p ()" "#" "&& 1" [(const_int 0)] @@ -6797,6 +10381,7 @@ [(set_attr "type" "sselog") (set_attr "prefix_data16" "1") (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6814,10 +10399,12 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6835,10 +10422,12 @@ (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") (set_attr "memory" "none,load") (set_attr "mode" "TI")]) @@ -6853,39 +10442,40 @@ (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 "length_immediate" "1") (set_attr "memory" "none,load,none,load") + (set_attr "prefix" "maybe_vex") (set_attr "mode" "TI")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; SSE5 instructions +;; XOP instructions ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; SSE5 parallel integer multiply/add instructions. +;; XOP parallel integer multiply/add instructions. ;; Note the instruction does not allow the value being added to be a memory ;; operation. However by pretending via the nonimmediate_operand predicate ;; that it does and splitting it later allows the following to be recognized: ;; a[i] = b[i] * c[i] + d[i]; -(define_insn "sse5_pmacsww" - [(set (match_operand:V8HI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacsww" + [(set (match_operand:V8HI 0 "register_operand" "=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,m") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x")) + (match_operand:V8HI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacsww\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacsww\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) @@ -6896,31 +10486,30 @@ (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "") (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) + "TARGET_XOP + && !ix86_fma4_valid_op_p (operands, insn, 4, false, 1, true) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, V8HImode); - emit_insn (gen_sse5_pmacsww (operands[0], operands[1], operands[2], - operands[3])); + ix86_expand_fma4_multiple_memory (operands, 4, V8HImode); + emit_insn (gen_xop_pmacsww (operands[0], operands[1], operands[2], + operands[3])); DONE; }) -(define_insn "sse5_pmacssww" - [(set (match_operand:V8HI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacssww" + [(set (match_operand:V8HI 0 "register_operand" "=x,x") (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)" + (mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x,m") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x")) + (match_operand:V8HI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacssww\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacssww\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) @@ -6928,18 +10517,17 @@ ;; operation. However by pretending via the nonimmediate_operand predicate ;; that it does and splitting it later allows the following to be recognized: ;; a[i] = b[i] * c[i] + d[i]; -(define_insn "sse5_pmacsdd" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacsdd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (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, 2)" + (match_operand:V4SI 1 "nonimmediate_operand" "%x,m") + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x")) + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacsdd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacsdd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) @@ -6950,195 +10538,350 @@ (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "") (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) + "TARGET_XOP + && !ix86_fma4_valid_op_p (operands, insn, 4, false, 1, true) + && ix86_fma4_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])" [(const_int 0)] { - ix86_expand_sse5_multiple_memory (operands, 4, V4SImode); - emit_insn (gen_sse5_pmacsdd (operands[0], operands[1], operands[2], - operands[3])); + ix86_expand_fma4_multiple_memory (operands, 4, V4SImode); + emit_insn (gen_xop_pmacsdd (operands[0], operands[1], operands[2], + operands[3])); DONE; }) -(define_insn "sse5_pmacssdd" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacssdd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (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)" + (mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,m") + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x")) + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacssdd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacssdd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmacssdql" - [(set (match_operand:V2DI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacssdql" + [(set (match_operand:V2DI 0 "register_operand" "=x,x") (ss_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,m") (parallel [(const_int 1) (const_int 3)]))) - (vec_select:V2SI - (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") - (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)" + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") + (parallel [(const_int 1) + (const_int 3)]))) + (match_operand:V2DI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacssdql\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacssdql\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmacssdqh" - [(set (match_operand:V2DI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacssdqh" + [(set (match_operand:V2DI 0 "register_operand" "=x,x") (ss_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,m") (parallel [(const_int 0) (const_int 2)]))) (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") (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)" + (match_operand:V2DI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacssdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacssdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmacsdql" - [(set (match_operand:V2DI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacsdql" + [(set (match_operand:V2DI 0 "register_operand" "=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,m") (parallel [(const_int 1) (const_int 3)]))) (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") (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)" + (match_operand:V2DI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacsdql\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacsdql\t{%3, %1, %2, %0|%0, %2, %1, %3}" + [(set_attr "type" "ssemuladd") + (set_attr "mode" "TI")]) + +(define_insn_and_split "*xop_pmacsdql_mem" + [(set (match_operand:V2DI 0 "register_operand" "=&x,&x") + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x,m") + (parallel [(const_int 1) + (const_int 3)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") + (parallel [(const_int 1) + (const_int 3)])))) + (match_operand:V2DI 3 "memory_operand" "m,m")))] + "TARGET_XOP && ix86_fma4_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 XOP, 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 "xop_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_XOP" + "#" + "&& (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") +(define_insn "xop_pmacsdqh" + [(set (match_operand:V2DI 0 "register_operand" "=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,m") (parallel [(const_int 0) (const_int 2)]))) (sign_extend:V2DI (vec_select:V2SI - (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") (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)" + (match_operand:V2DI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacsdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacsdqh\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(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") +(define_insn_and_split "*xop_pmacsdqh_mem" + [(set (match_operand:V2DI 0 "register_operand" "=&x,&x") + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "nonimmediate_operand" "%x,m") + (parallel [(const_int 0) + (const_int 2)]))) + (sign_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "nonimmediate_operand" "xm,x") + (parallel [(const_int 0) + (const_int 2)])))) + (match_operand:V2DI 3 "memory_operand" "m,m")))] + "TARGET_XOP && ix86_fma4_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 XOP, 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 "xop_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_XOP" + "#" + "&& (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")]) + +;; XOP parallel integer multiply/add instructions for the intrinisics +(define_insn "xop_pmacsswd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (ss_plus:V4SI (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,m") (parallel [(const_int 1) (const_int 3) (const_int 5) (const_int 7)]))) (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x") (parallel [(const_int 1) (const_int 3) (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)" + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmacswd" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmacswd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (plus:V4SI (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,m") (parallel [(const_int 1) (const_int 3) (const_int 5) (const_int 7)]))) (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x") (parallel [(const_int 1) (const_int 3) (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)" + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmacswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmacswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmadcsswd" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmadcsswd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (ss_plus:V4SI (plus:V4SI (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,m") (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" "x,m,x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -7158,30 +10901,29 @@ (const_int 3) (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)" + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmadcsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmadcsswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -(define_insn "sse5_pmadcswd" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") +(define_insn "xop_pmadcswd" + [(set (match_operand:V4SI 0 "register_operand" "=x,x") (plus:V4SI (plus:V4SI (mult:V4SI (sign_extend:V4SI (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V8HI 1 "nonimmediate_operand" "%x,m") (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" "x,m,x") + (match_operand:V8HI 2 "nonimmediate_operand" "xm,x") (parallel [(const_int 0) (const_int 2) (const_int 4) @@ -7201,34 +10943,37 @@ (const_int 3) (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)" + (match_operand:V4SI 3 "register_operand" "x,x")))] + "TARGET_XOP && ix86_fma4_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} - pmadcswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" + vpmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3} + vpmadcswd\t{%3, %1, %2, %0|%0, %2, %1, %3}" [(set_attr "type" "ssemuladd") (set_attr "mode" "TI")]) -;; SSE5 parallel XMM conditional moves -(define_insn "sse5_pcmov_" - [(set (match_operand:SSEMODE 0 "register_operand" "=x,x,x,x,x,x") +;; XOP parallel XMM conditional moves +(define_insn "xop_pcmov_" + [(set (match_operand:SSEMODE 0 "register_operand" "=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)" - "@ - 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}" + (match_operand:SSEMODE 3 "nonimmediate_operand" "x,x,m") + (match_operand:SSEMODE 1 "vector_move_operand" "x,m,x") + (match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x")))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sse4arg")]) + +(define_insn "xop_pcmov_256" + [(set (match_operand:AVX256MODE 0 "register_operand" "=x,x,x") + (if_then_else:AVX256MODE + (match_operand:AVX256MODE 3 "nonimmediate_operand" "x,x,m") + (match_operand:AVX256MODE 1 "vector_move_operand" "x,m,x") + (match_operand:AVX256MODE 2 "vector_move_operand" "xm,x,x")))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg")]) -;; SSE5 horizontal add/subtract instructions -(define_insn "sse5_phaddbw" +;; XOP horizontal add/subtract instructions +(define_insn "xop_phaddbw" [(set (match_operand:V8HI 0 "register_operand" "=x") (plus:V8HI (sign_extend:V8HI @@ -7253,11 +10998,11 @@ (const_int 11) (const_int 13) (const_int 15)])))))] - "TARGET_SSE5" - "phaddbw\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddbw\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddbd" +(define_insn "xop_phaddbd" [(set (match_operand:V4SI 0 "register_operand" "=x") (plus:V4SI (plus:V4SI @@ -7290,11 +11035,11 @@ (const_int 7) (const_int 11) (const_int 15)]))))))] - "TARGET_SSE5" - "phaddbd\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddbd\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddbq" +(define_insn "xop_phaddbq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (plus:V2DI @@ -7343,11 +11088,11 @@ (match_dup 1) (parallel [(const_int 11) (const_int 15)])))))))] - "TARGET_SSE5" - "phaddbq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddbq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddwd" +(define_insn "xop_phaddwd" [(set (match_operand:V4SI 0 "register_operand" "=x") (plus:V4SI (sign_extend:V4SI @@ -7364,11 +11109,11 @@ (const_int 3) (const_int 5) (const_int 7)])))))] - "TARGET_SSE5" - "phaddwd\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddwd\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddwq" +(define_insn "xop_phaddwq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (plus:V2DI @@ -7393,11 +11138,11 @@ (match_dup 1) (parallel [(const_int 3) (const_int 7)]))))))] - "TARGET_SSE5" - "phaddwq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddwq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phadddq" +(define_insn "xop_phadddq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (sign_extend:V2DI @@ -7410,11 +11155,11 @@ (match_dup 1) (parallel [(const_int 1) (const_int 3)])))))] - "TARGET_SSE5" - "phadddq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphadddq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddubw" +(define_insn "xop_phaddubw" [(set (match_operand:V8HI 0 "register_operand" "=x") (plus:V8HI (zero_extend:V8HI @@ -7439,11 +11184,11 @@ (const_int 11) (const_int 13) (const_int 15)])))))] - "TARGET_SSE5" - "phaddubw\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddubw\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddubd" +(define_insn "xop_phaddubd" [(set (match_operand:V4SI 0 "register_operand" "=x") (plus:V4SI (plus:V4SI @@ -7476,11 +11221,11 @@ (const_int 7) (const_int 11) (const_int 15)]))))))] - "TARGET_SSE5" - "phaddubd\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddubd\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddubq" +(define_insn "xop_phaddubq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (plus:V2DI @@ -7529,11 +11274,11 @@ (match_dup 1) (parallel [(const_int 11) (const_int 15)])))))))] - "TARGET_SSE5" - "phaddubq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddubq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phadduwd" +(define_insn "xop_phadduwd" [(set (match_operand:V4SI 0 "register_operand" "=x") (plus:V4SI (zero_extend:V4SI @@ -7550,11 +11295,11 @@ (const_int 3) (const_int 5) (const_int 7)])))))] - "TARGET_SSE5" - "phadduwd\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphadduwd\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phadduwq" +(define_insn "xop_phadduwq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (plus:V2DI @@ -7579,11 +11324,11 @@ (match_dup 1) (parallel [(const_int 3) (const_int 7)]))))))] - "TARGET_SSE5" - "phadduwq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphadduwq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phaddudq" +(define_insn "xop_phaddudq" [(set (match_operand:V2DI 0 "register_operand" "=x") (plus:V2DI (zero_extend:V2DI @@ -7596,11 +11341,11 @@ (match_dup 1) (parallel [(const_int 1) (const_int 3)])))))] - "TARGET_SSE5" - "phaddudq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphaddudq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phsubbw" +(define_insn "xop_phsubbw" [(set (match_operand:V8HI 0 "register_operand" "=x") (minus:V8HI (sign_extend:V8HI @@ -7625,11 +11370,11 @@ (const_int 11) (const_int 13) (const_int 15)])))))] - "TARGET_SSE5" - "phsubbw\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphsubbw\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phsubwd" +(define_insn "xop_phsubwd" [(set (match_operand:V4SI 0 "register_operand" "=x") (minus:V4SI (sign_extend:V4SI @@ -7646,11 +11391,11 @@ (const_int 3) (const_int 5) (const_int 7)])))))] - "TARGET_SSE5" - "phsubwd\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphsubwd\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -(define_insn "sse5_phsubdq" +(define_insn "xop_phsubdq" [(set (match_operand:V2DI 0 "register_operand" "=x") (minus:V2DI (sign_extend:V2DI @@ -7663,227 +11408,383 @@ (match_dup 1) (parallel [(const_int 1) (const_int 3)])))))] - "TARGET_SSE5" - "phsubdq\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vphsubdq\t{%1, %0|%0, %1}" [(set_attr "type" "sseiadd1")]) -;; SSE5 permute instructions -(define_insn "sse5_pperm" - [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x") +;; XOP permute instructions +(define_insn "xop_pperm" + [(set (match_operand:V16QI 0 "register_operand" "=x,x,x") (unspec:V16QI - [(match_operand:V16QI 1 "nonimmediate_operand" "0,0,x,xm") - (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)" - "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(match_operand:V16QI 1 "nonimmediate_operand" "x,x,m") + (match_operand:V16QI 2 "nonimmediate_operand" "x,m,x") + (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,x")] + UNSPEC_XOP_PERMUTE))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) -;; The following are for the various unpack insns which doesn't need the first -;; source operand, so we can just use the output operand for the first operand. -;; This allows either of the other two operands to be a memory operand. We -;; can't just use the first operand as an argument to the normal pperm because -;; then an output only argument, suddenly becomes an input operand. -(define_insn "sse5_pperm_zero_v16qi_v8hi" - [(set (match_operand:V8HI 0 "register_operand" "=x,x") - (zero_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V16QImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") +;; XOP pack instructions that combine two vectors into a smaller vector +(define_insn "xop_pperm_pack_v2di_v4si" + [(set (match_operand:V4SI 0 "register_operand" "=x,x,x") + (vec_concat:V4SI + (truncate:V2SI + (match_operand:V2DI 1 "nonimmediate_operand" "x,x,m")) + (truncate:V2SI + (match_operand:V2DI 2 "nonimmediate_operand" "x,m,x")))) + (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,x"))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) -(define_insn "sse5_pperm_sign_v16qi_v8hi" - [(set (match_operand:V8HI 0 "register_operand" "=x,x") - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V16QImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") +(define_insn "xop_pperm_pack_v4si_v8hi" + [(set (match_operand:V8HI 0 "register_operand" "=x,x,x") + (vec_concat:V8HI + (truncate:V4HI + (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")) + (truncate:V4HI + (match_operand:V4SI 2 "nonimmediate_operand" "x,m,x")))) + (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,x"))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) -(define_insn "sse5_pperm_zero_v8hi_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=x,x") - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V8HImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") +(define_insn "xop_pperm_pack_v8hi_v16qi" + [(set (match_operand:V16QI 0 "register_operand" "=x,x,x") + (vec_concat:V16QI + (truncate:V8QI + (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")) + (truncate:V8QI + (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x")))) + (use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,x"))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)" + "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sse4arg") (set_attr "mode" "TI")]) -(define_insn "sse5_pperm_sign_v8hi_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=x,x") - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V8HImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") - (set_attr "mode" "TI")]) +;; XOP packed rotate instructions +(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_XOP" +{ + /* 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; -(define_insn "sse5_pperm_zero_v4si_v2di" - [(set (match_operand:V2DI 0 "register_operand" "=x,x") - (zero_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V4SImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") - (set_attr "mode" "TI")]) + if (GET_MODE (op2) != mode) + { + op2 = gen_reg_rtx (mode); + convert_move (op2, operands[2], false); + } -(define_insn "sse5_pperm_sign_v4si_v2di" - [(set (match_operand:V2DI 0 "register_operand" "=x,x") - (sign_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "nonimmediate_operand" "xm,x") - (match_operand 2 "" "")))) ;; parallel with const_int's - (use (match_operand:V16QI 3 "nonimmediate_operand" "x,xm"))] - "TARGET_SSE5 - && (register_operand (operands[1], V4SImode) - || register_operand (operands[2], V16QImode))" - "pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}" - [(set_attr "type" "sseadd") - (set_attr "mode" "TI")]) + for (i = 0; i < ; i++) + RTVEC_ELT (vs, i) = op2; -;; SSE5 pack instructions that combine two vectors into a smaller vector -(define_insn "sse5_pperm_pack_v2di_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=x,x,x,x") - (vec_concat:V4SI - (truncate:V2SI - (match_operand:V2DI 1 "nonimmediate_operand" "0,0,x,xm")) - (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)" - "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" - [(set_attr "type" "sse4arg") - (set_attr "mode" "TI")]) + emit_insn (gen_vec_init (reg, par)); + emit_insn (gen_xop_vrotl3 (operands[0], operands[1], reg)); + DONE; + } +}) -(define_insn "sse5_pperm_pack_v4si_v8hi" - [(set (match_operand:V8HI 0 "register_operand" "=x,x,x,x") - (vec_concat:V8HI - (truncate:V4HI - (match_operand:V4SI 1 "nonimmediate_operand" "0,0,x,xm")) - (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)" - "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" - [(set_attr "type" "sse4arg") - (set_attr "mode" "TI")]) +(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_XOP" +{ + /* 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); + } -(define_insn "sse5_pperm_pack_v8hi_v16qi" - [(set (match_operand:V16QI 0 "register_operand" "=x,x,x,x") - (vec_concat:V16QI - (truncate:V8QI - (match_operand:V8HI 1 "nonimmediate_operand" "0,0,x,xm")) - (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)" - "pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}" - [(set_attr "type" "sse4arg") - (set_attr "mode" "TI")]) + for (i = 0; i < ; i++) + RTVEC_ELT (vs, i) = op2; -;; Floating point permutation (permps, permpd) -(define_insn "sse5_perm" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x,x,x,x") - (unspec:SSEMODEF2P - [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm") - (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)" - "perm\t{%3, %2, %1, %0|%0, %1, %2, %3}" - [(set_attr "type" "sse4arg") - (set_attr "mode" "")]) + emit_insn (gen_vec_init (reg, par)); + emit_insn (gen_neg2 (neg, reg)); + emit_insn (gen_xop_vrotl3 (operands[0], operands[1], neg)); + DONE; + } +}) -;; SSE5 packed rotate instructions -(define_insn "rotl3" +(define_insn "xop_rotl3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (rotate:SSEMODE1248 (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm") (match_operand:SI 2 "const_0_to__operand" "n")))] - "TARGET_SSE5" - "prot\t{%2, %1, %0|%0, %1, %2}" + "TARGET_XOP" + "vprot\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) -(define_insn "sse5_rotl3" +(define_insn "xop_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_XOP" +{ + operands[3] = GEN_INT (( * 8) - INTVAL (operands[2])); + return \"vprot\t{%3, %1, %0|%0, %1, %3}\"; +} + [(set_attr "type" "sseishft") + (set_attr "length_immediate" "1") + (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_XOP" +{ + rtx reg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (reg, operands[2])); + emit_insn (gen_xop_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_XOP" +{ + emit_insn (gen_xop_vrotl3 (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "xop_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)" - "prot\t{%2, %1, %0|%0, %1, %2}" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m") + (const_int 0)) + (rotate:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x") + (match_dup 2)) + (rotatert:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 3, true, 1, false)" + "vprot\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") + (set_attr "prefix_data16" "0") + (set_attr "prefix_extra" "2") (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 -(define_insn "sse5_ashl3" +;; XOP 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_XOP" +{ + rtx neg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (neg, operands[2])); + emit_insn (gen_xop_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_XOP" +{ + rtx neg = gen_reg_rtx (mode); + emit_insn (gen_neg2 (neg, operands[2])); + emit_insn (gen_xop_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_XOP" +{ + emit_insn (gen_xop_ashl3 (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "xop_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)" - "psha\t{%2, %1, %0|%0, %1, %2}" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m") + (const_int 0)) + (ashift:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x") + (match_dup 2)) + (ashiftrt:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 3, true, 1, false)" + "vpsha\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") + (set_attr "prefix_data16" "0") + (set_attr "prefix_extra" "2") (set_attr "mode" "TI")]) -(define_insn "sse5_lshl3" +(define_insn "xop_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)" - "pshl\t{%2, %1, %0|%0, %1, %2}" + (if_then_else:SSEMODE1248 + (ge:SSEMODE1248 + (match_operand:SSEMODE1248 2 "nonimmediate_operand" "x,m") + (const_int 0)) + (ashift:SSEMODE1248 + (match_operand:SSEMODE1248 1 "nonimmediate_operand" "xm,x") + (match_dup 2)) + (lshiftrt:SSEMODE1248 + (match_dup 1) + (neg:SSEMODE1248 (match_dup 2)))))] + "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 3, true, 1, false)" + "vpshl\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseishft") + (set_attr "prefix_data16" "0") + (set_attr "prefix_extra" "2") (set_attr "mode" "TI")]) -;; SSE5 FRCZ support +;; SSE2 doesn't have some shift varients, so define versions for XOP +(define_expand "ashlv16qi3" + [(match_operand:V16QI 0 "register_operand" "") + (match_operand:V16QI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")] + "TARGET_XOP" +{ + 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_xop_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_XOP" +{ + 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_xop_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_XOP" +{ + rtvec vs = rtvec_alloc (16); + rtx par = gen_rtx_PARALLEL (V16QImode, vs); + rtx reg = gen_reg_rtx (V16QImode); + int i; + rtx ele = ((CONST_INT_P (operands[2])) + ? 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 (!CONST_INT_P (operands[2])) + { + rtx neg = gen_reg_rtx (V16QImode); + emit_insn (gen_negv16qi2 (neg, reg)); + emit_insn (gen_xop_ashlv16qi3 (operands[0], operands[1], neg)); + } + else + emit_insn (gen_xop_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_XOP" +{ + rtvec vs = rtvec_alloc (2); + rtx par = gen_rtx_PARALLEL (V2DImode, vs); + rtx reg = gen_reg_rtx (V2DImode); + rtx ele; + + if (CONST_INT_P (operands[2])) + 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_xop_ashlv2di3 (operands[0], operands[1], reg)); + DONE; +}) + +;; XOP FRCZ support ;; parallel insns -(define_insn "sse5_frcz2" +(define_insn "xop_frcz2" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (unspec:SSEMODEF2P [(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "xm")] UNSPEC_FRCZ))] - "TARGET_SSE5" - "frcz\t{%1, %0|%0, %1}" + "TARGET_XOP" + "vfrcz\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt1") - (set_attr "prefix_extra" "1") (set_attr "mode" "")]) ;; scalar insns -(define_insn "sse5_vmfrcz2" +(define_insn "xop_vmfrcz2" [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") (vec_merge:SSEMODEF2P (unspec:SSEMODEF2P @@ -7891,159 +11792,705 @@ UNSPEC_FRCZ) (match_operand:SSEMODEF2P 1 "register_operand" "0") (const_int 1)))] - "TARGET_SSE5" - "frcz\t{%2, %0|%0, %2}" + "TARGET_XOP" + "vfrcz\t{%2, %0|%0, %2}" [(set_attr "type" "ssecvt1") - (set_attr "prefix_extra" "1") - (set_attr "mode" "")]) - -(define_insn "sse5_cvtph2ps" - [(set (match_operand:V4SF 0 "register_operand" "=x") - (unspec:V4SF [(match_operand:V4HI 1 "nonimmediate_operand" "xm")] - UNSPEC_CVTPH2PS))] - "TARGET_SSE5" - "cvtph2ps\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") - (set_attr "mode" "V4SF")]) - -(define_insn "sse5_cvtps2ph" - [(set (match_operand:V4HI 0 "nonimmediate_operand" "=xm") - (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x")] - UNSPEC_CVTPS2PH))] - "TARGET_SSE5" - "cvtps2ph\t{%1, %0|%0, %1}" - [(set_attr "type" "ssecvt") - (set_attr "mode" "V4SF")]) - -;; Scalar versions of the com instructions that use vector types that are -;; called from the intrinsics. Unlike the the other s{s,d} instructions, the -;; com instructions fill in 0's in the upper bits instead of leaving them -;; unmodified, so we use const_vector of 0 instead of match_dup. -(define_expand "sse5_vmmaskcmp3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "") - (vec_merge:SSEMODEF2P - (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator" - [(match_operand:SSEMODEF2P 2 "register_operand" "") - (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "")]) - (match_dup 4) - (const_int 1)))] - "TARGET_SSE5" -{ - operands[4] = CONST0_RTX (mode); -}) - -(define_insn "*sse5_vmmaskcmp3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (vec_merge:SSEMODEF2P - (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator" - [(match_operand:SSEMODEF2P 2 "register_operand" "x") - (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")]) - (match_operand:SSEMODEF2P 4 "") - (const_int 1)))] - "TARGET_SSE5" - "com%Y1\t{%3, %2, %0|%0, %2, %3}" - [(set_attr "type" "sse4arg") - (set_attr "mode" "")]) - -;; We don't have a comparison operator that always returns true/false, so -;; handle comfalse and comtrue specially. -(define_insn "sse5_com_tf3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (unspec:SSEMODEF2P - [(match_operand:SSEMODEF2P 1 "register_operand" "x") - (match_operand:SSEMODEF2P 2 "nonimmediate_operand" "xm") - (match_operand:SI 3 "const_int_operand" "n")] - UNSPEC_SSE5_TRUEFALSE))] - "TARGET_SSE5" -{ - const char *ret = NULL; - - switch (INTVAL (operands[3])) - { - case COM_FALSE_S: - ret = \"comfalses\t{%2, %1, %0|%0, %1, %2}\"; - break; - - case COM_FALSE_P: - ret = \"comfalsep\t{%2, %1, %0|%0, %1, %2}\"; - break; - - case COM_TRUE_S: - ret = \"comfalses\t{%2, %1, %0|%0, %1, %2}\"; - break; - - case COM_TRUE_P: - ret = \"comfalsep\t{%2, %1, %0|%0, %1, %2}\"; - break; - - default: - gcc_unreachable (); - } - - return ret; -} - [(set_attr "type" "ssecmp") (set_attr "mode" "")]) -(define_insn "sse5_maskcmp3" - [(set (match_operand:SSEMODEF2P 0 "register_operand" "=x") - (match_operator:SSEMODEF2P 1 "sse5_comparison_float_operator" - [(match_operand:SSEMODEF2P 2 "register_operand" "x") - (match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm")]))] - "TARGET_SSE5" - "com%Y1\t{%3, %2, %0|%0, %2, %3}" - [(set_attr "type" "ssecmp") +(define_insn "xop_frcz2256" + [(set (match_operand:FMA4MODEF4 0 "register_operand" "=x") + (unspec:FMA4MODEF4 + [(match_operand:FMA4MODEF4 1 "nonimmediate_operand" "xm")] + UNSPEC_FRCZ))] + "TARGET_XOP" + "vfrcz\t{%1, %0|%0, %1}" + [(set_attr "type" "ssecvt1") (set_attr "mode" "")]) -(define_insn "sse5_maskcmp3" +(define_insn "xop_maskcmp3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (match_operator:SSEMODE1248 1 "ix86_comparison_int_operator" [(match_operand:SSEMODE1248 2 "register_operand" "x") (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))] - "TARGET_SSE5" - "pcom%Y1\t{%3, %2, %0|%0, %2, %3}" + "TARGET_XOP" + "vpcom%Y1\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "sse4arg") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) -(define_insn "sse5_maskcmp_uns3" +(define_insn "xop_maskcmp_uns3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator" [(match_operand:SSEMODE1248 2 "register_operand" "x") (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")]))] - "TARGET_SSE5" - "pcom%Y1u\t{%3, %2, %0|%0, %2, %3}" + "TARGET_XOP" + "vpcom%Y1u\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssecmp") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) ;; Version of pcom*u* that is called from the intrinsics that allows pcomequ* ;; and pcomneu* not to be converted to the signed ones in case somebody needs ;; the exact instruction generated for the intrinsic. -(define_insn "sse5_maskcmp_uns23" +(define_insn "xop_maskcmp_uns23" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (unspec:SSEMODE1248 [(match_operator:SSEMODE1248 1 "ix86_comparison_uns_operator" [(match_operand:SSEMODE1248 2 "register_operand" "x") (match_operand:SSEMODE1248 3 "nonimmediate_operand" "xm")])] - UNSPEC_SSE5_UNSIGNED_CMP))] - "TARGET_SSE5" - "pcom%Y1u\t{%3, %2, %0|%0, %2, %3}" + UNSPEC_XOP_UNSIGNED_CMP))] + "TARGET_XOP" + "vpcom%Y1u\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssecmp") + (set_attr "prefix_data16" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") (set_attr "mode" "TI")]) ;; Pcomtrue and pcomfalse support. These are useless instructions, but are ;; being added here to be complete. -(define_insn "sse5_pcom_tf3" +(define_insn "xop_pcom_tf3" [(set (match_operand:SSEMODE1248 0 "register_operand" "=x") (unspec:SSEMODE1248 [(match_operand:SSEMODE1248 1 "register_operand" "x") (match_operand:SSEMODE1248 2 "nonimmediate_operand" "xm") (match_operand:SI 3 "const_int_operand" "n")] - UNSPEC_SSE5_TRUEFALSE))] - "TARGET_SSE5" + UNSPEC_XOP_TRUEFALSE))] + "TARGET_XOP" { return ((INTVAL (operands[3]) != 0) - ? "pcomtrue\t{%2, %1, %0|%0, %1, %2}" - : "pcomfalse\t{%2, %1, %0|%0, %1, %2}"); + ? "vpcomtrue\t{%2, %1, %0|%0, %1, %2}" + : "vpcomfalse\t{%2, %1, %0|%0, %1, %2}"); } [(set_attr "type" "ssecmp") + (set_attr "prefix_data16" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") + (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_extra" "1") + (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_extra" "1") + (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_extra" "1") + (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_extra" "1") + (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 "length_immediate" "1") + (set_attr "prefix" "maybe_vex") + (set_attr "mode" "TI")]) + +(define_insn "*vpclmulqdq" + [(set (match_operand:V2DI 0 "register_operand" "=x") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x") + (match_operand:V2DI 2 "nonimmediate_operand" "xm") + (match_operand:SI 3 "const_0_to_255_operand" "n")] + UNSPEC_PCLMUL))] + "TARGET_PCLMUL && TARGET_AVX" + "vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}" + [(set_attr "type" "sselog1") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "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 "length_immediate" "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 "modrm" "0") + (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 "modrm" "0") + (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 "modrm" "0") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (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_extra" "1") + (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_extra" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (set_attr "length_immediate" "1") + (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_extra" "1") + (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_extra" "1") + (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_extra" "1,*") + (set_attr "length_immediate" "1,*") + (set_attr "prefix" "vex") + (set_attr "mode" "")])