(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])
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
- "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
+ "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
(match_operand:DI 1 "general_operand"
- "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
+ "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r,*km,*k,*k"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
(unspec:HI
[(match_operand:HI 1 "nonimmediate_operand" "r,km")]
UNSPEC_KMOV))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
+ "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
kmovw\t{%k1, %0|%0, %k1}
kmovw\t{%1, %0|%0, %1}";
- [(set_attr "mode" "HI")
- (set_attr "type" "mskmov")
- (set_attr "prefix" "vex")])
-
+ [(set_attr "type" "mskmov")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "HI")])
(define_insn "*movhi_internal"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
(match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
case TYPE_MSKMOV:
switch (which_alternative)
- {
- case 4: return "kmovw\t{%k1, %0|%0, %k1}";
- case 5: /* FALLTHRU */
- case 7: return "kmovw\t{%1, %0|%0, %1}";
- case 6: return "kmovw\t{%1, %k0|%k0, %1}";
- default: gcc_unreachable ();
+ {
+ case 4:
+ return "kmovw\t{%k1, %0|%0, %k1}";
+ case 6:
+ return "kmovw\t{%1, %k0|%k0, %1}";
+ case 5:
+ case 7:
+ return "kmovw\t{%1, %0|%0, %1}";
+ default:
+ gcc_unreachable ();
}
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{w}\t{%1, %0|%0, %1}";
+ return "mov{w}\t{%1, %0|%0, %1}";
}
}
[(set (attr "type")
(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:
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")
(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")
kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
[(set_attr "isa" "*,<kmov_isa>")
(set_attr "type" "imovx,mskmov")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "SI,<MODE>")])
(define_expand "zero_extend<mode>si2"
[(set (match_operand:SI 0 "register_operand")
"@
movz{bl|x}\t{%1, %k0|%k0, %1}
kmovb\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx,mskmov")
- (set_attr "isa" "*,avx512dq")
+ [(set_attr "isa" "*,avx512dq")
+ (set_attr "type" "imovx,mskmov")
(set_attr "mode" "SI,QI")])
(define_insn_and_split "*zext<mode>_doubleword_and"
(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,
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")
case 1:
return "#";
case 2:
- if (TARGET_AVX512DQ && <MODE>mode == QImode)
- return "kandnb\t{%2, %1, %0|%0, %1, %2}";
- else
+ if (get_attr_mode (insn) == MODE_HI)
return "kandnw\t{%2, %1, %0|%0, %1, %2}";
+ else
+ return "kandn<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
default:
gcc_unreachable ();
}
(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")
(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}";
-}
- [(set_attr "type" "*,msklog")
- (set_attr "prefix" "*,vex")
- (set_attr "mode" "<MODE>")])
+ if (which_alternative == 0)
+ return "#";
-(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}"
+ 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_split
[(set (match_operand:SWI1248x 0 "general_reg_operand")
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 ();
}
[(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")