===================================================================
@@ -970,6 +970,11 @@
(define_mode_iterator SWI1248_AVX512BWDQ
[(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
+;; All integer modes with AVX512BW, where HImode operation
+;; can be used instead of QImode.
+(define_mode_iterator SWI1248_AVX512BW
+ [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
+
;; All integer modes without QImode.
(define_mode_iterator SWI248x [HI SI DI])
@@ -2574,11 +2582,15 @@
(define_insn "*movqi_internal"
[(set (match_operand:QI 0 "nonimmediate_operand"
- "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
+ "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
(match_operand:QI 1 "general_operand"
- "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
+ "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
+ static char buf[128];
+ const char *ops;
+ const char *suffix;
+
switch (get_attr_type (insn))
{
case TYPE_IMOVX:
@@ -2588,24 +2600,33 @@
case TYPE_MSKMOV:
switch (which_alternative)
{
- case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
- : "kmovw\t{%k1, %0|%0, %k1}";
- case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
- : "kmovw\t{%1, %0|%0, %1}";
- case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
- : "kmovw\t{%1, %k0|%k0, %1}";
+ case 7:
+ ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
+ break;
+ case 9:
+ ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
+ break;
case 10:
case 11:
gcc_assert (TARGET_AVX512DQ);
- return "kmovb\t{%1, %0|%0, %1}";
- default: gcc_unreachable ();
+ /* FALLTHRU */
+ case 8:
+ ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
+ break;
+ default:
+ gcc_unreachable ();
}
+ suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
+
+ snprintf (buf, sizeof (buf), ops, suffix);
+ return buf;
+
default:
if (get_attr_mode (insn) == MODE_SI)
- return "mov{l}\t{%k1, %k0|%k0, %k1}";
+ return "mov{l}\t{%k1, %k0|%k0, %k1}";
else
- return "mov{b}\t{%1, %0|%0, %1}";
+ return "mov{b}\t{%1, %0|%0, %1}";
}
}
[(set (attr "isa")
@@ -2640,6 +2661,9 @@
(const_string "SI")
(eq_attr "alternative" "6")
(const_string "QI")
+ (and (eq_attr "alternative" "7,8,9")
+ (not (match_test "TARGET_AVX512DQ")))
+ (const_string "HI")
(eq_attr "type" "imovx")
(const_string "SI")
(and (eq_attr "type" "imov")
@@ -8055,23 +8079,26 @@
(any_logic:SWI1248x (match_dup 1)
(match_dup 2)))])
-(define_mode_iterator SWI1248_AVX512BW
- [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
-
(define_insn "*k<logic><mode>"
[(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
- (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
- (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
+ (any_logic:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
+ (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
"TARGET_AVX512F"
{
- if (!TARGET_AVX512DQ && <MODE>mode == QImode)
+ if (get_attr_mode (insn) == MODE_HI)
return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
else
return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
}
- [(set_attr "mode" "<MODE>")
- (set_attr "type" "msklog")
- (set_attr "prefix" "vex")])
+ [(set_attr "type" "msklog")
+ (set_attr "prefix" "vex")
+ (set (attr "mode")
+ (cond [(and (match_test "<MODE>mode == QImode")
+ (not (match_test "TARGET_AVX512DQ")))
+ (const_string "HI")
+ ]
+ (const_string "<MODE>")))])
;; %%% This used to optimize known byte-wide and operations to memory,
;; and sometimes to QImode registers. If this is considered useful,
@@ -8278,14 +8305,22 @@
case 2:
return "and{l}\t{%k2, %k0|%k0, %k2}";
case 3:
- return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
- : "kandw\t{%2, %1, %0|%0, %1, %2}";
+ if (get_attr_mode (insn) == MODE_HI)
+ return "kandw\t{%2, %1, %0|%0, %1, %2}";
+ else
+ return "kandb\t{%2, %1, %0|%0, %1, %2}";
default:
gcc_unreachable ();
}
}
[(set_attr "type" "alu,alu,alu,msklog")
- (set_attr "mode" "QI,QI,SI,HI")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2")
+ (const_string "SI")
+ (and (eq_attr "alternative" "3")
+ (not (match_test "TARGET_AVX512DQ")))
+ (const_string "HI")]
+ (const_string "QI")))
;; Potential partial reg stall on alternative 2.
(set (attr "preferred_for_speed")
(cond [(eq_attr "alternative" "2")
@@ -8319,10 +8354,10 @@
case 1:
return "#";
case 2:
- if (TARGET_AVX512DQ && <MODE>mode == QImode)
- return "kandnb\t{%2, %1, %0|%0, %1, %2}";
+ if (get_attr_mode (insn) == MODE_HI)
+ return "kandnw\t{%2, %1, %0|%0, %1, %2}";
else
- return "kandnw\t{%2, %1, %0|%0, %1, %2}";
+ return "kandn<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
default:
gcc_unreachable ();
}
@@ -8331,7 +8366,13 @@
(set_attr "type" "bitmanip,*,msklog")
(set_attr "prefix" "*,*,vex")
(set_attr "btver2_decode" "direct,*,*")
- (set_attr "mode" "<MODE>")])
+ (set (attr "mode")
+ (cond [(and (eq_attr "alternative" "2")
+ (and (match_test "<MODE>mode == QImode")
+ (not (match_test "TARGET_AVX512DQ"))))
+ (const_string "HI")
+ ]
+ (const_string "<MODE>")))])
(define_split
[(set (match_operand:SWI12 0 "general_reg_operand")
@@ -8843,37 +8884,32 @@
(set_attr "mode" "<MODE>")])
(define_insn "kxnor<mode>"
- [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
- (not:SWI12
- (xor:SWI12
- (match_operand:SWI12 1 "register_operand" "0,k")
- (match_operand:SWI12 2 "register_operand" "r,k"))))
+ [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=r,!k")
+ (not:SWI1248_AVX512BW
+ (xor:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "register_operand" "0,k")
+ (match_operand:SWI1248_AVX512BW 2 "register_operand" "r,k"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_AVX512F"
{
- if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
- return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
- return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
+ if (which_alternative == 0)
+ return "#";
+
+ if (get_attr_mode (insn) == MODE_HI)
+ return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
+ else
+ return "kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
}
[(set_attr "type" "*,msklog")
(set_attr "prefix" "*,vex")
- (set_attr "mode" "<MODE>")])
+ (set (attr "mode")
+ (cond [(and (eq_attr "alternative" "1")
+ (and (match_test "<MODE>mode == QImode")
+ (not (match_test "TARGET_AVX512DQ"))))
+ (const_string "HI")
+ ]
+ (const_string "<MODE>")))])
-(define_insn "kxnor<mode>"
- [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
- (not:SWI48x
- (xor:SWI48x
- (match_operand:SWI48x 1 "register_operand" "0,k")
- (match_operand:SWI48x 2 "register_operand" "r,k"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_AVX512BW"
- "@
- #
- kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "*,msklog")
- (set_attr "prefix" "*,vex")
- (set_attr "mode" "<MODE>")])
-
(define_split
[(set (match_operand:SWI1248x 0 "general_reg_operand")
(not:SWI1248x
@@ -9583,9 +9619,10 @@
case 1:
return "not{l}\t%k0";
case 2:
- if (TARGET_AVX512DQ)
+ if (get_attr_mode (insn) == MODE_HI)
+ return "knotw\t{%1, %0|%0, %1}";
+ else
return "knotb\t{%1, %0|%0, %1}";
- return "knotw\t{%1, %0|%0, %1}";
default:
gcc_unreachable ();
}
@@ -9593,7 +9630,13 @@
[(set_attr "isa" "*,*,avx512f")
(set_attr "type" "negnot,negnot,msklog")
(set_attr "prefix" "*,*,vex")
- (set_attr "mode" "QI,SI,QI")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "1")
+ (const_string "SI")
+ (and (eq_attr "alternative" "2")
+ (not (match_test "TARGET_AVX512DQ")))
+ (const_string "HI")]
+ (const_string "QI")))
;; Potential partial reg stall on alternative 1.
(set (attr "preferred_for_speed")
(cond [(eq_attr "alternative" "1")