===================================================================
@@ -186,9 +186,6 @@
UNSPEC_PDEP
UNSPEC_PEXT
- ;; For AVX512F support
- UNSPEC_KMASKOP
-
UNSPEC_BNDMK
UNSPEC_BNDMK_ADDR
UNSPEC_BNDSTX
@@ -921,9 +918,6 @@
(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
-;; Mask variant left right mnemonics
-(define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
-
;; Mapping of rotate operators
(define_code_iterator any_rotate [rotate rotatert])
@@ -966,15 +960,6 @@
;; All integer modes.
(define_mode_iterator SWI1248x [QI HI SI DI])
-;; All integer modes with AVX512BW/DQ.
-(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])
@@ -2489,11 +2474,6 @@
]
(const_string "SI")))])
-(define_expand "kmovw"
- [(set (match_operand:HI 0 "nonimmediate_operand")
- (match_operand:HI 1 "nonimmediate_operand"))]
- "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
-
(define_insn "*movhi_internal"
[(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"))]
@@ -8061,28 +8041,6 @@
operands[3] = gen_lowpart (QImode, operands[3]);
})
-(define_insn "k<code><mode>"
- [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
- (any_logic:SWI1248_AVX512BW
- (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")
- (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))
- (unspec [(const_int 0)] UNSPEC_KMASKOP)]
- "TARGET_AVX512F"
-{
- 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 "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,
;; it should be done with splitters.
@@ -8576,29 +8534,6 @@
operands[2] = gen_lowpart (QImode, operands[2]);
})
-(define_insn "kandn<mode>"
- [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
- (and:SWI1248_AVX512BW
- (not:SWI1248_AVX512BW
- (match_operand:SWI1248_AVX512BW 1 "register_operand" "k"))
- (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))
- (unspec [(const_int 0)] UNSPEC_KMASKOP)]
- "TARGET_AVX512F"
-{
- 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}";
-}
- [(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>")))])
-
(define_insn_and_split "*andndi3_doubleword"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI
@@ -8987,92 +8922,6 @@
(set_attr "type" "alu")
(set_attr "modrm" "1")
(set_attr "mode" "QI")])
-
-(define_insn "kxnor<mode>"
- [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
- (not:SWI1248_AVX512BW
- (xor:SWI1248_AVX512BW
- (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")
- (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))))
- (unspec [(const_int 0)] UNSPEC_KMASKOP)]
- "TARGET_AVX512F"
-{
- 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")
- (cond [(and (match_test "<MODE>mode == QImode")
- (not (match_test "TARGET_AVX512DQ")))
- (const_string "HI")
- ]
- (const_string "<MODE>")))])
-
-;;There are kortrest[bdq] but no intrinsics for them.
-;;We probably don't need to implement them.
-(define_insn "kortestzhi"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ
- (ior:HI
- (match_operand:HI 0 "register_operand" "k")
- (match_operand:HI 1 "register_operand" "k"))
- (const_int 0)))]
- "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
- "kortestw\t{%1, %0|%0, %1}"
- [(set_attr "mode" "HI")
- (set_attr "type" "msklog")
- (set_attr "prefix" "vex")])
-
-(define_insn "kortestchi"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (ior:HI
- (match_operand:HI 0 "register_operand" "k")
- (match_operand:HI 1 "register_operand" "k"))
- (const_int -1)))]
- "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
- "kortestw\t{%1, %0|%0, %1}"
- [(set_attr "mode" "HI")
- (set_attr "type" "msklog")
- (set_attr "prefix" "vex")])
-
-(define_insn "kunpckhi"
- [(set (match_operand:HI 0 "register_operand" "=k")
- (ior:HI
- (ashift:HI
- (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
- (const_int 8))
- (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
- "TARGET_AVX512F"
- "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "mode" "HI")
- (set_attr "type" "msklog")
- (set_attr "prefix" "vex")])
-
-(define_insn "kunpcksi"
- [(set (match_operand:SI 0 "register_operand" "=k")
- (ior:SI
- (ashift:SI
- (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
- (const_int 16))
- (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
- "TARGET_AVX512BW"
- "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "mode" "SI")])
-
-(define_insn "kunpckdi"
- [(set (match_operand:DI 0 "register_operand" "=k")
- (ior:DI
- (ashift:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
- (const_int 32))
- (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
- "TARGET_AVX512BW"
- "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "mode" "DI")])
;; Negation instructions
@@ -9463,27 +9312,6 @@
;; One complement instructions
-(define_insn "knot<mode>"
- [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
- (not:SWI1248_AVX512BW
- (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")))
- (unspec [(const_int 0)] UNSPEC_KMASKOP)]
- "TARGET_AVX512F"
-{
- if (get_attr_mode (insn) == MODE_HI)
- return "knotw\t{%1, %0|%0, %1}";
- else
- return "knot<mskmodesuffix>\t{%1, %0|%0, %1}";
-}
- [(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>")))])
-
(define_expand "one_cmpl<mode>2"
[(set (match_operand:SWIM 0 "nonimmediate_operand")
(not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
@@ -9600,18 +9428,6 @@
;; shift pair, instead using moves and sign extension for counts greater
;; than 31.
-(define_insn "*k<code><mode>"
- [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
- (any_lshift:SWI1248_AVX512BWDQ
- (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
- (match_operand:QI 2 "immediate_operand" "n")))
- (unspec [(const_int 0)] UNSPEC_KMASKOP)]
- "TARGET_AVX512F"
- "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "msklog")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
(define_expand "ashl<mode>3"
[(set (match_operand:SDWIM 0 "<shift_operand>")
(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
===================================================================
@@ -106,6 +106,9 @@
UNSPEC_MASKED_EQ
UNSPEC_MASKED_GT
+ ;; Mask operations
+ UNSPEC_MASKOP
+
;; For embed. rounding feature
UNSPEC_EMBEDDED_ROUNDING
@@ -1290,6 +1293,195 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
+;; Mask operations
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; All integer modes with AVX512BW/DQ.
+(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")])
+
+;; Mask variant shift mnemonics
+(define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
+
+(define_expand "kmovw"
+ [(set (match_operand:HI 0 "nonimmediate_operand")
+ (match_operand:HI 1 "nonimmediate_operand"))]
+ "TARGET_AVX512F
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
+
+(define_insn "k<code><mode>"
+ [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
+ (any_logic:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")
+ (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))
+ (unspec [(const_int 0)] UNSPEC_MASKOP)]
+ "TARGET_AVX512F"
+{
+ 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 "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>")))])
+
+(define_insn "kandn<mode>"
+ [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
+ (and:SWI1248_AVX512BW
+ (not:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "register_operand" "k"))
+ (match_operand:SWI1248_AVX512BW 2 "register_operand" "k")))
+ (unspec [(const_int 0)] UNSPEC_MASKOP)]
+ "TARGET_AVX512F"
+{
+ 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}";
+}
+ [(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>")))])
+
+(define_insn "kxnor<mode>"
+ [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
+ (not:SWI1248_AVX512BW
+ (xor:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")
+ (match_operand:SWI1248_AVX512BW 2 "register_operand" "k"))))
+ (unspec [(const_int 0)] UNSPEC_MASKOP)]
+ "TARGET_AVX512F"
+{
+ 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")
+ (cond [(and (match_test "<MODE>mode == QImode")
+ (not (match_test "TARGET_AVX512DQ")))
+ (const_string "HI")
+ ]
+ (const_string "<MODE>")))])
+
+(define_insn "knot<mode>"
+ [(set (match_operand:SWI1248_AVX512BW 0 "register_operand" "=k")
+ (not:SWI1248_AVX512BW
+ (match_operand:SWI1248_AVX512BW 1 "register_operand" "k")))
+ (unspec [(const_int 0)] UNSPEC_MASKOP)]
+ "TARGET_AVX512F"
+{
+ if (get_attr_mode (insn) == MODE_HI)
+ return "knotw\t{%1, %0|%0, %1}";
+ else
+ return "knot<mskmodesuffix>\t{%1, %0|%0, %1}";
+}
+ [(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>")))])
+
+(define_insn "*k<code><mode>"
+ [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
+ (any_lshift:SWI1248_AVX512BWDQ
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
+ (match_operand:QI 2 "immediate_operand" "n")))
+ (unspec [(const_int 0)] UNSPEC_MASKOP)]
+ "TARGET_AVX512F"
+ "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "msklog")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "<MODE>")])
+
+;;There are kortrest[bdq] but no intrinsics for them.
+;;We probably don't need to implement them.
+(define_insn "kortestzhi"
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (ior:HI
+ (match_operand:HI 0 "register_operand" "k")
+ (match_operand:HI 1 "register_operand" "k"))
+ (const_int 0)))]
+ "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
+ "kortestw\t{%1, %0|%0, %1}"
+ [(set_attr "mode" "HI")
+ (set_attr "type" "msklog")
+ (set_attr "prefix" "vex")])
+
+(define_insn "kortestchi"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (ior:HI
+ (match_operand:HI 0 "register_operand" "k")
+ (match_operand:HI 1 "register_operand" "k"))
+ (const_int -1)))]
+ "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
+ "kortestw\t{%1, %0|%0, %1}"
+ [(set_attr "mode" "HI")
+ (set_attr "type" "msklog")
+ (set_attr "prefix" "vex")])
+
+(define_insn "kunpckhi"
+ [(set (match_operand:HI 0 "register_operand" "=k")
+ (ior:HI
+ (ashift:HI
+ (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
+ (const_int 8))
+ (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
+ "TARGET_AVX512F"
+ "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "mode" "HI")
+ (set_attr "type" "msklog")
+ (set_attr "prefix" "vex")])
+
+(define_insn "kunpcksi"
+ [(set (match_operand:SI 0 "register_operand" "=k")
+ (ior:SI
+ (ashift:SI
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
+ (const_int 16))
+ (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
+ "TARGET_AVX512BW"
+ "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "mode" "SI")])
+
+(define_insn "kunpckdi"
+ [(set (match_operand:DI 0 "register_operand" "=k")
+ (ior:DI
+ (ashift:DI
+ (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
+ (const_int 32))
+ (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
+ "TARGET_AVX512BW"
+ "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "mode" "DI")])
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
;; Parallel floating point arithmetic
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
===================================================================
@@ -8,5 +8,8 @@
void
avx512f_test ()
{
- k1 = _mm512_kmov (11);
+ __mmask16 k = _mm512_kmov (11);
+
+ asm volatile ("" : "+k" (k));
+ k1 = k;
}