i386.md (isa): Add x64_sse4 member.
authorUros Bizjak <ubizjak@gmail.com>
Mon, 6 May 2013 19:53:43 +0000 (21:53 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 6 May 2013 19:53:43 +0000 (21:53 +0200)
* config/i386/i386.md (isa): Add x64_sse4 member.
(enabled): Handle x64_sse4.
(*movdi_internal): Add *x->?r alternative to emit pextrq $0,%xmm,%reg
instruction for 64bit SSE4_1 targets.  Update insn attributes.
(*movsi_internal): Add *x->?r alternative to emit pextrd $0,%xmm,%reg
instruction for SSE4_1 targets.  Update insn attributes.
* config/i386/sse.md (*vec_extract<ssevecmodelower>_0): Merge
with *sse4_1_pextrd and *sse4_1_pextrq having const_0 selector.
(*vec_extractv2di_1): Merge with *sse4_1_pextrq having
const_1 selector.
(*vec_extractv4si): Rename from *sse4_1_pextrd.
(*vec_extractv4si_zext): Rename from *sse4_1_pextrd_zext.
(*vec_extract<ssevecmodelower>_0 splitters): Merge splitters together.

From-SVN: r198643

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/config/i386/sse.md

index 97faf764d9e530483fb34be1a0b47ef6e4e7d811..f1c214f3c17e23c2ae68fab8f28a5784f0b3f554 100644 (file)
@@ -1,3 +1,19 @@
+2013-05-06  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (isa): Add x64_sse4 member.
+       (enabled): Handle x64_sse4.
+       (*movdi_internal): Add *x->?r alternative to emit pextrq $0,%xmm,%reg
+       instruction for 64bit SSE4_1 targets.  Update insn attributes.
+       (*movsi_internal): Add *x->?r alternative to emit pextrd $0,%xmm,%reg
+       instruction for SSE4_1 targets.  Update insn attributes.
+       * config/i386/sse.md (*vec_extract<ssevecmodelower>_0): Merge
+       with *sse4_1_pextrd and *sse4_1_pextrq having const_0 selector.
+       (*vec_extractv2di_1): Merge with *sse4_1_pextrq having
+       const_1 selector.
+       (*vec_extractv4si): Rename from *sse4_1_pextrd.
+       (*vec_extractv4si_zext): Rename from *sse4_1_pextrd_zext.
+       (*vec_extract<ssevecmodelower>_0 splitters): Merge splitters together.
+
 2013-05-06  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/57108
@@ -14,7 +30,6 @@
 
 2013-05-06  Steven Bosscher  <steven@gcc.gnu.org>
 
-
        * config/mips/mips.c: Include tree-pass.h.
        (mips_reorg): Split in pre- and post-dbr_schedule parts.
        (mips_machine_reorg2): Move mips_reorg post-dbr_schedule parts here.
index ee31319ff7b4e6d8e4960e18bf1221174fdaf17f..2f08198bd20fe8fc1b96913dec426d6282be0937 100644 (file)
 (define_attr "movu" "0,1" (const_string "0"))
 
 ;; Used to control the "enabled" attribute on a per-instruction basis.
-(define_attr "isa" "base,x64,x64_sse4_noavx,x64_avx,nox64,sse2,sse2_noavx,
-                   sse3,sse4,sse4_noavx,avx,noavx,avx2,noavx2,bmi2,fma4,fma"
+(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
+                   sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
+                   avx2,noavx2,bmi2,fma4,fma"
   (const_string "base"))
 
 (define_attr "enabled" ""
   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
+        (eq_attr "isa" "x64_sse4")
+          (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
         (eq_attr "isa" "x64_sse4_noavx")
           (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
         (eq_attr "isa" "x64_avx")
 
 (define_insn "*movdi_internal"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?*Yi,?*Ym,?*Yi")
+    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
        (match_operand:DI 1 "general_operand"
-    "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*x,m ,*x,*Yj,r   ,*Yj ,*Yn"))]
+    "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*x,m ,*x,*Yj,*x,r   ,*Yj ,*Yn"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (get_attr_type (insn))
       return "movq\t{%1, %0|%0, %1}";
 
     case TYPE_SSELOG1:
+      if (GENERAL_REG_P (operands[0]))
+       return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
+
       return standard_sse_constant_opcode (insn, operands[1]);
 
     case TYPE_SSEMOV:
   [(set (attr "isa")
      (cond [(eq_attr "alternative" "0,1")
              (const_string "nox64")
-           (eq_attr "alternative" "2,3,4,5,10,11,16,17")
+           (eq_attr "alternative" "2,3,4,5,10,11,16,18")
              (const_string "x64")
+           (eq_attr "alternative" "17")
+             (const_string "x64_sse4")
           ]
           (const_string "*")))
    (set (attr "type")
              (const_string "mmx")
            (eq_attr "alternative" "7,8,9,10,11")
              (const_string "mmxmov")
-           (eq_attr "alternative" "12")
+           (eq_attr "alternative" "12,17")
              (const_string "sselog1")
-           (eq_attr "alternative" "13,14,15,16,17")
+           (eq_attr "alternative" "13,14,15,16,18")
              (const_string "ssemov")
-           (eq_attr "alternative" "18,19")
+           (eq_attr "alternative" "19,20")
              (const_string "ssecvt")
-           (match_operand 1 "pic_32bit_operand")
+           (match_operand 1 "pic_32bit_operand")
              (const_string "lea")
           ]
           (const_string "imov")))
         (const_string "0")
         (const_string "*")))
    (set (attr "length_immediate")
-     (if_then_else
-       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
-        (const_string "8")
-        (const_string "*")))
+     (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
+             (const_string "8")
+           (eq_attr "alternative" "17")
+             (const_string "1")
+          ]
+          (const_string "*")))
    (set (attr "prefix_rex")
-     (if_then_else (eq_attr "alternative" "10,11,16,17")
+     (if_then_else (eq_attr "alternative" "10,11,16,17,18")
+       (const_string "1")
+       (const_string "*")))
+   (set (attr "prefix_extra")
+     (if_then_else (eq_attr "alternative" "17")
        (const_string "1")
        (const_string "*")))
    (set (attr "prefix")
            (and (eq_attr "alternative" "14,15")
                 (not (match_test "TARGET_SSE2")))
              (const_string "V2SF")
+           (eq_attr "alternative" "17")
+             (const_string "TI")
           ]
           (const_string "DI")))])
 
 
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-                       "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?*Yi")
+                       "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
        (match_operand:SI 1 "general_operand"
-                       "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,r"))]
+                       "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
 {
   switch (get_attr_type (insn))
     {
     case TYPE_SSELOG1:
+      if (GENERAL_REG_P (operands[0]))
+       return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
+
       return standard_sse_constant_opcode (insn, operands[1]);
 
     case TYPE_SSEMOV:
       gcc_unreachable ();
     }
 }
-  [(set (attr "type")
+  [(set (attr "isa")
+     (if_then_else (eq_attr "alternative" "11")
+       (const_string "sse4")
+       (const_string "*")))
+   (set (attr "type")
      (cond [(eq_attr "alternative" "2")
              (const_string "mmx")
            (eq_attr "alternative" "3,4,5")
              (const_string "mmxmov")
-           (eq_attr "alternative" "6")
+           (eq_attr "alternative" "6,11")
              (const_string "sselog1")
-           (eq_attr "alternative" "7,8,9,10,11")
+           (eq_attr "alternative" "7,8,9,10,12")
              (const_string "ssemov")
            (match_operand 1 "pic_32bit_operand")
              (const_string "lea")
           ]
           (const_string "imov")))
+   (set (attr "length_immediate")
+     (if_then_else (eq_attr "alternative" "11")
+       (const_string "1")
+       (const_string "*")))
+   (set (attr "prefix_extra")
+     (if_then_else (eq_attr "alternative" "11")
+       (const_string "1")
+       (const_string "*")))
    (set (attr "prefix")
      (if_then_else (eq_attr "type" "sselog1,ssemov")
        (const_string "maybe_vex")
            (and (eq_attr "alternative" "8,9")
                 (not (match_test "TARGET_SSE2")))
              (const_string "SF")
+           (eq_attr "alternative" "11")
+             (const_string "TI")
           ]
           (const_string "SI")))])
 
index c1d03040eef354dd0f08f87e03e408e605906566..f0e7525a6beb29c0f943e43ea31b9e9c24e82129 100644 (file)
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "TI")])
 
-(define_insn "*sse4_1_pextrd"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
-       (vec_select:SI
-         (match_operand:V4SI 1 "register_operand" "x")
-         (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")])))]
-  "TARGET_SSE4_1"
-  "%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")])
-
-(define_insn "*sse4_1_pextrd_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (vec_select:SI
-           (match_operand:V4SI 1 "register_operand" "x")
-           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
-  "TARGET_64BIT && TARGET_SSE4_1"
-  "%vpextrd\t{%2, %1, %k0|%k0, %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 since it is preferred.
-(define_insn "*sse4_1_pextrq"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-       (vec_select:DI
-         (match_operand:V2DI 1 "register_operand" "x")
-         (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")])))]
-  "TARGET_SSE4_1 && TARGET_64BIT"
-  "%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 "avx2_pshufdv3"
   [(match_operand:V8SI 0 "register_operand")
    (match_operand:V8SI 1 "nonimmediate_operand")
    (set_attr "mode" "TI,TI,V4SF,SF,SF")])
 
 (define_insn "*vec_extract<ssevecmodelower>_0"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand"         "=x,m,r ,r")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand"         "=r,r,x ,m,r")
        (vec_select:SWI48
-         (match_operand:<ssevecmode> 1 "nonimmediate_operand" "xm,x,Yj,m")
+         (match_operand:<ssevecmode> 1 "nonimmediate_operand" "Yj,x,xm,x,m")
          (parallel [(const_int 0)])))]
   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-  "#")
+  "#"
+  [(set_attr "isa" "*,sse4,*,*,*")])
 
 (define_insn "*vec_extractv2di_0_sse"
   [(set (match_operand:DI 0 "nonimmediate_operand"     "=x,m")
   "#")
 
 (define_split
-  [(set (match_operand:SWI48x 0 "register_operand")
+  [(set (match_operand:SWI48x 0 "nonimmediate_operand")
        (vec_select:SWI48x
-         (match_operand:<ssevecmode> 1 "memory_operand")
+         (match_operand:<ssevecmode> 1 "nonimmediate_operand")
          (parallel [(const_int 0)])))]
   "TARGET_SSE && reload_completed"
   [(set (match_dup 0) (match_dup 1))]
-  "operands[1] = adjust_address (operands[1], <MODE>mode, 0);")
+{
+  if (REG_P (operands[1]))
+    operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
+  else
+    operands[1] = adjust_address (operands[1], <MODE>mode, 0);
+})
 
-(define_split
-  [(set (match_operand:SWI48x 0 "nonimmediate_operand")
-       (vec_select:SWI48x
-         (match_operand:<ssevecmode> 1 "register_operand")
-         (parallel [(const_int 0)])))]
-  "TARGET_SSE && reload_completed
-   && (TARGET_INTER_UNIT_MOVES_FROM_VEC
-       || !GENERAL_REG_P (operands [0]))"
-  [(set (match_dup 0) (match_dup 1))]
-  "operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));")
+(define_insn "*vec_extractv4si"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (vec_select:SI
+         (match_operand:V4SI 1 "register_operand" "x")
+         (parallel [(match_operand:SI 2 "const_0_to_3_operand")])))]
+  "TARGET_SSE4_1"
+  "%vpextrd\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 "*vec_extractv4si_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (vec_select:SI
+           (match_operand:V4SI 1 "register_operand" "x")
+           (parallel [(match_operand:SI 2 "const_0_to_3_operand")]))))]
+  "TARGET_64BIT && TARGET_SSE4_1"
+  "%vpextrd\t{%2, %1, %k0|%k0, %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_and_split "*vec_extractv4si_mem"
   [(set (match_operand:SI 0 "register_operand" "=x,r")
 })
 
 (define_insn "*vec_extractv2di_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand"     "=m,x,x,x,x,r")
+  [(set (match_operand:DI 0 "nonimmediate_operand"     "=rm,m,x,x,x,x,r")
        (vec_select:DI
-         (match_operand:V2DI 1 "nonimmediate_operand" x,0,x,x,o,o")
+         (match_operand:V2DI 1 "nonimmediate_operand"  "x ,x,0,x,x,o,o")
          (parallel [(const_int 1)])))]
   "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
   "@
+   %vpextrq\t{$1, %1, %0|%0, %1, 1}
    %vmovhps\t{%1, %0|%0, %1}
    psrldq\t{$8, %0|%0, 8}
    vpsrldq\t{$8, %1, %0|%0, %1, 8}
    movhlps\t{%1, %0|%0, %1}
    #
    #"
-  [(set_attr "isa" "*,sse2_noavx,avx,noavx,*,x64")
-   (set_attr "type" "ssemov,sseishft1,sseishft1,ssemov,ssemov,imov")
-   (set_attr "length_immediate" "*,1,1,*,*,*")
-   (set_attr "memory" "*,none,none,*,*,*")
-   (set_attr "prefix" "maybe_vex,orig,vex,orig,*,*")
-   (set_attr "mode" "V2SF,TI,TI,V4SF,DI,DI")])
+  [(set_attr "isa" "x64_sse4,*,sse2_noavx,avx,noavx,*,x64")
+   (set_attr "type" "sselog1,ssemov,sseishft1,sseishft1,ssemov,ssemov,imov")
+   (set_attr "length_immediate" "1,*,1,1,*,*,*")
+   (set_attr "memory" "*,*,none,none,*,*,*")
+   (set_attr "prefix_rex" "1,*,*,*,*,*,*")
+   (set_attr "prefix_extra" "1,*,*,*,*,*,*")
+   (set_attr "prefix" "maybe_vex,maybe_vex,orig,vex,orig,*,*")
+   (set_attr "mode" "TI,V2SF,TI,TI,V4SF,DI,DI")])
 
 (define_split
   [(set (match_operand:DI 0 "register_operand")