Patchwork v{extract,insert,broadcast,perm2}{i,f}128

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 23, 2011, 2:47 p.m.
Message ID <20110923144756.GU2687@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/116105/
State New
Headers show

Comments

Jakub Jelinek - Sept. 23, 2011, 2:47 p.m.
On Tue, Sep 20, 2011 at 04:10:56PM +0200, Uros Bizjak wrote:
> >> I can surely do that (or e.g.
> >> (define_mode_attr i128 [(V4DI "%~128") (V4DF "f128") ...])
> >> and
> >> "vextract<i128>\t{$0x1, %1, %0|%0, %1, 0x1}"
> >> )
> >> if you prefer it that way, but that is a functional alternative
> >> to the patch I've just posted.  What I don't know how to express

> Oh, and you can use <sseinsnmode> to set mode attribute statically.

This patch implements that, bootstrapped/regtested on x86_64-linux
and i686-linux, tested on SandyBridge additionally, eyeballed some
-mavx2 assembly files.  Ok for trunk?

2011-09-23  Jakub Jelinek  <jakub@redhat.com>

	* config/i386/i386.c (ix86_print_operand): Handle %~.
	(ix86_print_operand_punct_valid_p): Return true also for '~'.
	* config/i386/sse.md (i128): New mode_attr.
	(vec_extract_hi_<mode>, vec_extract_hi_<mode>,
	avx_vbroadcastf128_<mode>, *avx_vperm2f128<mode>_full,
	*avx_vperm2f128<mode>_nozero, vec_set_lo_<mode>, 
	vec_set_hi_<mode>, *vec_concat<mode>_avx): Use <i128> in the
	patterns, use "<sseinsnmode>" for "mode" attribute.
	(vec_extract_hi_v16hi, vec_extract_hi_v32qi, vec_set_lo_v16hi,
	vec_set_hi_v16hi, vec_set_lo_v32qi, vec_set_hi_v32qi): Use
	%~128 in the patterns, use "OI" for "mode" attribute.



	Jakub
Uros Bizjak - Sept. 23, 2011, 3:45 p.m.
On Fri, Sep 23, 2011 at 4:47 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>> >> I can surely do that (or e.g.
>> >> (define_mode_attr i128 [(V4DI "%~128") (V4DF "f128") ...])
>> >> and
>> >> "vextract<i128>\t{$0x1, %1, %0|%0, %1, 0x1}"
>> >> )
>> >> if you prefer it that way, but that is a functional alternative
>> >> to the patch I've just posted.  What I don't know how to express
>
>> Oh, and you can use <sseinsnmode> to set mode attribute statically.
>
> This patch implements that, bootstrapped/regtested on x86_64-linux
> and i686-linux, tested on SandyBridge additionally, eyeballed some
> -mavx2 assembly files.  Ok for trunk?
>
> 2011-09-23  Jakub Jelinek  <jakub@redhat.com>
>
>        * config/i386/i386.c (ix86_print_operand): Handle %~.
>        (ix86_print_operand_punct_valid_p): Return true also for '~'.
>        * config/i386/sse.md (i128): New mode_attr.
>        (vec_extract_hi_<mode>, vec_extract_hi_<mode>,
>        avx_vbroadcastf128_<mode>, *avx_vperm2f128<mode>_full,
>        *avx_vperm2f128<mode>_nozero, vec_set_lo_<mode>,
>        vec_set_hi_<mode>, *vec_concat<mode>_avx): Use <i128> in the
>        patterns, use "<sseinsnmode>" for "mode" attribute.
>        (vec_extract_hi_v16hi, vec_extract_hi_v32qi, vec_set_lo_v16hi,
>        vec_set_hi_v16hi, vec_set_lo_v32qi, vec_set_hi_v32qi): Use
>        %~128 in the patterns, use "OI" for "mode" attribute.

OK.

Thanks,
Uros.

Patch

--- gcc/config/i386/i386.c.jj	2011-09-23 10:04:35.000000000 +0200
+++ gcc/config/i386/i386.c	2011-09-23 13:12:11.000000000 +0200
@@ -13513,6 +13513,7 @@  get_some_local_dynamic_name (void)
    Y -- print condition for XOP pcom* instruction.
    + -- print a branch hint as 'cs' or 'ds' prefix
    ; -- print a semicolon (after prefixes due to bug in older gas).
+   ~ -- print "i" if TARGET_AVX2, "f" otherwise.
    @ -- print a segment register of thread base pointer load
  */
 
@@ -14006,6 +14007,10 @@  ix86_print_operand (FILE *file, rtx x, i
 	    fputs ("gs", file);
 	  return;
 
+	case '~':
+	  putc (TARGET_AVX2 ? 'i' : 'f', file);
+	  return;
+
 	default:
 	    output_operand_lossage ("invalid operand code '%c'", code);
 	}
@@ -14141,7 +14146,7 @@  static bool
 ix86_print_operand_punct_valid_p (unsigned char code)
 {
   return (code == '@' || code == '*' || code == '+'
-	  || code == '&' || code == ';');
+	  || code == '&' || code == ';' || code == '~');
 }
 
 /* Print a memory operand whose address is ADDR.  */
--- gcc/config/i386/sse.md.jj	2011-09-22 15:40:48.000000000 +0200
+++ gcc/config/i386/sse.md	2011-09-23 12:59:12.000000000 +0200
@@ -297,6 +297,11 @@  (define_mode_attr castmode [(V8SI "si") 
 ;; Instruction suffix for sign and zero extensions.
 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
 
+;; i128 for integer vectors and TARGET_AVX2, f128 otherwise.
+(define_mode_attr i128
+  [(V8SF "f128") (V4DF "f128") (V32QI "%~128") (V16HI "%~128")
+   (V8SI "%~128") (V4DI "%~128")])
+
 ;; Mix-n-match
 (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
 
@@ -3872,23 +3877,13 @@  (define_insn "vec_extract_hi_<mode>"
 	  (match_operand:VI8F_256 1 "register_operand" "x,x")
 	  (parallel [(const_int 2) (const_int 3)])))]
   "TARGET_AVX"
-{
-  if (get_attr_mode (insn) == MODE_OI)
-    return "vextracti128\t{$0x1, %1, %0|%0, %1, 0x1}";
-  else
-    return "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}";
-}
+  "vextract<i128>\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")
-     (if_then_else
-       (and (match_test "TARGET_AVX2")
-	    (eq (const_string "<MODE>mode") (const_string "V4DImode")))
-     (const_string "OI")
-     (const_string "V4DF")))])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn_and_split "vec_extract_lo_<mode>"
   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=x,m")
@@ -3917,23 +3912,13 @@  (define_insn "vec_extract_hi_<mode>"
 	  (parallel [(const_int 4) (const_int 5)
 		     (const_int 6) (const_int 7)])))]
   "TARGET_AVX"
-{
-  if (get_attr_mode (insn) == MODE_OI)
-    return "vextracti128\t{$0x1, %1, %0|%0, %1, 0x1}";
-  else
-    return "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}";
-}
+  "vextract<i128>\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")
-     (if_then_else
-       (and (match_test "TARGET_AVX2")
-	    (eq (const_string "<MODE>mode") (const_string "V8SImode")))
-     (const_string "OI")
-     (const_string "V8SF")))])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn_and_split "vec_extract_lo_v16hi"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
@@ -3966,21 +3951,13 @@  (define_insn "vec_extract_hi_v16hi"
 		     (const_int 12) (const_int 13)
 		     (const_int 14) (const_int 15)])))]
   "TARGET_AVX"
-{
-  if (get_attr_mode (insn) == MODE_OI)
-    return "vextracti128\t{$0x1, %1, %0|%0, %1, 0x1}";
-  else
-    return "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}";
-}
+  "vextract%~128\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")
-     (if_then_else (match_test "TARGET_AVX2")
-   (const_string "OI")
-   (const_string "V8SF")))])
+   (set_attr "mode" "OI")])
 
 (define_insn_and_split "vec_extract_lo_v32qi"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
@@ -4021,21 +3998,13 @@  (define_insn "vec_extract_hi_v32qi"
 		     (const_int 28) (const_int 29)
 		     (const_int 30) (const_int 31)])))]
   "TARGET_AVX"
-{
-  if (get_attr_mode (insn) == MODE_OI)
-    return "vextracti128\t{$0x1, %1, %0|%0, %1, 0x1}";
-  else
-    return "vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}";
-}
+  "vextract%~128\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")
-     (if_then_else (match_test "TARGET_AVX2")
-   (const_string "OI")
-   (const_string "V8SF")))])
+   (set_attr "mode" "OI")])
 
 (define_insn_and_split "*sse4_1_extractps"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,x,x")
@@ -11663,14 +11632,14 @@  (define_insn "avx_vbroadcastf128_<mode>"
 	  (match_dup 1)))]
   "TARGET_AVX"
   "@
-   vbroadcastf128\t{%1, %0|%0, %1}
-   vinsertf128\t{$1, %1, %0, %0|%0, %0, %1, 1}
-   vperm2f128\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
+   vbroadcast<i128>\t{%1, %0|%0, %1}
+   vinsert<i128>\t{$1, %1, %0, %0|%0, %0, %1, 1}
+   vperm2<i128>\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
   [(set_attr "type" "ssemov,sselog1,sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "0,1,1")
    (set_attr "prefix" "vex")
-   (set_attr "mode" "V4SF,V8SF,V8SF")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 ;; Recognize broadcast as a vec_select as produced by builtin_vec_perm.
 ;; If it so happens that the input is in memory, use vbroadcast.
@@ -11864,12 +11833,12 @@  (define_insn "*avx_vperm2f128<mode>_full
 	   (match_operand:SI 3 "const_0_to_255_operand" "n")]
 	  UNSPEC_VPERMIL2F128))]
   "TARGET_AVX"
-  "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+  "vperm2<i128>\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")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn "*avx_vperm2f128<mode>_nozero"
   [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
@@ -11884,13 +11853,13 @@  (define_insn "*avx_vperm2f128<mode>_noze
 {
   int mask = avx_vperm2f128_parallel (operands[3], <MODE>mode) - 1;
   operands[3] = GEN_INT (mask);
-  return "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+  return "vperm2<i128>\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")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_expand "avx_vinsertf128<mode>"
   [(match_operand:V_256 0 "register_operand" "")
@@ -11955,12 +11924,12 @@  (define_insn "vec_set_lo_<mode>"
 	    (match_operand:VI8F_256 1 "register_operand" "x")
 	    (parallel [(const_int 2) (const_int 3)]))))]
   "TARGET_AVX"
-  "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
+  "vinsert<i128>\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" "V4DF")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn "vec_set_hi_<mode>"
   [(set (match_operand:VI8F_256 0 "register_operand" "=x")
@@ -11970,12 +11939,12 @@  (define_insn "vec_set_hi_<mode>"
 	    (parallel [(const_int 0) (const_int 1)]))
 	  (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")))]
   "TARGET_AVX"
-  "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
+  "vinsert<i128>\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" "V4DF")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn "vec_set_lo_<mode>"
   [(set (match_operand:VI4F_256 0 "register_operand" "=x")
@@ -11986,12 +11955,12 @@  (define_insn "vec_set_lo_<mode>"
 	    (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}"
+  "vinsert<i128>\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")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn "vec_set_hi_<mode>"
   [(set (match_operand:VI4F_256 0 "register_operand" "=x")
@@ -12002,12 +11971,12 @@  (define_insn "vec_set_hi_<mode>"
 		       (const_int 2) (const_int 3)]))
 	  (match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "xm")))]
   "TARGET_AVX"
-  "vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
+  "vinsert<i128>\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")])
+   (set_attr "mode" "<sseinsnmode>")])
 
 (define_insn "vec_set_lo_v16hi"
   [(set (match_operand:V16HI 0 "register_operand" "=x")
@@ -12020,12 +11989,12 @@  (define_insn "vec_set_lo_v16hi"
 		       (const_int 12) (const_int 13)
 		       (const_int 14) (const_int 15)]))))]
   "TARGET_AVX"
-  "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
+  "vinsert%~128\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")])
+   (set_attr "mode" "OI")])
 
 (define_insn "vec_set_hi_v16hi"
   [(set (match_operand:V16HI 0 "register_operand" "=x")
@@ -12038,12 +12007,12 @@  (define_insn "vec_set_hi_v16hi"
 		       (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}"
+  "vinsert%~128\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")])
+   (set_attr "mode" "OI")])
 
 (define_insn "vec_set_lo_v32qi"
   [(set (match_operand:V32QI 0 "register_operand" "=x")
@@ -12060,12 +12029,12 @@  (define_insn "vec_set_lo_v32qi"
 		       (const_int 28) (const_int 29)
 		       (const_int 30) (const_int 31)]))))]
   "TARGET_AVX"
-  "vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
+  "vinsert%~128\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")])
+   (set_attr "mode" "OI")])
 
 (define_insn "vec_set_hi_v32qi"
   [(set (match_operand:V32QI 0 "register_operand" "=x")
@@ -12082,12 +12051,12 @@  (define_insn "vec_set_hi_v32qi"
 		       (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}"
+  "vinsert%~128\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")])
+   (set_attr "mode" "OI")])
 
 (define_expand "<avx_avx2>_maskload<ssemodesuffix><avxsizesuffix>"
   [(set (match_operand:V48_AVX2 0 "register_operand" "")
@@ -12468,7 +12437,7 @@  (define_insn "*vec_concat<mode>_avx"
   switch (which_alternative)
     {
     case 0:
-      return "vinsertf128\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}";
+      return "vinsert<i128>\t{$0x1, %2, %t1, %0|%0, %t1, %2, 0x1}";
     case 1:
       switch (get_attr_mode (insn))
 	{