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 <ja...@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. --- 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)) { Jakub