b205de058a6b9367e309442ed57d2d85f85c0b18
[oota-llvm.git] / lib / Target / X86 / X86InstrAVX512.td
1 // Group template arguments that can be derived from the vector type (EltNum x
2 // EltVT).  These are things like the register class for the writemask, etc.
3 // The idea is to pass one of these as the template argument rather than the
4 // individual arguments.
5 class X86VectorVTInfo<int NumElts, ValueType EltVT, RegisterClass rc,
6                       string suffix = ""> {
7   RegisterClass RC = rc;
8
9   // Corresponding mask register class.
10   RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
11
12   // Corresponding write-mask register class.
13   RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
14
15   // The GPR register class that can hold the write mask.  Use GR8 for fewer
16   // than 8 elements.  Use shift-right and equal to work around the lack of
17   // !lt in tablegen.
18   RegisterClass MRC =
19     !cast<RegisterClass>("GR" #
20                          !if (!eq (!srl(NumElts, 3), 0), 8, NumElts));
21
22   // Suffix used in the instruction mnemonic.
23   string Suffix = suffix;
24
25   string VTName = "v" # NumElts # EltVT;
26
27   // The vector VT.
28   ValueType VT = !cast<ValueType>(VTName);
29
30   string EltTypeName = !cast<string>(EltVT);
31   // Size of the element type in bits, e.g. 32 for v16i32.
32   string EltSizeName = !subst("i", "", !subst("f", "", EltTypeName));
33   int EltSize = EltVT.Size;
34
35   // "i" for integer types and "f" for floating-point types
36   string TypeVariantName = !subst(EltSizeName, "", EltTypeName);
37
38   // Size of RC in bits, e.g. 512 for VR512.
39   int Size = VT.Size;
40
41   // The corresponding memory operand, e.g. i512mem for VR512.
42   X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
43   X86MemOperand ScalarMemOp = !cast<X86MemOperand>(EltVT # "mem");
44
45   // Load patterns
46   // Note: For 128/256-bit integer VT we choose loadv2i64/loadv4i64
47   //       due to load promotion during legalization
48   PatFrag LdFrag = !cast<PatFrag>("load" #
49                                   !if (!eq (TypeVariantName, "i"),
50                                        !if (!eq (Size, 128), "v2i64",
51                                        !if (!eq (Size, 256), "v4i64",
52                                             VTName)), VTName));
53   PatFrag ScalarLdFrag = !cast<PatFrag>("load" # EltVT);
54
55   // Load patterns used for memory operands.  We only have this defined in
56   // case of i64 element types for sub-512 integer vectors.  For now, keep
57   // MemOpFrag undefined in these cases.
58   PatFrag MemOpFrag =
59     !if (!eq (TypeVariantName, "f"), !cast<PatFrag>("memop" # VTName),
60     !if (!eq (EltTypeName, "i64"),   !cast<PatFrag>("memop" # VTName),
61     !if (!eq (VTName, "v16i32"),     !cast<PatFrag>("memop" # VTName), ?)));
62
63   // The corresponding float type, e.g. v16f32 for v16i32
64   // Note: For EltSize < 32, FloatVT is illegal and TableGen
65   //       fails to compile, so we choose FloatVT = VT
66   ValueType FloatVT = !cast<ValueType>(
67                         !if (!eq (!srl(EltSize,5),0),
68                              VTName,
69                              !if (!eq(TypeVariantName, "i"),
70                                   "v" # NumElts # "f" # EltSize,
71                                   VTName)));
72
73   // The string to specify embedded broadcast in assembly.
74   string BroadcastStr = "{1to" # NumElts # "}";
75
76   SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
77                           !if (!eq (Size, 256), sub_ymm, ?));
78
79   Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
80                      !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
81                      SSEPackedInt));
82 }
83
84 def v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
85 def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
86 def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
87 def v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
88 def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
89 def v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
90
91 // "x" in v32i8x_info means RC = VR256X
92 def v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
93 def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
94 def v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
95 def v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
96
97 def v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
98 def v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
99 def v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
100 def v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
101
102 class AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
103                            X86VectorVTInfo i128> {
104   X86VectorVTInfo info512 = i512;
105   X86VectorVTInfo info256 = i256;
106   X86VectorVTInfo info128 = i128;
107 }
108
109 def avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
110                                              v16i8x_info>;
111 def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
112                                              v8i16x_info>;
113 def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
114                                              v4i32x_info>;
115 def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
116                                              v2i64x_info>;
117
118
119 // Common base class of AVX512_masking and AVX512_masking_3src.
120 multiclass AVX512_masking_common<bits<8> O, Format F, X86VectorVTInfo _,
121                                  dag Outs,
122                                  dag Ins, dag MaskingIns, dag ZeroMaskingIns,
123                                  string OpcodeStr,
124                                  string AttSrcAsm, string IntelSrcAsm,
125                                  dag RHS, dag MaskingRHS,
126                                  string MaskingConstraint = ""> {
127   def NAME: AVX512<O, F, Outs, Ins,
128                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
129                                      "$dst, "#IntelSrcAsm#"}",
130                        [(set _.RC:$dst, RHS)]>;
131
132   // Prefer over VMOV*rrk Pat<>
133   let AddedComplexity = 20 in
134     def NAME#k: AVX512<O, F, Outs, MaskingIns,
135                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
136                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
137                        [(set _.RC:$dst, MaskingRHS)]>,
138               EVEX_K {
139       // In case of the 3src subclass this is overridden with a let.
140       string Constraints = MaskingConstraint;
141   }
142   let AddedComplexity = 30 in // Prefer over VMOV*rrkz Pat<>
143     def NAME#kz: AVX512<O, F, Outs, ZeroMaskingIns,
144                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}} {z}|"#
145                                      "$dst {${mask}} {z}, "#IntelSrcAsm#"}",
146                        [(set _.RC:$dst,
147                              (vselect _.KRCWM:$mask, RHS,
148                                       (_.VT (bitconvert
149                                               (v16i32 immAllZerosV)))))]>,
150               EVEX_KZ;
151 }
152
153 // This multiclass generates the unconditional/non-masking, the masking and
154 // the zero-masking variant of the instruction.  In the masking case, the
155 // perserved vector elements come from a new dummy input operand tied to $dst.
156 multiclass AVX512_masking<bits<8> O, Format F, X86VectorVTInfo _,
157                           dag Outs, dag Ins, string OpcodeStr,
158                           string AttSrcAsm, string IntelSrcAsm,
159                           dag RHS> :
160    AVX512_masking_common<O, F, _, Outs, Ins,
161                          !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
162                          !con((ins _.KRCWM:$mask), Ins),
163                          OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
164                          (vselect _.KRCWM:$mask, RHS, _.RC:$src0),
165                          "$src0 = $dst">;
166
167 // Similar to AVX512_masking but in this case one of the source operands
168 // ($src1) is already tied to $dst so we just use that for the preserved
169 // vector elements.  NOTE that the NonTiedIns (the ins dag) should exclude
170 // $src1.
171 multiclass AVX512_masking_3src<bits<8> O, Format F, X86VectorVTInfo _,
172                                dag Outs, dag NonTiedIns, string OpcodeStr,
173                                string AttSrcAsm, string IntelSrcAsm,
174                                dag RHS> :
175    AVX512_masking_common<O, F, _, Outs,
176                          !con((ins _.RC:$src1), NonTiedIns),
177                          !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
178                          !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
179                          OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
180                          (vselect _.KRCWM:$mask, RHS, _.RC:$src1)>;
181
182 // Bitcasts between 512-bit vector types. Return the original type since
183 // no instruction is needed for the conversion
184 let Predicates = [HasAVX512] in {
185   def : Pat<(v8f64  (bitconvert (v8i64 VR512:$src))),  (v8f64 VR512:$src)>;
186   def : Pat<(v8f64  (bitconvert (v16i32 VR512:$src))), (v8f64 VR512:$src)>;
187   def : Pat<(v8f64  (bitconvert (v32i16 VR512:$src))),  (v8f64 VR512:$src)>;
188   def : Pat<(v8f64  (bitconvert (v64i8 VR512:$src))), (v8f64 VR512:$src)>;
189   def : Pat<(v8f64  (bitconvert (v16f32 VR512:$src))), (v8f64 VR512:$src)>;
190   def : Pat<(v16f32 (bitconvert (v8i64 VR512:$src))),  (v16f32 VR512:$src)>;
191   def : Pat<(v16f32 (bitconvert (v16i32 VR512:$src))), (v16f32 VR512:$src)>;
192   def : Pat<(v16f32 (bitconvert (v32i16 VR512:$src))), (v16f32 VR512:$src)>;
193   def : Pat<(v16f32 (bitconvert (v64i8 VR512:$src))), (v16f32 VR512:$src)>;
194   def : Pat<(v16f32 (bitconvert (v8f64 VR512:$src))),  (v16f32 VR512:$src)>;
195   def : Pat<(v8i64  (bitconvert (v16i32 VR512:$src))), (v8i64 VR512:$src)>;
196   def : Pat<(v8i64  (bitconvert (v32i16 VR512:$src))), (v8i64 VR512:$src)>;
197   def : Pat<(v8i64  (bitconvert (v64i8 VR512:$src))), (v8i64 VR512:$src)>;
198   def : Pat<(v8i64  (bitconvert (v8f64 VR512:$src))),  (v8i64 VR512:$src)>;
199   def : Pat<(v8i64  (bitconvert (v16f32 VR512:$src))), (v8i64 VR512:$src)>;
200   def : Pat<(v16i32 (bitconvert (v8i64 VR512:$src))), (v16i32 VR512:$src)>;
201   def : Pat<(v16i32 (bitconvert (v16f32 VR512:$src))), (v16i32 VR512:$src)>;
202   def : Pat<(v16i32 (bitconvert (v32i16 VR512:$src))),  (v16i32 VR512:$src)>;
203   def : Pat<(v16i32 (bitconvert (v64i8 VR512:$src))),  (v16i32 VR512:$src)>;
204   def : Pat<(v16i32 (bitconvert (v8f64 VR512:$src))),  (v16i32 VR512:$src)>;
205   def : Pat<(v32i16 (bitconvert (v8i64 VR512:$src))), (v32i16 VR512:$src)>;
206   def : Pat<(v32i16 (bitconvert (v16i32 VR512:$src))),  (v32i16 VR512:$src)>;
207   def : Pat<(v32i16 (bitconvert (v64i8 VR512:$src))),  (v32i16 VR512:$src)>;
208   def : Pat<(v32i16 (bitconvert (v8f64 VR512:$src))),  (v32i16 VR512:$src)>;
209   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
210   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
211   def : Pat<(v64i8  (bitconvert (v8i64 VR512:$src))), (v64i8 VR512:$src)>;
212   def : Pat<(v64i8  (bitconvert (v16i32 VR512:$src))), (v64i8 VR512:$src)>;
213   def : Pat<(v64i8  (bitconvert (v32i16 VR512:$src))), (v64i8 VR512:$src)>;
214   def : Pat<(v64i8  (bitconvert (v8f64 VR512:$src))),  (v64i8 VR512:$src)>;
215   def : Pat<(v64i8  (bitconvert (v16f32 VR512:$src))), (v64i8 VR512:$src)>;
216
217   def : Pat<(v2i64 (bitconvert (v4i32 VR128X:$src))), (v2i64 VR128X:$src)>;
218   def : Pat<(v2i64 (bitconvert (v8i16 VR128X:$src))), (v2i64 VR128X:$src)>;
219   def : Pat<(v2i64 (bitconvert (v16i8 VR128X:$src))), (v2i64 VR128X:$src)>;
220   def : Pat<(v2i64 (bitconvert (v2f64 VR128X:$src))), (v2i64 VR128X:$src)>;
221   def : Pat<(v2i64 (bitconvert (v4f32 VR128X:$src))), (v2i64 VR128X:$src)>;
222   def : Pat<(v4i32 (bitconvert (v2i64 VR128X:$src))), (v4i32 VR128X:$src)>;
223   def : Pat<(v4i32 (bitconvert (v8i16 VR128X:$src))), (v4i32 VR128X:$src)>;
224   def : Pat<(v4i32 (bitconvert (v16i8 VR128X:$src))), (v4i32 VR128X:$src)>;
225   def : Pat<(v4i32 (bitconvert (v2f64 VR128X:$src))), (v4i32 VR128X:$src)>;
226   def : Pat<(v4i32 (bitconvert (v4f32 VR128X:$src))), (v4i32 VR128X:$src)>;
227   def : Pat<(v8i16 (bitconvert (v2i64 VR128X:$src))), (v8i16 VR128X:$src)>;
228   def : Pat<(v8i16 (bitconvert (v4i32 VR128X:$src))), (v8i16 VR128X:$src)>;
229   def : Pat<(v8i16 (bitconvert (v16i8 VR128X:$src))), (v8i16 VR128X:$src)>;
230   def : Pat<(v8i16 (bitconvert (v2f64 VR128X:$src))), (v8i16 VR128X:$src)>;
231   def : Pat<(v8i16 (bitconvert (v4f32 VR128X:$src))), (v8i16 VR128X:$src)>;
232   def : Pat<(v16i8 (bitconvert (v2i64 VR128X:$src))), (v16i8 VR128X:$src)>;
233   def : Pat<(v16i8 (bitconvert (v4i32 VR128X:$src))), (v16i8 VR128X:$src)>;
234   def : Pat<(v16i8 (bitconvert (v8i16 VR128X:$src))), (v16i8 VR128X:$src)>;
235   def : Pat<(v16i8 (bitconvert (v2f64 VR128X:$src))), (v16i8 VR128X:$src)>;
236   def : Pat<(v16i8 (bitconvert (v4f32 VR128X:$src))), (v16i8 VR128X:$src)>;
237   def : Pat<(v4f32 (bitconvert (v2i64 VR128X:$src))), (v4f32 VR128X:$src)>;
238   def : Pat<(v4f32 (bitconvert (v4i32 VR128X:$src))), (v4f32 VR128X:$src)>;
239   def : Pat<(v4f32 (bitconvert (v8i16 VR128X:$src))), (v4f32 VR128X:$src)>;
240   def : Pat<(v4f32 (bitconvert (v16i8 VR128X:$src))), (v4f32 VR128X:$src)>;
241   def : Pat<(v4f32 (bitconvert (v2f64 VR128X:$src))), (v4f32 VR128X:$src)>;
242   def : Pat<(v2f64 (bitconvert (v2i64 VR128X:$src))), (v2f64 VR128X:$src)>;
243   def : Pat<(v2f64 (bitconvert (v4i32 VR128X:$src))), (v2f64 VR128X:$src)>;
244   def : Pat<(v2f64 (bitconvert (v8i16 VR128X:$src))), (v2f64 VR128X:$src)>;
245   def : Pat<(v2f64 (bitconvert (v16i8 VR128X:$src))), (v2f64 VR128X:$src)>;
246   def : Pat<(v2f64 (bitconvert (v4f32 VR128X:$src))), (v2f64 VR128X:$src)>;
247
248 // Bitcasts between 256-bit vector types. Return the original type since
249 // no instruction is needed for the conversion
250   def : Pat<(v4f64  (bitconvert (v8f32 VR256X:$src))),  (v4f64 VR256X:$src)>;
251   def : Pat<(v4f64  (bitconvert (v8i32 VR256X:$src))),  (v4f64 VR256X:$src)>;
252   def : Pat<(v4f64  (bitconvert (v4i64 VR256X:$src))),  (v4f64 VR256X:$src)>;
253   def : Pat<(v4f64  (bitconvert (v16i16 VR256X:$src))), (v4f64 VR256X:$src)>;
254   def : Pat<(v4f64  (bitconvert (v32i8 VR256X:$src))),  (v4f64 VR256X:$src)>;
255   def : Pat<(v8f32  (bitconvert (v8i32 VR256X:$src))),  (v8f32 VR256X:$src)>;
256   def : Pat<(v8f32  (bitconvert (v4i64 VR256X:$src))),  (v8f32 VR256X:$src)>;
257   def : Pat<(v8f32  (bitconvert (v4f64 VR256X:$src))),  (v8f32 VR256X:$src)>;
258   def : Pat<(v8f32  (bitconvert (v32i8 VR256X:$src))),  (v8f32 VR256X:$src)>;
259   def : Pat<(v8f32  (bitconvert (v16i16 VR256X:$src))), (v8f32 VR256X:$src)>;
260   def : Pat<(v4i64  (bitconvert (v8f32 VR256X:$src))),  (v4i64 VR256X:$src)>;
261   def : Pat<(v4i64  (bitconvert (v8i32 VR256X:$src))),  (v4i64 VR256X:$src)>;
262   def : Pat<(v4i64  (bitconvert (v4f64 VR256X:$src))),  (v4i64 VR256X:$src)>;
263   def : Pat<(v4i64  (bitconvert (v32i8 VR256X:$src))),  (v4i64 VR256X:$src)>;
264   def : Pat<(v4i64  (bitconvert (v16i16 VR256X:$src))), (v4i64 VR256X:$src)>;
265   def : Pat<(v32i8  (bitconvert (v4f64 VR256X:$src))),  (v32i8 VR256X:$src)>;
266   def : Pat<(v32i8  (bitconvert (v4i64 VR256X:$src))),  (v32i8 VR256X:$src)>;
267   def : Pat<(v32i8  (bitconvert (v8f32 VR256X:$src))),  (v32i8 VR256X:$src)>;
268   def : Pat<(v32i8  (bitconvert (v8i32 VR256X:$src))),  (v32i8 VR256X:$src)>;
269   def : Pat<(v32i8  (bitconvert (v16i16 VR256X:$src))), (v32i8 VR256X:$src)>;
270   def : Pat<(v8i32  (bitconvert (v32i8 VR256X:$src))),  (v8i32 VR256X:$src)>;
271   def : Pat<(v8i32  (bitconvert (v16i16 VR256X:$src))), (v8i32 VR256X:$src)>;
272   def : Pat<(v8i32  (bitconvert (v8f32 VR256X:$src))),  (v8i32 VR256X:$src)>;
273   def : Pat<(v8i32  (bitconvert (v4i64 VR256X:$src))),  (v8i32 VR256X:$src)>;
274   def : Pat<(v8i32  (bitconvert (v4f64 VR256X:$src))),  (v8i32 VR256X:$src)>;
275   def : Pat<(v16i16 (bitconvert (v8f32 VR256X:$src))),  (v16i16 VR256X:$src)>;
276   def : Pat<(v16i16 (bitconvert (v8i32 VR256X:$src))),  (v16i16 VR256X:$src)>;
277   def : Pat<(v16i16 (bitconvert (v4i64 VR256X:$src))),  (v16i16 VR256X:$src)>;
278   def : Pat<(v16i16 (bitconvert (v4f64 VR256X:$src))),  (v16i16 VR256X:$src)>;
279   def : Pat<(v16i16 (bitconvert (v32i8 VR256X:$src))),  (v16i16 VR256X:$src)>;
280 }
281
282 //
283 // AVX-512: VPXOR instruction writes zero to its upper part, it's safe build zeros.
284 //
285
286 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
287     isPseudo = 1, Predicates = [HasAVX512] in {
288 def AVX512_512_SET0 : I<0, Pseudo, (outs VR512:$dst), (ins), "",
289                [(set VR512:$dst, (v16f32 immAllZerosV))]>;
290 }
291
292 let Predicates = [HasAVX512] in {
293 def : Pat<(v8i64 immAllZerosV), (AVX512_512_SET0)>;
294 def : Pat<(v16i32 immAllZerosV), (AVX512_512_SET0)>;
295 def : Pat<(v8f64 immAllZerosV), (AVX512_512_SET0)>;
296 }
297
298 //===----------------------------------------------------------------------===//
299 // AVX-512 - VECTOR INSERT
300 //
301
302 multiclass vinsert_for_size<int Opcode,
303                              X86VectorVTInfo From, X86VectorVTInfo To,
304                              X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo,
305                              PatFrag vinsert_insert,
306                              SDNodeXForm INSERT_get_vinsert_imm> {
307   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
308     def rr : AVX512AIi8<Opcode, MRMSrcReg, (outs VR512:$dst),
309                (ins VR512:$src1, From.RC:$src2, i8imm:$src3),
310                "vinsert" # From.EltTypeName # "x4\t{$src3, $src2, $src1, $dst|"
311                                                    "$dst, $src1, $src2, $src3}",
312                [(set To.RC:$dst, (vinsert_insert:$src3 (To.VT VR512:$src1),
313                                                        (From.VT From.RC:$src2),
314                                                        (iPTR imm)))]>,
315              EVEX_4V, EVEX_V512;
316
317     let mayLoad = 1 in
318     def rm : AVX512AIi8<Opcode, MRMSrcMem, (outs VR512:$dst),
319                (ins VR512:$src1, From.MemOp:$src2, i8imm:$src3),
320                "vinsert" # From.EltTypeName # "x4\t{$src3, $src2, $src1, $dst|"
321                                                    "$dst, $src1, $src2, $src3}",
322                []>, EVEX_4V, EVEX_V512, EVEX_CD8<From.EltSize, CD8VT4>;
323   }
324
325   // Codegen pattern with the alternative types, e.g. v2i64 -> v8i64 for
326   // vinserti32x4
327   def : Pat<(vinsert_insert:$ins
328                (AltTo.VT VR512:$src1), (AltFrom.VT From.RC:$src2), (iPTR imm)),
329             (AltTo.VT (!cast<Instruction>(NAME # From.EltSize # "x4rr")
330                           VR512:$src1, From.RC:$src2,
331                           (INSERT_get_vinsert_imm VR512:$ins)))>;
332 }
333
334 multiclass vinsert_for_type<ValueType EltVT32, int Opcode32,
335                             ValueType EltVT64, int Opcode64> {
336   defm NAME # "32x4" : vinsert_for_size<Opcode32,
337                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
338                                  X86VectorVTInfo<16, EltVT32, VR512>,
339                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
340                                  X86VectorVTInfo< 8, EltVT64, VR512>,
341                                  vinsert128_insert,
342                                  INSERT_get_vinsert128_imm>;
343   defm NAME # "64x4" : vinsert_for_size<Opcode64,
344                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
345                                  X86VectorVTInfo< 8, EltVT64, VR512>,
346                                  X86VectorVTInfo< 8, EltVT32, VR256>,
347                                  X86VectorVTInfo<16, EltVT32, VR512>,
348                                  vinsert256_insert,
349                                  INSERT_get_vinsert256_imm>, VEX_W;
350 }
351
352 defm VINSERTF : vinsert_for_type<f32, 0x18, f64, 0x1a>;
353 defm VINSERTI : vinsert_for_type<i32, 0x38, i64, 0x3a>;
354
355 // vinsertps - insert f32 to XMM
356 def VINSERTPSzrr : AVX512AIi8<0x21, MRMSrcReg, (outs VR128X:$dst),
357       (ins VR128X:$src1, VR128X:$src2, i8imm:$src3),
358       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
359       [(set VR128X:$dst, (X86insertps VR128X:$src1, VR128X:$src2, imm:$src3))]>,
360       EVEX_4V;
361 def VINSERTPSzrm: AVX512AIi8<0x21, MRMSrcMem, (outs VR128X:$dst),
362       (ins VR128X:$src1, f32mem:$src2, i8imm:$src3),
363       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
364       [(set VR128X:$dst, (X86insertps VR128X:$src1,
365                           (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
366                           imm:$src3))]>, EVEX_4V, EVEX_CD8<32, CD8VT1>;
367
368 //===----------------------------------------------------------------------===//
369 // AVX-512 VECTOR EXTRACT
370 //---
371
372 multiclass vextract_for_size<int Opcode,
373                              X86VectorVTInfo From, X86VectorVTInfo To,
374                              X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo,
375                              PatFrag vextract_extract,
376                              SDNodeXForm EXTRACT_get_vextract_imm> {
377   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
378     def rr : AVX512AIi8<Opcode, MRMDestReg, (outs To.RC:$dst),
379             (ins VR512:$src1, i8imm:$idx),
380             "vextract" # To.EltTypeName # "x4\t{$idx, $src1, $dst|"
381                                                "$dst, $src1, $idx}",
382             [(set To.RC:$dst, (vextract_extract:$idx (From.VT VR512:$src1),
383                                                      (iPTR imm)))]>,
384             EVEX, EVEX_V512;
385     let mayStore = 1 in
386     def rm : AVX512AIi8<Opcode, MRMDestMem, (outs),
387             (ins To.MemOp:$dst, VR512:$src1, i8imm:$src2),
388             "vextract" # To.EltTypeName # "x4\t{$src2, $src1, $dst|"
389                                                "$dst, $src1, $src2}",
390             []>, EVEX, EVEX_V512, EVEX_CD8<To.EltSize, CD8VT4>;
391   }
392
393   // Codegen pattern with the alternative types, e.g. v8i64 -> v2i64 for
394   // vextracti32x4
395   def : Pat<(vextract_extract:$ext (AltFrom.VT VR512:$src1), (iPTR imm)),
396             (AltTo.VT (!cast<Instruction>(NAME # To.EltSize # "x4rr")
397                           VR512:$src1,
398                           (EXTRACT_get_vextract_imm To.RC:$ext)))>;
399
400   // A 128/256-bit subvector extract from the first 512-bit vector position is
401   // a subregister copy that needs no instruction.
402   def : Pat<(To.VT (extract_subvector (From.VT VR512:$src), (iPTR 0))),
403             (To.VT
404                (EXTRACT_SUBREG (From.VT VR512:$src), To.SubRegIdx))>;
405
406   // And for the alternative types.
407   def : Pat<(AltTo.VT (extract_subvector (AltFrom.VT VR512:$src), (iPTR 0))),
408             (AltTo.VT
409                (EXTRACT_SUBREG (AltFrom.VT VR512:$src), AltTo.SubRegIdx))>;
410 }
411
412 multiclass vextract_for_type<ValueType EltVT32, int Opcode32,
413                              ValueType EltVT64, int Opcode64> {
414   defm NAME # "32x4" : vextract_for_size<Opcode32,
415                                  X86VectorVTInfo<16, EltVT32, VR512>,
416                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
417                                  X86VectorVTInfo< 8, EltVT64, VR512>,
418                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
419                                  vextract128_extract,
420                                  EXTRACT_get_vextract128_imm>;
421   defm NAME # "64x4" : vextract_for_size<Opcode64,
422                                  X86VectorVTInfo< 8, EltVT64, VR512>,
423                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
424                                  X86VectorVTInfo<16, EltVT32, VR512>,
425                                  X86VectorVTInfo< 8, EltVT32, VR256>,
426                                  vextract256_extract,
427                                  EXTRACT_get_vextract256_imm>, VEX_W;
428 }
429
430 defm VEXTRACTF : vextract_for_type<f32, 0x19, f64, 0x1b>;
431 defm VEXTRACTI : vextract_for_type<i32, 0x39, i64, 0x3b>;
432
433 // A 128-bit subvector insert to the first 512-bit vector position
434 // is a subregister copy that needs no instruction.
435 def : Pat<(insert_subvector undef, (v2i64 VR128X:$src), (iPTR 0)),
436           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)),
437           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
438           sub_ymm)>;
439 def : Pat<(insert_subvector undef, (v2f64 VR128X:$src), (iPTR 0)),
440           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)),
441           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
442           sub_ymm)>;
443 def : Pat<(insert_subvector undef, (v4i32 VR128X:$src), (iPTR 0)),
444           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
445           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
446           sub_ymm)>;
447 def : Pat<(insert_subvector undef, (v4f32 VR128X:$src), (iPTR 0)),
448           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
449           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
450           sub_ymm)>;
451
452 def : Pat<(insert_subvector undef, (v4i64 VR256X:$src), (iPTR 0)),
453           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
454 def : Pat<(insert_subvector undef, (v4f64 VR256X:$src), (iPTR 0)),
455           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
456 def : Pat<(insert_subvector undef, (v8i32 VR256X:$src), (iPTR 0)),
457           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
458 def : Pat<(insert_subvector undef, (v8f32 VR256X:$src), (iPTR 0)),
459           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
460
461 // vextractps - extract 32 bits from XMM
462 def VEXTRACTPSzrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32:$dst),
463       (ins VR128X:$src1, i32i8imm:$src2),
464       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
465       [(set GR32:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
466       EVEX;
467
468 def VEXTRACTPSzmr : AVX512AIi8<0x17, MRMDestMem, (outs),
469       (ins f32mem:$dst, VR128X:$src1, i32i8imm:$src2),
470       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
471       [(store (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2),
472                           addr:$dst)]>, EVEX, EVEX_CD8<32, CD8VT1>;
473
474 //===---------------------------------------------------------------------===//
475 // AVX-512 BROADCAST
476 //---
477 multiclass avx512_fp_broadcast<bits<8> opc, string OpcodeStr, 
478                          RegisterClass DestRC,
479                          RegisterClass SrcRC, X86MemOperand x86memop> {
480   def rr : AVX5128I<opc, MRMSrcReg, (outs DestRC:$dst), (ins SrcRC:$src),
481          !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
482          []>, EVEX;
483   def rm : AVX5128I<opc, MRMSrcMem, (outs DestRC:$dst), (ins x86memop:$src),
484         !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),[]>, EVEX;
485 }
486 let ExeDomain = SSEPackedSingle in {
487   defm VBROADCASTSSZ  : avx512_fp_broadcast<0x18, "vbroadcastss", VR512,
488                                        VR128X, f32mem>,
489                                        EVEX_V512, EVEX_CD8<32, CD8VT1>;
490 }
491
492 let ExeDomain = SSEPackedDouble in {
493   defm VBROADCASTSDZ  : avx512_fp_broadcast<0x19, "vbroadcastsd", VR512,
494                                        VR128X, f64mem>,
495                                        EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
496 }
497
498 def : Pat<(v16f32 (X86VBroadcast (loadf32 addr:$src))),
499           (VBROADCASTSSZrm addr:$src)>;
500 def : Pat<(v8f64 (X86VBroadcast (loadf64 addr:$src))),
501           (VBROADCASTSDZrm addr:$src)>;
502
503 def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
504           (VBROADCASTSSZrm addr:$src)>;
505 def : Pat<(int_x86_avx512_vbroadcast_sd_512 addr:$src),
506           (VBROADCASTSDZrm addr:$src)>;
507
508 multiclass avx512_int_broadcast_reg<bits<8> opc, string OpcodeStr,
509                           RegisterClass SrcRC, RegisterClass KRC> {
510   def Zrr : AVX5128I<opc, MRMSrcReg, (outs VR512:$dst), (ins SrcRC:$src),
511                    !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
512                    []>, EVEX, EVEX_V512;
513   def Zkrr : AVX5128I<opc, MRMSrcReg, (outs VR512:$dst), 
514                    (ins KRC:$mask, SrcRC:$src),
515                    !strconcat(OpcodeStr, 
516                         " \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
517                    []>, EVEX, EVEX_V512, EVEX_KZ;
518 }
519
520 defm VPBROADCASTDr  : avx512_int_broadcast_reg<0x7C, "vpbroadcastd", GR32, VK16WM>;
521 defm VPBROADCASTQr  : avx512_int_broadcast_reg<0x7C, "vpbroadcastq", GR64, VK8WM>,
522                                             VEX_W;
523                                             
524 def : Pat <(v16i32 (X86vzext VK16WM:$mask)),
525            (VPBROADCASTDrZkrr VK16WM:$mask, (i32 (MOV32ri 0x1)))>;
526
527 def : Pat <(v8i64 (X86vzext VK8WM:$mask)),
528            (VPBROADCASTQrZkrr VK8WM:$mask, (i64 (MOV64ri 0x1)))>;
529
530 def : Pat<(v16i32 (X86VBroadcast (i32 GR32:$src))),
531         (VPBROADCASTDrZrr GR32:$src)>;
532 def : Pat<(v16i32 (X86VBroadcastm VK16WM:$mask, (i32 GR32:$src))),
533         (VPBROADCASTDrZkrr VK16WM:$mask, GR32:$src)>;
534 def : Pat<(v8i64 (X86VBroadcast (i64 GR64:$src))),
535         (VPBROADCASTQrZrr GR64:$src)>;
536 def : Pat<(v8i64 (X86VBroadcastm VK8WM:$mask, (i64 GR64:$src))),
537         (VPBROADCASTQrZkrr VK8WM:$mask, GR64:$src)>;
538
539 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_i32_512 (i32 GR32:$src))),
540         (VPBROADCASTDrZrr GR32:$src)>;
541 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_i64_512 (i64 GR64:$src))),
542         (VPBROADCASTQrZrr GR64:$src)>;
543
544 def : Pat<(v16i32 (int_x86_avx512_mask_pbroadcast_d_gpr_512 (i32 GR32:$src),
545                    (v16i32 immAllZerosV), (i16 GR16:$mask))),
546           (VPBROADCASTDrZkrr (COPY_TO_REGCLASS GR16:$mask, VK16WM), GR32:$src)>;
547 def : Pat<(v8i64 (int_x86_avx512_mask_pbroadcast_q_gpr_512 (i64 GR64:$src),
548                    (bc_v8i64 (v16i32 immAllZerosV)), (i8 GR8:$mask))),
549           (VPBROADCASTQrZkrr (COPY_TO_REGCLASS GR8:$mask, VK8WM), GR64:$src)>;
550
551 multiclass avx512_int_broadcast_rm<bits<8> opc, string OpcodeStr,
552                           X86MemOperand x86memop, PatFrag ld_frag,
553                           RegisterClass DstRC, ValueType OpVT, ValueType SrcVT,
554                           RegisterClass KRC> {
555   def rr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins VR128X:$src),
556                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
557                   [(set DstRC:$dst,
558                     (OpVT (X86VBroadcast (SrcVT VR128X:$src))))]>, EVEX;
559   def krr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins KRC:$mask,
560                                                          VR128X:$src),
561                     !strconcat(OpcodeStr, 
562                     " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
563                     [(set DstRC:$dst,
564                       (OpVT (X86VBroadcastm KRC:$mask, (SrcVT VR128X:$src))))]>,
565                     EVEX, EVEX_KZ;
566   let mayLoad = 1 in {
567   def rm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
568                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
569                   [(set DstRC:$dst, 
570                     (OpVT (X86VBroadcast (ld_frag addr:$src))))]>, EVEX;
571   def krm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins KRC:$mask,
572                                                          x86memop:$src),
573                   !strconcat(OpcodeStr, 
574                       " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
575                   [(set DstRC:$dst, (OpVT (X86VBroadcastm KRC:$mask, 
576                                      (ld_frag addr:$src))))]>, EVEX, EVEX_KZ;
577   }
578 }
579
580 defm VPBROADCASTDZ  : avx512_int_broadcast_rm<0x58, "vpbroadcastd", i32mem,
581                       loadi32, VR512, v16i32, v4i32, VK16WM>,
582                       EVEX_V512, EVEX_CD8<32, CD8VT1>;
583 defm VPBROADCASTQZ  : avx512_int_broadcast_rm<0x59, "vpbroadcastq", i64mem,
584                       loadi64, VR512, v8i64, v2i64, VK8WM>,  EVEX_V512, VEX_W,
585                       EVEX_CD8<64, CD8VT1>;
586
587 multiclass avx512_int_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
588                           X86MemOperand x86memop, PatFrag ld_frag,
589                           RegisterClass KRC> {
590   let mayLoad = 1 in {
591   def rm : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst), (ins x86memop:$src),
592                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
593                   []>, EVEX;
594   def krm : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst), (ins KRC:$mask,
595                                                          x86memop:$src),
596                   !strconcat(OpcodeStr,
597                       " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
598                   []>, EVEX, EVEX_KZ;
599   }
600 }
601
602 defm VBROADCASTI32X4 : avx512_int_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
603                        i128mem, loadv2i64, VK16WM>,
604                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
605 defm VBROADCASTI64X4 : avx512_int_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
606                        i256mem, loadv4i64, VK16WM>, VEX_W,
607                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
608
609 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_512 (v4i32 VR128X:$src))),
610           (VPBROADCASTDZrr VR128X:$src)>;
611 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_512 (v2i64 VR128X:$src))),
612           (VPBROADCASTQZrr VR128X:$src)>;
613
614 def : Pat<(v16f32 (X86VBroadcast (v4f32 VR128X:$src))),
615           (VBROADCASTSSZrr VR128X:$src)>;
616 def : Pat<(v8f64 (X86VBroadcast (v2f64 VR128X:$src))),
617           (VBROADCASTSDZrr VR128X:$src)>;
618
619 def : Pat<(v16f32 (int_x86_avx512_vbroadcast_ss_ps_512 (v4f32 VR128X:$src))),
620           (VBROADCASTSSZrr VR128X:$src)>;
621 def : Pat<(v8f64 (int_x86_avx512_vbroadcast_sd_pd_512 (v2f64 VR128X:$src))),
622           (VBROADCASTSDZrr VR128X:$src)>;
623     
624 // Provide fallback in case the load node that is used in the patterns above
625 // is used by additional users, which prevents the pattern selection.
626 def : Pat<(v16f32 (X86VBroadcast FR32X:$src)),
627           (VBROADCASTSSZrr (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
628 def : Pat<(v8f64 (X86VBroadcast FR64X:$src)),
629           (VBROADCASTSDZrr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
630
631
632 let Predicates = [HasAVX512] in {
633 def : Pat<(v8i32 (X86VBroadcastm (v8i1 VK8WM:$mask), (loadi32 addr:$src))),
634            (EXTRACT_SUBREG 
635               (v16i32 (VPBROADCASTDZkrm (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
636                        addr:$src)), sub_ymm)>;
637 }
638 //===----------------------------------------------------------------------===//
639 // AVX-512 BROADCAST MASK TO VECTOR REGISTER
640 //---
641
642 multiclass avx512_mask_broadcast<bits<8> opc, string OpcodeStr,
643                        RegisterClass DstRC, RegisterClass KRC,
644                        ValueType OpVT, ValueType SrcVT> {
645 def rr : AVX512XS8I<opc, MRMDestReg, (outs DstRC:$dst), (ins KRC:$src),
646                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
647                   []>, EVEX;
648 }
649
650 let Predicates = [HasCDI] in {
651 defm VPBROADCASTMW2D : avx512_mask_broadcast<0x3A, "vpbroadcastmw2d", VR512,
652                                              VK16, v16i32, v16i1>, EVEX_V512;
653 defm VPBROADCASTMB2Q : avx512_mask_broadcast<0x2A, "vpbroadcastmb2q", VR512,
654                                             VK8, v8i64, v8i1>, EVEX_V512, VEX_W;
655 }
656
657 //===----------------------------------------------------------------------===//
658 // AVX-512 - VPERM
659 //
660 // -- immediate form --
661 multiclass avx512_perm_imm<bits<8> opc, string OpcodeStr, RegisterClass RC,
662                          SDNode OpNode, PatFrag mem_frag, 
663                          X86MemOperand x86memop, ValueType OpVT> {
664   def ri : AVX512AIi8<opc, MRMSrcReg, (outs RC:$dst),
665                      (ins RC:$src1, i8imm:$src2),
666                      !strconcat(OpcodeStr,
667                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
668                      [(set RC:$dst,
669                        (OpVT (OpNode RC:$src1, (i8 imm:$src2))))]>,
670                      EVEX;
671   def mi : AVX512AIi8<opc, MRMSrcMem, (outs RC:$dst),
672                      (ins x86memop:$src1, i8imm:$src2),
673                      !strconcat(OpcodeStr,
674                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
675                      [(set RC:$dst,
676                        (OpVT (OpNode (mem_frag addr:$src1),
677                               (i8 imm:$src2))))]>, EVEX;
678 }
679
680 defm VPERMQZ  : avx512_perm_imm<0x00, "vpermq", VR512, X86VPermi, memopv8i64,
681                         i512mem, v8i64>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
682 let ExeDomain = SSEPackedDouble in 
683 defm VPERMPDZ  : avx512_perm_imm<0x01, "vpermpd", VR512, X86VPermi, memopv8f64, 
684                         f512mem, v8f64>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
685
686 // -- VPERM - register form --
687 multiclass avx512_perm<bits<8> opc, string OpcodeStr, RegisterClass RC, 
688                      PatFrag mem_frag, X86MemOperand x86memop, ValueType OpVT> {
689
690   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
691                    (ins RC:$src1, RC:$src2),
692                    !strconcat(OpcodeStr,
693                        " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
694                    [(set RC:$dst,
695                      (OpVT (X86VPermv RC:$src1, RC:$src2)))]>, EVEX_4V;
696
697   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
698                    (ins RC:$src1, x86memop:$src2),
699                    !strconcat(OpcodeStr,
700                        " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
701                    [(set RC:$dst,
702                      (OpVT (X86VPermv RC:$src1, (mem_frag addr:$src2))))]>,
703                      EVEX_4V;
704 }
705
706 defm VPERMDZ   : avx512_perm<0x36, "vpermd",  VR512,  memopv16i32, i512mem,
707                            v16i32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
708 defm VPERMQZ   : avx512_perm<0x36, "vpermq",  VR512,  memopv8i64,  i512mem, 
709                            v8i64>,  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
710 let ExeDomain = SSEPackedSingle in
711 defm VPERMPSZ  : avx512_perm<0x16, "vpermps", VR512,  memopv16f32, f512mem,
712                            v16f32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
713 let ExeDomain = SSEPackedDouble in
714 defm VPERMPDZ  : avx512_perm<0x16, "vpermpd", VR512,  memopv8f64, f512mem, 
715                            v8f64>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
716
717 // -- VPERM2I - 3 source operands form --
718 multiclass avx512_perm_3src<bits<8> opc, string OpcodeStr, RegisterClass RC,
719                           PatFrag mem_frag, X86MemOperand x86memop,
720                           SDNode OpNode, ValueType OpVT, RegisterClass KRC> {
721 let Constraints = "$src1 = $dst" in {
722   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
723                    (ins RC:$src1, RC:$src2, RC:$src3),
724                    !strconcat(OpcodeStr,
725                        " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
726                    [(set RC:$dst,
727                      (OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>,
728                     EVEX_4V;
729
730   def rrk : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
731                    (ins RC:$src1, KRC:$mask, RC:$src2, RC:$src3),
732                    !strconcat(OpcodeStr,
733                        " \t{$src3, $src2, $dst {${mask}}|"
734                        "$dst {${mask}}, $src2, $src3}"),
735                    [(set RC:$dst, (OpVT (vselect KRC:$mask,
736                                            (OpNode RC:$src1, RC:$src2,
737                                               RC:$src3),
738                                            RC:$src1)))]>,
739                     EVEX_4V, EVEX_K;
740
741   let AddedComplexity = 30 in // Prefer over VMOV*rrkz Pat<>
742     def rrkz : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
743                    (ins RC:$src1, KRC:$mask, RC:$src2, RC:$src3),
744                    !strconcat(OpcodeStr,
745                        " \t{$src3, $src2, $dst {${mask}} {z} |",
746                        "$dst {${mask}} {z}, $src2, $src3}"),
747                    [(set RC:$dst, (OpVT (vselect KRC:$mask,
748                                            (OpNode RC:$src1, RC:$src2,
749                                               RC:$src3),
750                                            (OpVT (bitconvert
751                                               (v16i32 immAllZerosV))))))]>,
752                     EVEX_4V, EVEX_KZ;
753
754   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
755                    (ins RC:$src1, RC:$src2, x86memop:$src3),
756                    !strconcat(OpcodeStr,
757                     " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
758                    [(set RC:$dst,
759                      (OpVT (OpNode RC:$src1, RC:$src2,
760                       (mem_frag addr:$src3))))]>, EVEX_4V;
761
762   def rmk : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
763                    (ins RC:$src1, KRC:$mask, RC:$src2, x86memop:$src3),
764                    !strconcat(OpcodeStr,
765                     " \t{$src3, $src2, $dst {${mask}}|"
766                     "$dst {${mask}}, $src2, $src3}"),
767                    [(set RC:$dst,
768                        (OpVT (vselect KRC:$mask,
769                                       (OpNode RC:$src1, RC:$src2,
770                                          (mem_frag addr:$src3)),
771                                       RC:$src1)))]>,
772                     EVEX_4V, EVEX_K;
773
774   let AddedComplexity = 10 in // Prefer over the rrkz variant
775     def rmkz : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
776                    (ins RC:$src1, KRC:$mask, RC:$src2, x86memop:$src3),
777                    !strconcat(OpcodeStr,
778                     " \t{$src3, $src2, $dst {${mask}} {z}|"
779                     "$dst {${mask}} {z}, $src2, $src3}"),
780                    [(set RC:$dst,
781                      (OpVT (vselect KRC:$mask,
782                                     (OpNode RC:$src1, RC:$src2,
783                                             (mem_frag addr:$src3)),
784                                     (OpVT (bitconvert
785                                        (v16i32 immAllZerosV))))))]>,
786                     EVEX_4V, EVEX_KZ;
787   }
788 }
789 defm VPERMI2D  : avx512_perm_3src<0x76, "vpermi2d",  VR512, memopv16i32,
790                                   i512mem, X86VPermiv3, v16i32, VK16WM>,
791                  EVEX_V512, EVEX_CD8<32, CD8VF>;
792 defm VPERMI2Q  : avx512_perm_3src<0x76, "vpermi2q",  VR512, memopv8i64,
793                                   i512mem, X86VPermiv3, v8i64, VK8WM>,
794                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
795 defm VPERMI2PS : avx512_perm_3src<0x77, "vpermi2ps",  VR512, memopv16f32,
796                                   i512mem, X86VPermiv3, v16f32, VK16WM>,
797                  EVEX_V512, EVEX_CD8<32, CD8VF>;
798 defm VPERMI2PD : avx512_perm_3src<0x77, "vpermi2pd",  VR512, memopv8f64,
799                                   i512mem, X86VPermiv3, v8f64, VK8WM>,
800                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
801
802 multiclass avx512_perm_table_3src<bits<8> opc, string Suffix, RegisterClass RC,
803                           PatFrag mem_frag, X86MemOperand x86memop,
804                           SDNode OpNode, ValueType OpVT, RegisterClass KRC,
805                           ValueType MaskVT, RegisterClass MRC> :
806         avx512_perm_3src<opc, "vpermt2"##Suffix, RC, mem_frag, x86memop, OpNode,
807                          OpVT, KRC> {
808   def : Pat<(OpVT (!cast<Intrinsic>("int_x86_avx512_mask_vpermt_"##Suffix##"_512")
809                      VR512:$idx, VR512:$src1, VR512:$src2, -1)),
810             (!cast<Instruction>(NAME#rr) VR512:$src1, VR512:$idx, VR512:$src2)>;
811
812   def : Pat<(OpVT (!cast<Intrinsic>("int_x86_avx512_mask_vpermt_"##Suffix##"_512")
813                      VR512:$idx, VR512:$src1, VR512:$src2, MRC:$mask)),
814             (!cast<Instruction>(NAME#rrk) VR512:$src1,
815               (MaskVT (COPY_TO_REGCLASS MRC:$mask, KRC)), VR512:$idx, VR512:$src2)>;
816 }
817
818 defm VPERMT2D  : avx512_perm_table_3src<0x7E, "d",  VR512, memopv16i32, i512mem,
819                                X86VPermv3, v16i32, VK16WM, v16i1, GR16>,
820                  EVEX_V512, EVEX_CD8<32, CD8VF>;
821 defm VPERMT2Q  : avx512_perm_table_3src<0x7E, "q",  VR512, memopv8i64, i512mem,
822                                X86VPermv3, v8i64, VK8WM, v8i1, GR8>,
823                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
824 defm VPERMT2PS : avx512_perm_table_3src<0x7F, "ps",  VR512, memopv16f32, i512mem,
825                                X86VPermv3, v16f32, VK16WM, v16i1, GR16>,
826                  EVEX_V512, EVEX_CD8<32, CD8VF>;
827 defm VPERMT2PD : avx512_perm_table_3src<0x7F, "pd",  VR512, memopv8f64, i512mem,
828                                X86VPermv3, v8f64, VK8WM, v8i1, GR8>,
829                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
830
831 //===----------------------------------------------------------------------===//
832 // AVX-512 - BLEND using mask
833 //
834 multiclass avx512_blendmask<bits<8> opc, string OpcodeStr,
835                           RegisterClass KRC, RegisterClass RC,
836                           X86MemOperand x86memop, PatFrag mem_frag,
837                           SDNode OpNode, ValueType vt> {
838   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
839              (ins KRC:$mask, RC:$src1, RC:$src2),
840              !strconcat(OpcodeStr,
841              " \t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
842              [(set RC:$dst, (OpNode KRC:$mask, (vt RC:$src2),
843                  (vt RC:$src1)))]>, EVEX_4V, EVEX_K;
844   let mayLoad = 1 in
845   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
846              (ins KRC:$mask, RC:$src1, x86memop:$src2),
847              !strconcat(OpcodeStr,
848              " \t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
849              []>, EVEX_4V, EVEX_K;
850 }
851
852 let ExeDomain = SSEPackedSingle in
853 defm VBLENDMPSZ : avx512_blendmask<0x65, "vblendmps", 
854                               VK16WM, VR512, f512mem,
855                               memopv16f32, vselect, v16f32>, 
856                               EVEX_CD8<32, CD8VF>, EVEX_V512;
857 let ExeDomain = SSEPackedDouble in
858 defm VBLENDMPDZ : avx512_blendmask<0x65, "vblendmpd", 
859                               VK8WM, VR512, f512mem,
860                               memopv8f64, vselect, v8f64>, 
861                               VEX_W, EVEX_CD8<64, CD8VF>, EVEX_V512;
862
863 def : Pat<(v16f32 (int_x86_avx512_mask_blend_ps_512 (v16f32 VR512:$src1),
864                  (v16f32 VR512:$src2), (i16 GR16:$mask))),
865         (VBLENDMPSZrr (COPY_TO_REGCLASS GR16:$mask, VK16WM),
866          VR512:$src1, VR512:$src2)>;
867
868 def : Pat<(v8f64 (int_x86_avx512_mask_blend_pd_512 (v8f64 VR512:$src1),
869                  (v8f64 VR512:$src2), (i8 GR8:$mask))),
870         (VBLENDMPDZrr (COPY_TO_REGCLASS GR8:$mask, VK8WM),
871          VR512:$src1, VR512:$src2)>;
872
873 defm VPBLENDMDZ : avx512_blendmask<0x64, "vpblendmd", 
874                               VK16WM, VR512, f512mem, 
875                               memopv16i32, vselect, v16i32>, 
876                               EVEX_CD8<32, CD8VF>, EVEX_V512;
877
878 defm VPBLENDMQZ : avx512_blendmask<0x64, "vpblendmq", 
879                               VK8WM, VR512, f512mem, 
880                               memopv8i64, vselect, v8i64>, 
881                               VEX_W, EVEX_CD8<64, CD8VF>, EVEX_V512;
882
883 def : Pat<(v16i32 (int_x86_avx512_mask_blend_d_512 (v16i32 VR512:$src1),
884                  (v16i32 VR512:$src2), (i16 GR16:$mask))),
885         (VPBLENDMDZrr (COPY_TO_REGCLASS GR16:$mask, VK16),
886          VR512:$src1, VR512:$src2)>;
887
888 def : Pat<(v8i64 (int_x86_avx512_mask_blend_q_512 (v8i64 VR512:$src1),
889                  (v8i64 VR512:$src2), (i8 GR8:$mask))),
890         (VPBLENDMQZrr (COPY_TO_REGCLASS GR8:$mask, VK8),
891          VR512:$src1, VR512:$src2)>;
892
893 let Predicates = [HasAVX512] in {
894 def : Pat<(v8f32 (vselect (v8i1 VK8WM:$mask), (v8f32 VR256X:$src1),
895                             (v8f32 VR256X:$src2))),
896             (EXTRACT_SUBREG 
897               (v16f32 (VBLENDMPSZrr (COPY_TO_REGCLASS VK8WM:$mask, VK16WM), 
898             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
899             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
900
901 def : Pat<(v8i32 (vselect (v8i1 VK8WM:$mask), (v8i32 VR256X:$src1),
902                             (v8i32 VR256X:$src2))),
903             (EXTRACT_SUBREG 
904                 (v16i32 (VPBLENDMDZrr (COPY_TO_REGCLASS VK8WM:$mask, VK16WM), 
905             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
906             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
907 }
908 //===----------------------------------------------------------------------===//
909 // Compare Instructions
910 //===----------------------------------------------------------------------===//
911
912 // avx512_cmp_scalar - AVX512 CMPSS and CMPSD
913 multiclass avx512_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
914                             Operand CC, SDNode OpNode, ValueType VT,
915                             PatFrag ld_frag, string asm, string asm_alt> {
916   def rr : AVX512Ii8<0xC2, MRMSrcReg,
917                 (outs VK1:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
918                 [(set VK1:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
919                 IIC_SSE_ALU_F32S_RR>, EVEX_4V;
920   def rm : AVX512Ii8<0xC2, MRMSrcMem,
921                 (outs VK1:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
922                 [(set VK1:$dst, (OpNode (VT RC:$src1),
923                 (ld_frag addr:$src2), imm:$cc))], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
924   let isAsmParserOnly = 1, hasSideEffects = 0 in {
925     def rri_alt : AVX512Ii8<0xC2, MRMSrcReg,
926                (outs VK1:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
927                asm_alt, [], IIC_SSE_ALU_F32S_RR>, EVEX_4V;
928     def rmi_alt : AVX512Ii8<0xC2, MRMSrcMem,
929                (outs VK1:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
930                asm_alt, [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
931   }
932 }
933
934 let Predicates = [HasAVX512] in {
935 defm VCMPSSZ : avx512_cmp_scalar<FR32X, f32mem, AVXCC, X86cmpms, f32, loadf32,
936                  "vcmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
937                  "vcmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
938                  XS;
939 defm VCMPSDZ : avx512_cmp_scalar<FR64X, f64mem, AVXCC, X86cmpms, f64, loadf64,
940                  "vcmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
941                  "vcmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
942                  XD, VEX_W;
943 }
944
945 multiclass avx512_icmp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
946               X86VectorVTInfo _> {
947   def rr : AVX512BI<opc, MRMSrcReg,
948              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2),
949              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
950              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2)))],
951              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
952   let mayLoad = 1 in
953   def rm : AVX512BI<opc, MRMSrcMem,
954              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2),
955              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
956              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
957                                      (_.VT (bitconvert (_.LdFrag addr:$src2)))))],
958              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
959   def rrk : AVX512BI<opc, MRMSrcReg,
960               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
961               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
962                           "$dst {${mask}}, $src1, $src2}"),
963               [(set _.KRC:$dst, (and _.KRCWM:$mask,
964                                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))))],
965               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
966   let mayLoad = 1 in
967   def rmk : AVX512BI<opc, MRMSrcMem,
968               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
969               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
970                           "$dst {${mask}}, $src1, $src2}"),
971               [(set _.KRC:$dst, (and _.KRCWM:$mask,
972                                    (OpNode (_.VT _.RC:$src1),
973                                        (_.VT (bitconvert
974                                               (_.LdFrag addr:$src2))))))],
975               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
976 }
977
978 multiclass avx512_icmp_packed_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
979               X86VectorVTInfo _> :
980            avx512_icmp_packed<opc, OpcodeStr, OpNode, _> {
981   let mayLoad = 1 in {
982   def rmb : AVX512BI<opc, MRMSrcMem,
983               (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2),
984               !strconcat(OpcodeStr, "\t{${src2}", _.BroadcastStr, ", $src1, $dst",
985                                     "|$dst, $src1, ${src2}", _.BroadcastStr, "}"),
986               [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
987                               (X86VBroadcast (_.ScalarLdFrag addr:$src2))))],
988               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
989   def rmbk : AVX512BI<opc, MRMSrcMem,
990                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
991                                        _.ScalarMemOp:$src2),
992                !strconcat(OpcodeStr,
993                           "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
994                           "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
995                [(set _.KRC:$dst, (and _.KRCWM:$mask,
996                                       (OpNode (_.VT _.RC:$src1),
997                                         (X86VBroadcast
998                                           (_.ScalarLdFrag addr:$src2)))))],
999                IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1000   }
1001 }
1002
1003 multiclass avx512_icmp_packed_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
1004                                  AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1005   let Predicates = [prd] in
1006   defm Z : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info512>,
1007            EVEX_V512;
1008
1009   let Predicates = [prd, HasVLX] in {
1010     defm Z256 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info256>,
1011                 EVEX_V256;
1012     defm Z128 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info128>,
1013                 EVEX_V128;
1014   }
1015 }
1016
1017 multiclass avx512_icmp_packed_rmb_vl<bits<8> opc, string OpcodeStr,
1018                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo,
1019                                   Predicate prd> {
1020   let Predicates = [prd] in
1021   defm Z : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
1022            EVEX_V512;
1023
1024   let Predicates = [prd, HasVLX] in {
1025     defm Z256 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
1026                 EVEX_V256;
1027     defm Z128 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
1028                 EVEX_V128;
1029   }
1030 }
1031
1032 defm VPCMPEQB : avx512_icmp_packed_vl<0x74, "vpcmpeqb", X86pcmpeqm,
1033                       avx512vl_i8_info, HasBWI>,
1034                 EVEX_CD8<8, CD8VF>;
1035
1036 defm VPCMPEQW : avx512_icmp_packed_vl<0x75, "vpcmpeqw", X86pcmpeqm,
1037                       avx512vl_i16_info, HasBWI>,
1038                 EVEX_CD8<16, CD8VF>;
1039
1040 defm VPCMPEQD : avx512_icmp_packed_rmb_vl<0x76, "vpcmpeqd", X86pcmpeqm,
1041                       avx512vl_i32_info, HasAVX512>,
1042                 EVEX_CD8<32, CD8VF>;
1043
1044 defm VPCMPEQQ : avx512_icmp_packed_rmb_vl<0x29, "vpcmpeqq", X86pcmpeqm,
1045                       avx512vl_i64_info, HasAVX512>,
1046                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1047
1048 defm VPCMPGTB : avx512_icmp_packed_vl<0x64, "vpcmpgtb", X86pcmpgtm,
1049                       avx512vl_i8_info, HasBWI>,
1050                 EVEX_CD8<8, CD8VF>;
1051
1052 defm VPCMPGTW : avx512_icmp_packed_vl<0x65, "vpcmpgtw", X86pcmpgtm,
1053                       avx512vl_i16_info, HasBWI>,
1054                 EVEX_CD8<16, CD8VF>;
1055
1056 defm VPCMPGTD : avx512_icmp_packed_rmb_vl<0x66, "vpcmpgtd", X86pcmpgtm,
1057                       avx512vl_i32_info, HasAVX512>,
1058                 EVEX_CD8<32, CD8VF>;
1059
1060 defm VPCMPGTQ : avx512_icmp_packed_rmb_vl<0x37, "vpcmpgtq", X86pcmpgtm,
1061                       avx512vl_i64_info, HasAVX512>,
1062                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1063
1064 def : Pat<(v8i1 (X86pcmpgtm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1065             (COPY_TO_REGCLASS (VPCMPGTDZrr
1066             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1067             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1068
1069 def : Pat<(v8i1 (X86pcmpeqm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1070             (COPY_TO_REGCLASS (VPCMPEQDZrr
1071             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1072             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1073
1074 multiclass avx512_icmp_cc<bits<8> opc, string Suffix, SDNode OpNode,
1075                           X86VectorVTInfo _> {
1076   def rri : AVX512AIi8<opc, MRMSrcReg,
1077              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1078              !strconcat("vpcmp${cc}", Suffix,
1079                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1080              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1081                                        imm:$cc))],
1082              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1083   let mayLoad = 1 in
1084   def rmi : AVX512AIi8<opc, MRMSrcMem,
1085              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1086              !strconcat("vpcmp${cc}", Suffix,
1087                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1088              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1089                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
1090                               imm:$cc))],
1091              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1092   def rrik : AVX512AIi8<opc, MRMSrcReg,
1093               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1094                                       AVXCC:$cc),
1095               !strconcat("vpcmp${cc}", Suffix,
1096                          "\t{$src2, $src1, $dst {${mask}}|",
1097                          "$dst {${mask}}, $src1, $src2}"),
1098               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1099                                   (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1100                                           imm:$cc)))],
1101               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1102   let mayLoad = 1 in
1103   def rmik : AVX512AIi8<opc, MRMSrcMem,
1104               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1105                                     AVXCC:$cc),
1106               !strconcat("vpcmp${cc}", Suffix,
1107                          "\t{$src2, $src1, $dst {${mask}}|",
1108                          "$dst {${mask}}, $src1, $src2}"),
1109               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1110                                    (OpNode (_.VT _.RC:$src1),
1111                                       (_.VT (bitconvert (_.LdFrag addr:$src2))),
1112                                       imm:$cc)))],
1113               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1114
1115   // Accept explicit immediate argument form instead of comparison code.
1116   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1117     def rri_alt : AVX512AIi8<opc, MRMSrcReg,
1118                (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, i8imm:$cc),
1119                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1120                           "$dst, $src1, $src2, $cc}"),
1121                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1122     def rmi_alt : AVX512AIi8<opc, MRMSrcMem,
1123                (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, i8imm:$cc),
1124                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1125                           "$dst, $src1, $src2, $cc}"),
1126                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1127     def rrik_alt : AVX512AIi8<opc, MRMSrcReg,
1128                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1129                                        i8imm:$cc),
1130                !strconcat("vpcmp", Suffix,
1131                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1132                           "$dst {${mask}}, $src1, $src2, $cc}"),
1133                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1134     def rmik_alt : AVX512AIi8<opc, MRMSrcMem,
1135                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1136                                        i8imm:$cc),
1137                !strconcat("vpcmp", Suffix,
1138                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1139                           "$dst {${mask}}, $src1, $src2, $cc}"),
1140                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1141   }
1142 }
1143
1144 multiclass avx512_icmp_cc_rmb<bits<8> opc, string Suffix, SDNode OpNode,
1145                               X86VectorVTInfo _> :
1146            avx512_icmp_cc<opc, Suffix, OpNode, _> {
1147   let mayLoad = 1 in {
1148   def rmib : AVX512AIi8<opc, MRMSrcMem,
1149              (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1150                                      AVXCC:$cc),
1151              !strconcat("vpcmp${cc}", Suffix,
1152                         "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1153                         "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1154              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1155                                (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1156                                imm:$cc))],
1157              IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1158   def rmibk : AVX512AIi8<opc, MRMSrcMem,
1159               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1160                                        _.ScalarMemOp:$src2, AVXCC:$cc),
1161               !strconcat("vpcmp${cc}", Suffix,
1162                        "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1163                        "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1164               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1165                                   (OpNode (_.VT _.RC:$src1),
1166                                     (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1167                                     imm:$cc)))],
1168               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1169   }
1170
1171   // Accept explicit immediate argument form instead of comparison code.
1172   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1173     def rmib_alt : AVX512AIi8<opc, MRMSrcMem,
1174                (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1175                                        i8imm:$cc),
1176                !strconcat("vpcmp", Suffix,
1177                    "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst|",
1178                    "$dst, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1179                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1180     def rmibk_alt : AVX512AIi8<opc, MRMSrcMem,
1181                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1182                                        _.ScalarMemOp:$src2, i8imm:$cc),
1183                !strconcat("vpcmp", Suffix,
1184                   "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1185                   "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1186                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1187   }
1188 }
1189
1190 multiclass avx512_icmp_cc_vl<bits<8> opc, string Suffix, SDNode OpNode,
1191                              AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1192   let Predicates = [prd] in
1193   defm Z : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info512>, EVEX_V512;
1194
1195   let Predicates = [prd, HasVLX] in {
1196     defm Z256 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info256>, EVEX_V256;
1197     defm Z128 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info128>, EVEX_V128;
1198   }
1199 }
1200
1201 multiclass avx512_icmp_cc_rmb_vl<bits<8> opc, string Suffix, SDNode OpNode,
1202                                 AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1203   let Predicates = [prd] in
1204   defm Z : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info512>,
1205            EVEX_V512;
1206
1207   let Predicates = [prd, HasVLX] in {
1208     defm Z256 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info256>,
1209                 EVEX_V256;
1210     defm Z128 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info128>,
1211                 EVEX_V128;
1212   }
1213 }
1214
1215 defm VPCMPB : avx512_icmp_cc_vl<0x3F, "b", X86cmpm, avx512vl_i8_info,
1216                                 HasBWI>, EVEX_CD8<8, CD8VF>;
1217 defm VPCMPUB : avx512_icmp_cc_vl<0x3E, "ub", X86cmpmu, avx512vl_i8_info,
1218                                  HasBWI>, EVEX_CD8<8, CD8VF>;
1219
1220 defm VPCMPW : avx512_icmp_cc_vl<0x3F, "w", X86cmpm, avx512vl_i16_info,
1221                                 HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1222 defm VPCMPUW : avx512_icmp_cc_vl<0x3E, "uw", X86cmpmu, avx512vl_i16_info,
1223                                  HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1224
1225 defm VPCMPD : avx512_icmp_cc_rmb_vl<0x1F, "d", X86cmpm, avx512vl_i32_info,
1226                                     HasAVX512>, EVEX_CD8<32, CD8VF>;
1227 defm VPCMPUD : avx512_icmp_cc_rmb_vl<0x1E, "ud", X86cmpmu, avx512vl_i32_info,
1228                                      HasAVX512>, EVEX_CD8<32, CD8VF>;
1229
1230 defm VPCMPQ : avx512_icmp_cc_rmb_vl<0x1F, "q", X86cmpm, avx512vl_i64_info,
1231                                     HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1232 defm VPCMPUQ : avx512_icmp_cc_rmb_vl<0x1E, "uq", X86cmpmu, avx512vl_i64_info,
1233                                      HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1234
1235 // avx512_cmp_packed - compare packed instructions
1236 multiclass avx512_cmp_packed<RegisterClass KRC, RegisterClass RC,
1237                            X86MemOperand x86memop, ValueType vt,
1238                            string suffix, Domain d> {
1239   def rri : AVX512PIi8<0xC2, MRMSrcReg,
1240              (outs KRC:$dst), (ins RC:$src1, RC:$src2, AVXCC:$cc),
1241              !strconcat("vcmp${cc}", suffix,
1242                         " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1243              [(set KRC:$dst, (X86cmpm (vt RC:$src1), (vt RC:$src2), imm:$cc))], d>;
1244   def rrib: AVX512PIi8<0xC2, MRMSrcReg,
1245              (outs KRC:$dst), (ins RC:$src1, RC:$src2, AVXCC:$cc),
1246      !strconcat("vcmp${cc}", suffix,
1247                 " \t{{sae}, $src2, $src1, $dst|$dst, $src1, $src2, {sae}}"),
1248                 [], d>, EVEX_B;
1249   def rmi : AVX512PIi8<0xC2, MRMSrcMem,
1250              (outs KRC:$dst), (ins RC:$src1, x86memop:$src2, AVXCC:$cc),
1251               !strconcat("vcmp${cc}", suffix,
1252                          " \t{$src2, $src1, $dst|$dst, $src1, $src2, $cc}"),
1253              [(set KRC:$dst,
1254               (X86cmpm (vt RC:$src1), (memop addr:$src2), imm:$cc))], d>;
1255
1256   // Accept explicit immediate argument form instead of comparison code.
1257   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1258     def rri_alt : AVX512PIi8<0xC2, MRMSrcReg,
1259                (outs KRC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
1260               !strconcat("vcmp", suffix,
1261                         " \t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
1262     def rmi_alt : AVX512PIi8<0xC2, MRMSrcMem,
1263                (outs KRC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
1264               !strconcat("vcmp", suffix,
1265                         " \t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
1266   }
1267 }
1268
1269 defm VCMPPSZ : avx512_cmp_packed<VK16, VR512, f512mem, v16f32,
1270                "ps", SSEPackedSingle>, PS, EVEX_4V, EVEX_V512,
1271                EVEX_CD8<32, CD8VF>;
1272 defm VCMPPDZ : avx512_cmp_packed<VK8, VR512, f512mem, v8f64,
1273                "pd", SSEPackedDouble>, PD, EVEX_4V, VEX_W, EVEX_V512,
1274                EVEX_CD8<64, CD8VF>;
1275
1276 def : Pat<(v8i1 (X86cmpm (v8f32 VR256X:$src1), (v8f32 VR256X:$src2), imm:$cc)),
1277           (COPY_TO_REGCLASS (VCMPPSZrri
1278             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1279             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1280             imm:$cc), VK8)>;
1281 def : Pat<(v8i1 (X86cmpm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1282           (COPY_TO_REGCLASS (VPCMPDZrri
1283             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1284             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1285             imm:$cc), VK8)>;
1286 def : Pat<(v8i1 (X86cmpmu (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1287           (COPY_TO_REGCLASS (VPCMPUDZrri
1288             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1289             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1290             imm:$cc), VK8)>;
1291
1292 def : Pat<(i16 (int_x86_avx512_mask_cmp_ps_512 (v16f32 VR512:$src1),
1293                 (v16f32 VR512:$src2), imm:$cc, (i16 -1),
1294                  FROUND_NO_EXC)),
1295           (COPY_TO_REGCLASS (VCMPPSZrrib VR512:$src1, VR512:$src2,
1296                              (I8Imm imm:$cc)), GR16)>;
1297            
1298 def : Pat<(i8 (int_x86_avx512_mask_cmp_pd_512 (v8f64 VR512:$src1),
1299                 (v8f64 VR512:$src2), imm:$cc, (i8 -1),
1300                  FROUND_NO_EXC)),
1301           (COPY_TO_REGCLASS (VCMPPDZrrib VR512:$src1, VR512:$src2,
1302                              (I8Imm imm:$cc)), GR8)>;
1303
1304 def : Pat<(i16 (int_x86_avx512_mask_cmp_ps_512 (v16f32 VR512:$src1),
1305                 (v16f32 VR512:$src2), imm:$cc, (i16 -1),
1306                 FROUND_CURRENT)),
1307           (COPY_TO_REGCLASS (VCMPPSZrri VR512:$src1, VR512:$src2,
1308                              (I8Imm imm:$cc)), GR16)>;
1309
1310 def : Pat<(i8 (int_x86_avx512_mask_cmp_pd_512 (v8f64 VR512:$src1),
1311                 (v8f64 VR512:$src2), imm:$cc, (i8 -1),
1312                  FROUND_CURRENT)),
1313           (COPY_TO_REGCLASS (VCMPPDZrri VR512:$src1, VR512:$src2,
1314                              (I8Imm imm:$cc)), GR8)>;
1315
1316 // Mask register copy, including
1317 // - copy between mask registers
1318 // - load/store mask registers
1319 // - copy from GPR to mask register and vice versa
1320 //
1321 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
1322                          string OpcodeStr, RegisterClass KRC,
1323                          ValueType vvt, ValueType ivt, X86MemOperand x86memop> {
1324   let hasSideEffects = 0 in {
1325     def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
1326                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1327     let mayLoad = 1 in
1328     def km : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
1329                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
1330                [(set KRC:$dst, (vvt (bitconvert (ivt (load addr:$src)))))]>;
1331     let mayStore = 1 in
1332     def mk : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
1333                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1334   }
1335 }
1336
1337 multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,
1338                              string OpcodeStr,
1339                              RegisterClass KRC, RegisterClass GRC> {
1340   let hasSideEffects = 0 in {
1341     def kr : I<opc_kr, MRMSrcReg, (outs KRC:$dst), (ins GRC:$src),
1342                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1343     def rk : I<opc_rk, MRMSrcReg, (outs GRC:$dst), (ins KRC:$src),
1344                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1345   }
1346 }
1347
1348 let Predicates = [HasDQI] in
1349   defm KMOVB : avx512_mask_mov<0x90, 0x90, 0x91, "kmovb", VK8, v8i1, i8,
1350                                i8mem>,
1351                avx512_mask_mov_gpr<0x92, 0x93, "kmovb", VK8, GR32>,
1352                VEX, PD;
1353
1354 let Predicates = [HasAVX512] in
1355   defm KMOVW : avx512_mask_mov<0x90, 0x90, 0x91, "kmovw", VK16, v16i1, i16,
1356                                i16mem>,
1357                avx512_mask_mov_gpr<0x92, 0x93, "kmovw", VK16, GR32>,
1358                VEX, PS;
1359
1360 let Predicates = [HasBWI] in {
1361   defm KMOVD : avx512_mask_mov<0x90, 0x90, 0x91, "kmovd", VK32, v32i1, i32,
1362                                i32mem>, VEX, PD, VEX_W;
1363   defm KMOVD : avx512_mask_mov_gpr<0x92, 0x93, "kmovd", VK32, GR32>,
1364                VEX, XD;
1365 }
1366
1367 let Predicates = [HasBWI] in {
1368   defm KMOVQ : avx512_mask_mov<0x90, 0x90, 0x91, "kmovq", VK64, v64i1, i64,
1369                                i64mem>, VEX, PS, VEX_W;
1370   defm KMOVQ : avx512_mask_mov_gpr<0x92, 0x93, "kmovq", VK64, GR64>,
1371                VEX, XD, VEX_W;
1372 }
1373
1374 // GR from/to mask register
1375 let Predicates = [HasDQI] in {
1376   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
1377             (KMOVBkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit))>;
1378   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
1379             (EXTRACT_SUBREG (KMOVBrk VK8:$src), sub_8bit)>;
1380 }
1381 let Predicates = [HasAVX512] in {
1382   def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
1383             (KMOVWkr (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit))>;
1384   def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
1385             (EXTRACT_SUBREG (KMOVWrk VK16:$src), sub_16bit)>;
1386 }
1387 let Predicates = [HasBWI] in {
1388   def : Pat<(v32i1 (bitconvert (i32 GR32:$src))), (KMOVDkr GR32:$src)>;
1389   def : Pat<(i32 (bitconvert (v32i1 VK32:$src))), (KMOVDrk VK32:$src)>;
1390 }
1391 let Predicates = [HasBWI] in {
1392   def : Pat<(v64i1 (bitconvert (i64 GR64:$src))), (KMOVQkr GR64:$src)>;
1393   def : Pat<(i64 (bitconvert (v64i1 VK64:$src))), (KMOVQrk VK64:$src)>;
1394 }
1395
1396 // Load/store kreg
1397 let Predicates = [HasDQI] in {
1398   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1399             (KMOVBmk addr:$dst, VK8:$src)>;
1400 }
1401 let Predicates = [HasAVX512] in {
1402   def : Pat<(store (i16 (bitconvert (v16i1 VK16:$src))), addr:$dst),
1403             (KMOVWmk addr:$dst, VK16:$src)>;
1404   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1405             (KMOVWmk addr:$dst, (COPY_TO_REGCLASS VK8:$src, VK16))>;
1406   def : Pat<(i1 (load addr:$src)),
1407             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK1)>;
1408   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
1409             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK8)>;
1410 }
1411 let Predicates = [HasBWI] in {
1412   def : Pat<(store (i32 (bitconvert (v32i1 VK32:$src))), addr:$dst),
1413             (KMOVDmk addr:$dst, VK32:$src)>;
1414 }
1415 let Predicates = [HasBWI] in {
1416   def : Pat<(store (i64 (bitconvert (v64i1 VK64:$src))), addr:$dst),
1417             (KMOVQmk addr:$dst, VK64:$src)>;
1418 }
1419
1420 let Predicates = [HasAVX512] in {
1421   def : Pat<(i1 (trunc (i64 GR64:$src))),
1422             (COPY_TO_REGCLASS (KMOVWkr (AND32ri (EXTRACT_SUBREG $src, sub_32bit),
1423                                         (i32 1))), VK1)>;
1424
1425   def : Pat<(i1 (trunc (i32 GR32:$src))),
1426             (COPY_TO_REGCLASS (KMOVWkr (AND32ri $src, (i32 1))), VK1)>;
1427
1428   def : Pat<(i1 (trunc (i8 GR8:$src))),
1429        (COPY_TO_REGCLASS
1430         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit), (i32 1))),
1431        VK1)>;
1432   def : Pat<(i1 (trunc (i16 GR16:$src))),
1433        (COPY_TO_REGCLASS
1434         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), $src, sub_16bit), (i32 1))),
1435        VK1)>;
1436
1437   def : Pat<(i32 (zext VK1:$src)),
1438             (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1))>;
1439   def : Pat<(i8 (zext VK1:$src)),
1440             (EXTRACT_SUBREG
1441              (AND32ri (KMOVWrk
1442                        (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)), sub_8bit)>;
1443   def : Pat<(i64 (zext VK1:$src)),
1444             (AND64ri8 (SUBREG_TO_REG (i64 0),
1445              (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), sub_32bit), (i64 1))>;
1446   def : Pat<(i16 (zext VK1:$src)),
1447             (EXTRACT_SUBREG
1448              (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)),
1449               sub_16bit)>;
1450   def : Pat<(v16i1 (scalar_to_vector VK1:$src)),
1451             (COPY_TO_REGCLASS VK1:$src, VK16)>;
1452   def : Pat<(v8i1 (scalar_to_vector VK1:$src)),
1453             (COPY_TO_REGCLASS VK1:$src, VK8)>;
1454 }
1455 let Predicates = [HasBWI] in {
1456   def : Pat<(v32i1 (scalar_to_vector VK1:$src)),
1457             (COPY_TO_REGCLASS VK1:$src, VK32)>;
1458   def : Pat<(v64i1 (scalar_to_vector VK1:$src)),
1459             (COPY_TO_REGCLASS VK1:$src, VK64)>;
1460 }
1461
1462
1463 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
1464 let Predicates = [HasAVX512] in {
1465   // GR from/to 8-bit mask without native support
1466   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
1467             (COPY_TO_REGCLASS
1468               (KMOVWkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
1469               VK8)>;
1470   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
1471             (EXTRACT_SUBREG
1472               (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
1473               sub_8bit)>;
1474
1475   def : Pat<(i1 (X86Vextract VK16:$src, (iPTR 0))),
1476             (COPY_TO_REGCLASS VK16:$src, VK1)>;
1477   def : Pat<(i1 (X86Vextract VK8:$src, (iPTR 0))),
1478             (COPY_TO_REGCLASS VK8:$src, VK1)>;
1479 }
1480 let Predicates = [HasBWI] in {
1481   def : Pat<(i1 (X86Vextract VK32:$src, (iPTR 0))),
1482             (COPY_TO_REGCLASS VK32:$src, VK1)>;
1483   def : Pat<(i1 (X86Vextract VK64:$src, (iPTR 0))),
1484             (COPY_TO_REGCLASS VK64:$src, VK1)>;
1485 }
1486
1487 // Mask unary operation
1488 // - KNOT
1489 multiclass avx512_mask_unop<bits<8> opc, string OpcodeStr,
1490                             RegisterClass KRC, SDPatternOperator OpNode,
1491                             Predicate prd> {
1492   let Predicates = [prd] in
1493     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
1494                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
1495                [(set KRC:$dst, (OpNode KRC:$src))]>;
1496 }
1497
1498 multiclass avx512_mask_unop_all<bits<8> opc, string OpcodeStr,
1499                                 SDPatternOperator OpNode> {
1500   defm B : avx512_mask_unop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
1501                             HasDQI>, VEX, PD;
1502   defm W : avx512_mask_unop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
1503                             HasAVX512>, VEX, PS;
1504   defm D : avx512_mask_unop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
1505                             HasBWI>, VEX, PD, VEX_W;
1506   defm Q : avx512_mask_unop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
1507                             HasBWI>, VEX, PS, VEX_W;
1508 }
1509
1510 defm KNOT : avx512_mask_unop_all<0x44, "knot", not>;
1511
1512 multiclass avx512_mask_unop_int<string IntName, string InstName> {
1513   let Predicates = [HasAVX512] in
1514     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
1515                 (i16 GR16:$src)),
1516               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
1517               (v16i1 (COPY_TO_REGCLASS GR16:$src, VK16))), GR16)>;
1518 }
1519 defm : avx512_mask_unop_int<"knot", "KNOT">;
1520
1521 let Predicates = [HasDQI] in
1522 def : Pat<(xor VK8:$src1, (v8i1 immAllOnesV)), (KNOTBrr VK8:$src1)>;
1523 let Predicates = [HasAVX512] in
1524 def : Pat<(xor VK16:$src1, (v16i1 immAllOnesV)), (KNOTWrr VK16:$src1)>;
1525 let Predicates = [HasBWI] in
1526 def : Pat<(xor VK32:$src1, (v32i1 immAllOnesV)), (KNOTDrr VK32:$src1)>;
1527 let Predicates = [HasBWI] in
1528 def : Pat<(xor VK64:$src1, (v64i1 immAllOnesV)), (KNOTQrr VK64:$src1)>;
1529
1530 // KNL does not support KMOVB, 8-bit mask is promoted to 16-bit
1531 let Predicates = [HasAVX512] in {
1532 def : Pat<(xor VK8:$src1,  (v8i1 immAllOnesV)),
1533           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$src1, VK16)), VK8)>;
1534
1535 def : Pat<(not VK8:$src),
1536           (COPY_TO_REGCLASS
1537             (KNOTWrr (COPY_TO_REGCLASS VK8:$src, VK16)), VK8)>;
1538 }
1539
1540 // Mask binary operation
1541 // - KAND, KANDN, KOR, KXNOR, KXOR
1542 multiclass avx512_mask_binop<bits<8> opc, string OpcodeStr,
1543                            RegisterClass KRC, SDPatternOperator OpNode,
1544                            Predicate prd> {
1545   let Predicates = [prd] in
1546     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
1547                !strconcat(OpcodeStr,
1548                           " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1549                [(set KRC:$dst, (OpNode KRC:$src1, KRC:$src2))]>;
1550 }
1551
1552 multiclass avx512_mask_binop_all<bits<8> opc, string OpcodeStr,
1553                                SDPatternOperator OpNode> {
1554   defm B : avx512_mask_binop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
1555                              HasDQI>, VEX_4V, VEX_L, PD;
1556   defm W : avx512_mask_binop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
1557                              HasAVX512>, VEX_4V, VEX_L, PS;
1558   defm D : avx512_mask_binop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
1559                              HasBWI>, VEX_4V, VEX_L, VEX_W, PD;
1560   defm Q : avx512_mask_binop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
1561                              HasBWI>, VEX_4V, VEX_L, VEX_W, PS;
1562 }
1563
1564 def andn : PatFrag<(ops node:$i0, node:$i1), (and (not node:$i0), node:$i1)>;
1565 def xnor : PatFrag<(ops node:$i0, node:$i1), (not (xor node:$i0, node:$i1))>;
1566
1567 let isCommutable = 1 in {
1568   defm KAND  : avx512_mask_binop_all<0x41, "kand",  and>;
1569   defm KOR   : avx512_mask_binop_all<0x45, "kor",   or>;
1570   defm KXNOR : avx512_mask_binop_all<0x46, "kxnor", xnor>;
1571   defm KXOR  : avx512_mask_binop_all<0x47, "kxor",  xor>;
1572 }
1573 let isCommutable = 0 in
1574   defm KANDN : avx512_mask_binop_all<0x42, "kandn", andn>;
1575
1576 def : Pat<(xor VK1:$src1, VK1:$src2),
1577      (COPY_TO_REGCLASS (KXORWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1578                                 (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1579
1580 def : Pat<(or VK1:$src1, VK1:$src2),
1581      (COPY_TO_REGCLASS (KORWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1582                                (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1583
1584 def : Pat<(and VK1:$src1, VK1:$src2),
1585      (COPY_TO_REGCLASS (KANDWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1586                                 (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1587
1588 multiclass avx512_mask_binop_int<string IntName, string InstName> {
1589   let Predicates = [HasAVX512] in
1590     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
1591                 (i16 GR16:$src1), (i16 GR16:$src2)),
1592               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
1593               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
1594               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
1595 }
1596
1597 defm : avx512_mask_binop_int<"kand",  "KAND">;
1598 defm : avx512_mask_binop_int<"kandn", "KANDN">;
1599 defm : avx512_mask_binop_int<"kor",   "KOR">;
1600 defm : avx512_mask_binop_int<"kxnor", "KXNOR">;
1601 defm : avx512_mask_binop_int<"kxor",  "KXOR">;
1602
1603 // With AVX-512, 8-bit mask is promoted to 16-bit mask.
1604 multiclass avx512_binop_pat<SDPatternOperator OpNode, Instruction Inst> {
1605   let Predicates = [HasAVX512] in
1606     def : Pat<(OpNode VK8:$src1, VK8:$src2),
1607               (COPY_TO_REGCLASS
1608                 (Inst (COPY_TO_REGCLASS VK8:$src1, VK16),
1609                       (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
1610 }
1611
1612 defm : avx512_binop_pat<and,  KANDWrr>;
1613 defm : avx512_binop_pat<andn, KANDNWrr>;
1614 defm : avx512_binop_pat<or,   KORWrr>;
1615 defm : avx512_binop_pat<xnor, KXNORWrr>;
1616 defm : avx512_binop_pat<xor,  KXORWrr>;
1617
1618 // Mask unpacking
1619 multiclass avx512_mask_unpck<bits<8> opc, string OpcodeStr,
1620                            RegisterClass KRC> {
1621   let Predicates = [HasAVX512] in
1622     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
1623                !strconcat(OpcodeStr,
1624                           " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
1625 }
1626
1627 multiclass avx512_mask_unpck_bw<bits<8> opc, string OpcodeStr> {
1628   defm BW : avx512_mask_unpck<opc, !strconcat(OpcodeStr, "bw"), VK16>,
1629                             VEX_4V, VEX_L, PD;
1630 }
1631
1632 defm KUNPCK : avx512_mask_unpck_bw<0x4b, "kunpck">;
1633 def : Pat<(v16i1 (concat_vectors (v8i1 VK8:$src1), (v8i1 VK8:$src2))),
1634           (KUNPCKBWrr (COPY_TO_REGCLASS VK8:$src2, VK16),
1635                   (COPY_TO_REGCLASS VK8:$src1, VK16))>;
1636
1637
1638 multiclass avx512_mask_unpck_int<string IntName, string InstName> {
1639   let Predicates = [HasAVX512] in
1640     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_bw")
1641                 (i16 GR16:$src1), (i16 GR16:$src2)),
1642               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"BWrr")
1643               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
1644               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
1645 }
1646 defm : avx512_mask_unpck_int<"kunpck",  "KUNPCK">;
1647
1648 // Mask bit testing
1649 multiclass avx512_mask_testop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
1650                             SDNode OpNode> {
1651   let Predicates = [HasAVX512], Defs = [EFLAGS] in
1652     def rr : I<opc, MRMSrcReg, (outs), (ins KRC:$src1, KRC:$src2),
1653                !strconcat(OpcodeStr, " \t{$src2, $src1|$src1, $src2}"),
1654                [(set EFLAGS, (OpNode KRC:$src1, KRC:$src2))]>;
1655 }
1656
1657 multiclass avx512_mask_testop_w<bits<8> opc, string OpcodeStr, SDNode OpNode> {
1658   defm W : avx512_mask_testop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
1659                             VEX, PS;
1660 }
1661
1662 defm KORTEST : avx512_mask_testop_w<0x98, "kortest", X86kortest>;
1663
1664 def : Pat<(X86cmp VK1:$src1, (i1 0)),
1665           (KORTESTWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1666            (COPY_TO_REGCLASS VK1:$src1, VK16))>;
1667
1668 // Mask shift
1669 multiclass avx512_mask_shiftop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
1670                              SDNode OpNode> {
1671   let Predicates = [HasAVX512] in
1672     def ri : Ii8<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src, i8imm:$imm),
1673                  !strconcat(OpcodeStr,
1674                             " \t{$imm, $src, $dst|$dst, $src, $imm}"),
1675                             [(set KRC:$dst, (OpNode KRC:$src, (i8 imm:$imm)))]>;
1676 }
1677
1678 multiclass avx512_mask_shiftop_w<bits<8> opc1, bits<8> opc2, string OpcodeStr,
1679                                SDNode OpNode> {
1680   defm W : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
1681                              VEX, TAPD, VEX_W;
1682 }
1683
1684 defm KSHIFTL : avx512_mask_shiftop_w<0x32, 0x33, "kshiftl", X86vshli>;
1685 defm KSHIFTR : avx512_mask_shiftop_w<0x30, 0x31, "kshiftr", X86vsrli>;
1686
1687 // Mask setting all 0s or 1s
1688 multiclass avx512_mask_setop<RegisterClass KRC, ValueType VT, PatFrag Val> {
1689   let Predicates = [HasAVX512] in
1690     let isReMaterializable = 1, isAsCheapAsAMove = 1, isPseudo = 1 in
1691       def #NAME# : I<0, Pseudo, (outs KRC:$dst), (ins), "",
1692                      [(set KRC:$dst, (VT Val))]>;
1693 }
1694
1695 multiclass avx512_mask_setop_w<PatFrag Val> {
1696   defm B : avx512_mask_setop<VK8,   v8i1, Val>;
1697   defm W : avx512_mask_setop<VK16, v16i1, Val>;
1698 }
1699
1700 defm KSET0 : avx512_mask_setop_w<immAllZerosV>;
1701 defm KSET1 : avx512_mask_setop_w<immAllOnesV>;
1702
1703 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
1704 let Predicates = [HasAVX512] in {
1705   def : Pat<(v8i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK8)>;
1706   def : Pat<(v8i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK8)>;
1707   def : Pat<(i1 0), (COPY_TO_REGCLASS (KSET0W), VK1)>;
1708   def : Pat<(i1 1), (COPY_TO_REGCLASS (KSET1W), VK1)>;
1709   def : Pat<(i1 -1), (COPY_TO_REGCLASS (KSET1W), VK1)>;
1710 }
1711 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 0))),
1712           (v8i1 (COPY_TO_REGCLASS VK16:$src, VK8))>;
1713
1714 def : Pat<(v16i1 (insert_subvector undef, (v8i1 VK8:$src), (iPTR 0))),
1715           (v16i1 (COPY_TO_REGCLASS VK8:$src, VK16))>;
1716
1717 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 8))),
1718           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri VK16:$src, (i8 8)), VK8))>;
1719
1720 let Predicates = [HasVLX] in {
1721   def : Pat<(v8i1 (insert_subvector undef, (v4i1 VK4:$src), (iPTR 0))),
1722             (v8i1 (COPY_TO_REGCLASS VK4:$src, VK8))>;
1723   def : Pat<(v8i1 (insert_subvector undef, (v2i1 VK2:$src), (iPTR 0))),
1724             (v8i1 (COPY_TO_REGCLASS VK2:$src, VK8))>;
1725   def : Pat<(v4i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
1726             (v4i1 (COPY_TO_REGCLASS VK8:$src, VK4))>;
1727   def : Pat<(v2i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
1728             (v2i1 (COPY_TO_REGCLASS VK8:$src, VK2))>;
1729 }
1730
1731 def : Pat<(v8i1 (X86vshli VK8:$src, (i8 imm:$imm))),
1732           (v8i1 (COPY_TO_REGCLASS (KSHIFTLWri (COPY_TO_REGCLASS VK8:$src, VK16), (I8Imm $imm)), VK8))>;
1733
1734 def : Pat<(v8i1 (X86vsrli VK8:$src, (i8 imm:$imm))),
1735           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri (COPY_TO_REGCLASS VK8:$src, VK16), (I8Imm $imm)), VK8))>;
1736 //===----------------------------------------------------------------------===//
1737 // AVX-512 - Aligned and unaligned load and store
1738 //
1739
1740 multiclass avx512_load<bits<8> opc, string OpcodeStr, PatFrag ld_frag,
1741                        RegisterClass KRC, RegisterClass RC,
1742                        ValueType vt, ValueType zvt, X86MemOperand memop,
1743                        Domain d, bit IsReMaterializable = 1> {
1744 let hasSideEffects = 0 in {
1745   def rr : AVX512PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
1746                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
1747                     d>, EVEX;
1748   def rrkz : AVX512PI<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src),
1749                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
1750                        "${dst} {${mask}} {z}, $src}"), [], d>, EVEX, EVEX_KZ;
1751   }
1752   let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable,
1753       SchedRW = [WriteLoad] in
1754   def rm : AVX512PI<opc, MRMSrcMem, (outs RC:$dst), (ins memop:$src),
1755                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1756                     [(set RC:$dst, (vt (bitconvert (ld_frag addr:$src))))],
1757                     d>, EVEX;
1758
1759   let AddedComplexity = 20 in {
1760   let Constraints = "$src0 = $dst",  hasSideEffects = 0 in {
1761   let hasSideEffects = 0 in
1762     def rrk : AVX512PI<opc, MRMSrcReg, (outs RC:$dst),
1763                      (ins RC:$src0, KRC:$mask, RC:$src1),
1764                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
1765                       "${dst} {${mask}}, $src1}"),
1766                      [(set RC:$dst, (vt (vselect KRC:$mask,
1767                                           (vt RC:$src1),
1768                                           (vt RC:$src0))))],
1769                      d>, EVEX, EVEX_K;
1770   let mayLoad = 1, SchedRW = [WriteLoad] in
1771     def rmk : AVX512PI<opc, MRMSrcMem, (outs RC:$dst),
1772                      (ins RC:$src0, KRC:$mask, memop:$src1),
1773                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
1774                       "${dst} {${mask}}, $src1}"),
1775                      [(set RC:$dst, (vt
1776                          (vselect KRC:$mask,
1777                                  (vt (bitconvert (ld_frag addr:$src1))),
1778                                  (vt RC:$src0))))],
1779                      d>, EVEX, EVEX_K;
1780   }
1781   let mayLoad = 1, SchedRW = [WriteLoad] in
1782     def rmkz : AVX512PI<opc, MRMSrcMem, (outs RC:$dst),
1783                       (ins KRC:$mask, memop:$src),
1784                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
1785                        "${dst} {${mask}} {z}, $src}"),
1786                       [(set RC:$dst, (vt
1787                            (vselect KRC:$mask,
1788                                      (vt (bitconvert (ld_frag addr:$src))),
1789                                      (vt (bitconvert (zvt immAllZerosV))))))],
1790                       d>, EVEX, EVEX_KZ;
1791   }
1792 }
1793
1794 multiclass avx512_load_vl<bits<8> opc, string OpcodeStr, string ld_pat,
1795                           string elty, string elsz, string vsz512,
1796                           string vsz256, string vsz128, Domain d,
1797                           Predicate prd, bit IsReMaterializable = 1> {
1798   let Predicates = [prd] in
1799   defm Z : avx512_load<opc, OpcodeStr,
1800                        !cast<PatFrag>(ld_pat##"v"##vsz512##elty##elsz),
1801                        !cast<RegisterClass>("VK"##vsz512##"WM"), VR512,
1802                        !cast<ValueType>("v"##vsz512##elty##elsz), v16i32,
1803                        !cast<X86MemOperand>(elty##"512mem"), d,
1804                        IsReMaterializable>, EVEX_V512;
1805
1806   let Predicates = [prd, HasVLX] in {
1807     defm Z256 : avx512_load<opc, OpcodeStr,
1808                        !cast<PatFrag>(ld_pat##!if(!eq(elty,"f"),
1809                              "v"##vsz256##elty##elsz, "v4i64")),
1810                        !cast<RegisterClass>("VK"##vsz256##"WM"), VR256X,
1811                        !cast<ValueType>("v"##vsz256##elty##elsz), v8i32,
1812                        !cast<X86MemOperand>(elty##"256mem"), d,
1813                        IsReMaterializable>, EVEX_V256;
1814
1815     defm Z128 : avx512_load<opc, OpcodeStr,
1816                        !cast<PatFrag>(ld_pat##!if(!eq(elty,"f"),
1817                              "v"##vsz128##elty##elsz, "v2i64")),
1818                        !cast<RegisterClass>("VK"##vsz128##"WM"), VR128X,
1819                        !cast<ValueType>("v"##vsz128##elty##elsz), v4i32,
1820                        !cast<X86MemOperand>(elty##"128mem"), d,
1821                        IsReMaterializable>, EVEX_V128;
1822   }
1823 }
1824
1825
1826 multiclass avx512_store<bits<8> opc, string OpcodeStr, PatFrag st_frag,
1827                         ValueType OpVT, RegisterClass KRC, RegisterClass RC,
1828                         X86MemOperand memop, Domain d> {
1829   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1830   def rr_alt : AVX512PI<opc, MRMDestReg, (outs RC:$dst), (ins RC:$src),
1831               !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [], d>,
1832               EVEX;
1833   let Constraints = "$src1 = $dst" in
1834   def rrk_alt : AVX512PI<opc, MRMDestReg, (outs  RC:$dst),
1835                                           (ins RC:$src1, KRC:$mask, RC:$src2),
1836               !strconcat(OpcodeStr,
1837               "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"), [], d>,
1838               EVEX, EVEX_K;
1839   def rrkz_alt : AVX512PI<opc, MRMDestReg, (outs  RC:$dst),
1840                                            (ins KRC:$mask, RC:$src),
1841               !strconcat(OpcodeStr,
1842               "\t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
1843               [], d>, EVEX, EVEX_KZ;
1844   }
1845   let mayStore = 1 in {
1846   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins memop:$dst, RC:$src),
1847                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1848                     [(st_frag (OpVT RC:$src), addr:$dst)], d>, EVEX;
1849   def mrk : AVX512PI<opc, MRMDestMem, (outs),
1850                                       (ins memop:$dst, KRC:$mask, RC:$src),
1851               !strconcat(OpcodeStr,
1852               "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
1853                [], d>, EVEX, EVEX_K;
1854   }
1855 }
1856
1857
1858 multiclass avx512_store_vl<bits<8> opc, string OpcodeStr, string st_pat,
1859                            string st_suff_512, string st_suff_256,
1860                            string st_suff_128, string elty, string elsz,
1861                            string vsz512, string vsz256, string vsz128,
1862                            Domain d, Predicate prd> {
1863   let Predicates = [prd] in
1864   defm Z : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_512),
1865                         !cast<ValueType>("v"##vsz512##elty##elsz),
1866                         !cast<RegisterClass>("VK"##vsz512##"WM"), VR512,
1867                         !cast<X86MemOperand>(elty##"512mem"), d>, EVEX_V512;
1868
1869   let Predicates = [prd, HasVLX] in {
1870     defm Z256 : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_256),
1871                              !cast<ValueType>("v"##vsz256##elty##elsz),
1872                              !cast<RegisterClass>("VK"##vsz256##"WM"), VR256X,
1873                              !cast<X86MemOperand>(elty##"256mem"), d>, EVEX_V256;
1874
1875     defm Z128 : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_128),
1876                              !cast<ValueType>("v"##vsz128##elty##elsz),
1877                              !cast<RegisterClass>("VK"##vsz128##"WM"), VR128X,
1878                              !cast<X86MemOperand>(elty##"128mem"), d>, EVEX_V128;
1879   }
1880 }
1881
1882 defm VMOVAPS : avx512_load_vl<0x28, "vmovaps", "alignedload", "f", "32",
1883                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
1884                avx512_store_vl<0x29, "vmovaps", "alignedstore",
1885                                "512", "256", "", "f", "32", "16", "8", "4",
1886                                SSEPackedSingle, HasAVX512>,
1887                               PS, EVEX_CD8<32, CD8VF>;
1888
1889 defm VMOVAPD : avx512_load_vl<0x28, "vmovapd", "alignedload", "f", "64",
1890                               "8", "4", "2", SSEPackedDouble, HasAVX512>,
1891                avx512_store_vl<0x29, "vmovapd", "alignedstore",
1892                                "512", "256", "", "f", "64", "8", "4", "2",
1893                                SSEPackedDouble, HasAVX512>,
1894                               PD, VEX_W, EVEX_CD8<64, CD8VF>;
1895
1896 defm VMOVUPS : avx512_load_vl<0x10, "vmovups", "load", "f", "32",
1897                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
1898                avx512_store_vl<0x11, "vmovups", "store", "", "", "", "f", "32",
1899                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
1900                               PS, EVEX_CD8<32, CD8VF>;
1901
1902 defm VMOVUPD : avx512_load_vl<0x10, "vmovupd", "load", "f", "64",
1903                               "8", "4", "2", SSEPackedDouble, HasAVX512, 0>,
1904                avx512_store_vl<0x11, "vmovupd", "store", "", "", "", "f", "64",
1905                               "8", "4", "2", SSEPackedDouble, HasAVX512>,
1906                              PD, VEX_W, EVEX_CD8<64, CD8VF>;
1907
1908 def: Pat<(v8f64 (int_x86_avx512_mask_loadu_pd_512 addr:$ptr,
1909                 (bc_v8f64 (v16i32 immAllZerosV)), GR8:$mask)),
1910        (VMOVUPDZrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
1911
1912 def: Pat<(v16f32 (int_x86_avx512_mask_loadu_ps_512 addr:$ptr,
1913                  (bc_v16f32 (v16i32 immAllZerosV)), GR16:$mask)),
1914        (VMOVUPSZrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
1915
1916 def: Pat<(int_x86_avx512_mask_storeu_ps_512 addr:$ptr, (v16f32 VR512:$src),
1917           GR16:$mask),
1918          (VMOVUPSZmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
1919             VR512:$src)>;
1920 def: Pat<(int_x86_avx512_mask_storeu_pd_512 addr:$ptr, (v8f64 VR512:$src),
1921           GR8:$mask),
1922          (VMOVUPDZmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
1923             VR512:$src)>;
1924
1925 defm VMOVDQA32 : avx512_load_vl<0x6F, "vmovdqa32", "alignedload", "i", "32",
1926                                 "16", "8", "4", SSEPackedInt, HasAVX512>,
1927                  avx512_store_vl<0x7F, "vmovdqa32", "alignedstore",
1928                                  "512", "256", "", "i", "32", "16", "8", "4",
1929                                  SSEPackedInt, HasAVX512>,
1930                                 PD, EVEX_CD8<32, CD8VF>;
1931
1932 defm VMOVDQA64 : avx512_load_vl<0x6F, "vmovdqa64", "alignedload", "i", "64",
1933                                 "8", "4", "2", SSEPackedInt, HasAVX512>,
1934                  avx512_store_vl<0x7F, "vmovdqa64", "alignedstore",
1935                                  "512", "256", "", "i", "64", "8", "4", "2",
1936                                  SSEPackedInt, HasAVX512>,
1937                                 PD, VEX_W, EVEX_CD8<64, CD8VF>;
1938
1939 defm VMOVDQU8 : avx512_load_vl<0x6F, "vmovdqu8", "load", "i", "8",
1940                                "64", "32", "16", SSEPackedInt, HasBWI>,
1941                  avx512_store_vl<0x7F, "vmovdqu8", "store", "", "", "",
1942                                  "i", "8", "64", "32", "16", SSEPackedInt,
1943                                  HasBWI>, XD, EVEX_CD8<8, CD8VF>;
1944
1945 defm VMOVDQU16 : avx512_load_vl<0x6F, "vmovdqu16", "load", "i", "16",
1946                                 "32", "16", "8", SSEPackedInt, HasBWI>,
1947                  avx512_store_vl<0x7F, "vmovdqu16", "store", "", "", "",
1948                                  "i", "16", "32", "16", "8", SSEPackedInt,
1949                                  HasBWI>, XD, VEX_W, EVEX_CD8<16, CD8VF>;
1950
1951 defm VMOVDQU32 : avx512_load_vl<0x6F, "vmovdqu32", "load", "i", "32",
1952                                 "16", "8", "4", SSEPackedInt, HasAVX512>,
1953                  avx512_store_vl<0x7F, "vmovdqu32", "store", "", "", "",
1954                                  "i", "32", "16", "8", "4", SSEPackedInt,
1955                                  HasAVX512>, XS, EVEX_CD8<32, CD8VF>;
1956
1957 defm VMOVDQU64 : avx512_load_vl<0x6F, "vmovdqu64", "load", "i", "64",
1958                                 "8", "4", "2", SSEPackedInt, HasAVX512>,
1959                  avx512_store_vl<0x7F, "vmovdqu64", "store", "", "", "",
1960                                  "i", "64", "8", "4", "2", SSEPackedInt,
1961                                  HasAVX512>, XS, VEX_W, EVEX_CD8<64, CD8VF>;
1962
1963 def: Pat<(v16i32 (int_x86_avx512_mask_loadu_d_512 addr:$ptr,
1964                  (v16i32 immAllZerosV), GR16:$mask)),
1965        (VMOVDQU32Zrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
1966
1967 def: Pat<(v8i64 (int_x86_avx512_mask_loadu_q_512 addr:$ptr,
1968                 (bc_v8i64 (v16i32 immAllZerosV)), GR8:$mask)),
1969        (VMOVDQU64Zrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
1970
1971 def: Pat<(int_x86_avx512_mask_storeu_d_512 addr:$ptr, (v16i32 VR512:$src),
1972             GR16:$mask),
1973          (VMOVDQU32Zmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
1974             VR512:$src)>;
1975 def: Pat<(int_x86_avx512_mask_storeu_q_512 addr:$ptr, (v8i64 VR512:$src),
1976             GR8:$mask),
1977          (VMOVDQU64Zmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
1978             VR512:$src)>;
1979
1980 let AddedComplexity = 20 in {
1981 def : Pat<(v8i64 (vselect VK8WM:$mask, (v8i64 VR512:$src),
1982                           (bc_v8i64 (v16i32 immAllZerosV)))),
1983                   (VMOVDQU64Zrrkz VK8WM:$mask, VR512:$src)>;
1984
1985 def : Pat<(v8i64 (vselect VK8WM:$mask, (bc_v8i64 (v16i32 immAllZerosV)),
1986                           (v8i64 VR512:$src))),
1987    (VMOVDQU64Zrrkz (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$mask, VK16)),
1988                                               VK8), VR512:$src)>;
1989
1990 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 VR512:$src),
1991                            (v16i32 immAllZerosV))),
1992                   (VMOVDQU32Zrrkz VK16WM:$mask, VR512:$src)>;
1993
1994 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 immAllZerosV),
1995                            (v16i32 VR512:$src))),
1996                   (VMOVDQU32Zrrkz (KNOTWrr VK16WM:$mask), VR512:$src)>;
1997 }
1998
1999 // Move Int Doubleword to Packed Double Int
2000 //
2001 def VMOVDI2PDIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR32:$src),
2002                       "vmovd\t{$src, $dst|$dst, $src}",
2003                       [(set VR128X:$dst,
2004                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
2005                         EVEX, VEX_LIG;
2006 def VMOVDI2PDIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst), (ins i32mem:$src),
2007                       "vmovd\t{$src, $dst|$dst, $src}",
2008                       [(set VR128X:$dst,
2009                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
2010                         IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2011 def VMOV64toPQIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR64:$src),
2012                       "vmovq\t{$src, $dst|$dst, $src}",
2013                         [(set VR128X:$dst,
2014                           (v2i64 (scalar_to_vector GR64:$src)))],
2015                           IIC_SSE_MOVDQ>, EVEX, VEX_W, VEX_LIG;
2016 let isCodeGenOnly = 1 in {
2017 def VMOV64toSDZrr : AVX512BI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
2018                        "vmovq\t{$src, $dst|$dst, $src}",
2019                        [(set FR64:$dst, (bitconvert GR64:$src))],
2020                        IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2021 def VMOVSDto64Zrr : AVX512BI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
2022                          "vmovq\t{$src, $dst|$dst, $src}",
2023                          [(set GR64:$dst, (bitconvert FR64:$src))],
2024                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2025 }
2026 def VMOVSDto64Zmr : AVX512BI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
2027                          "vmovq\t{$src, $dst|$dst, $src}",
2028                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
2029                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteStore]>,
2030                          EVEX_CD8<64, CD8VT1>;
2031
2032 // Move Int Doubleword to Single Scalar
2033 //
2034 let isCodeGenOnly = 1 in {
2035 def VMOVDI2SSZrr  : AVX512BI<0x6E, MRMSrcReg, (outs FR32X:$dst), (ins GR32:$src),
2036                       "vmovd\t{$src, $dst|$dst, $src}",
2037                       [(set FR32X:$dst, (bitconvert GR32:$src))],
2038                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG;
2039
2040 def VMOVDI2SSZrm  : AVX512BI<0x6E, MRMSrcMem, (outs FR32X:$dst), (ins i32mem:$src),
2041                       "vmovd\t{$src, $dst|$dst, $src}",
2042                       [(set FR32X:$dst, (bitconvert (loadi32 addr:$src)))],
2043                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2044 }
2045
2046 // Move doubleword from xmm register to r/m32
2047 //
2048 def VMOVPDI2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128X:$src),
2049                        "vmovd\t{$src, $dst|$dst, $src}",
2050                        [(set GR32:$dst, (vector_extract (v4i32 VR128X:$src),
2051                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
2052                        EVEX, VEX_LIG;
2053 def VMOVPDI2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2054                        (ins i32mem:$dst, VR128X:$src),
2055                        "vmovd\t{$src, $dst|$dst, $src}",
2056                        [(store (i32 (vector_extract (v4i32 VR128X:$src),
2057                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
2058                        EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2059
2060 // Move quadword from xmm1 register to r/m64
2061 //
2062 def VMOVPQIto64Zrr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128X:$src),
2063                       "vmovq\t{$src, $dst|$dst, $src}",
2064                       [(set GR64:$dst, (extractelt (v2i64 VR128X:$src),
2065                                                    (iPTR 0)))],
2066                       IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_LIG, VEX_W,
2067                       Requires<[HasAVX512, In64BitMode]>;
2068
2069 def VMOVPQIto64Zmr : I<0xD6, MRMDestMem, (outs),
2070                        (ins i64mem:$dst, VR128X:$src),
2071                        "vmovq\t{$src, $dst|$dst, $src}",
2072                        [(store (extractelt (v2i64 VR128X:$src), (iPTR 0)),
2073                                addr:$dst)], IIC_SSE_MOVDQ>,
2074                        EVEX, PD, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>,
2075                        Sched<[WriteStore]>, Requires<[HasAVX512, In64BitMode]>;
2076
2077 // Move Scalar Single to Double Int
2078 //
2079 let isCodeGenOnly = 1 in {
2080 def VMOVSS2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst),
2081                       (ins FR32X:$src),
2082                       "vmovd\t{$src, $dst|$dst, $src}",
2083                       [(set GR32:$dst, (bitconvert FR32X:$src))],
2084                       IIC_SSE_MOVD_ToGP>, EVEX, VEX_LIG;
2085 def VMOVSS2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2086                       (ins i32mem:$dst, FR32X:$src),
2087                       "vmovd\t{$src, $dst|$dst, $src}",
2088                       [(store (i32 (bitconvert FR32X:$src)), addr:$dst)],
2089                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2090 }
2091
2092 // Move Quadword Int to Packed Quadword Int
2093 //
2094 def VMOVQI2PQIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst),
2095                       (ins i64mem:$src),
2096                       "vmovq\t{$src, $dst|$dst, $src}",
2097                       [(set VR128X:$dst,
2098                         (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
2099                       EVEX, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
2100
2101 //===----------------------------------------------------------------------===//
2102 // AVX-512  MOVSS, MOVSD
2103 //===----------------------------------------------------------------------===//
2104
2105 multiclass avx512_move_scalar <string asm, RegisterClass RC, 
2106                               SDNode OpNode, ValueType vt,
2107                               X86MemOperand x86memop, PatFrag mem_pat> {
2108   let hasSideEffects = 0 in {
2109   def rr : SI<0x10, MRMSrcReg, (outs VR128X:$dst), (ins VR128X:$src1, RC:$src2), 
2110               !strconcat(asm, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2111               [(set VR128X:$dst, (vt (OpNode VR128X:$src1,
2112                                       (scalar_to_vector RC:$src2))))],
2113               IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG;
2114   let Constraints = "$src1 = $dst" in
2115   def rrk : SI<0x10, MRMSrcReg, (outs VR128X:$dst),
2116               (ins VR128X:$src1, VK1WM:$mask, RC:$src2, RC:$src3),
2117               !strconcat(asm,
2118                 " \t{$src3, $src2, $dst {${mask}}|$dst {${mask}}, $src2, $src3}"),
2119               [], IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG, EVEX_K;
2120   def rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
2121               !strconcat(asm, " \t{$src, $dst|$dst, $src}"),
2122               [(set RC:$dst, (mem_pat addr:$src))], IIC_SSE_MOV_S_RM>,
2123               EVEX, VEX_LIG;
2124   let mayStore = 1 in {
2125   def mr: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
2126              !strconcat(asm, " \t{$src, $dst|$dst, $src}"),
2127              [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
2128              EVEX, VEX_LIG;
2129   def mrk: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, VK1WM:$mask, RC:$src),
2130              !strconcat(asm, " \t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
2131              [], IIC_SSE_MOV_S_MR>,
2132              EVEX, VEX_LIG, EVEX_K;
2133   } // mayStore
2134   } //hasSideEffects = 0
2135 }
2136
2137 let ExeDomain = SSEPackedSingle in
2138 defm VMOVSSZ : avx512_move_scalar<"movss", FR32X, X86Movss, v4f32, f32mem,
2139                                  loadf32>, XS, EVEX_CD8<32, CD8VT1>;
2140
2141 let ExeDomain = SSEPackedDouble in
2142 defm VMOVSDZ : avx512_move_scalar<"movsd", FR64X, X86Movsd, v2f64, f64mem,
2143                                  loadf64>, XD, VEX_W, EVEX_CD8<64, CD8VT1>;
2144
2145 def : Pat<(f32 (X86select VK1WM:$mask, (f32 FR32X:$src1), (f32 FR32X:$src2))),
2146           (COPY_TO_REGCLASS (VMOVSSZrrk (COPY_TO_REGCLASS FR32X:$src2, VR128X),
2147            VK1WM:$mask, (f32 (IMPLICIT_DEF)), FR32X:$src1), FR32X)>;
2148
2149 def : Pat<(f64 (X86select VK1WM:$mask, (f64 FR64X:$src1), (f64 FR64X:$src2))),
2150           (COPY_TO_REGCLASS (VMOVSDZrrk (COPY_TO_REGCLASS FR64X:$src2, VR128X),
2151            VK1WM:$mask, (f64 (IMPLICIT_DEF)), FR64X:$src1), FR64X)>;
2152
2153 def : Pat<(int_x86_avx512_mask_store_ss addr:$dst, VR128X:$src, GR8:$mask),
2154           (VMOVSSZmrk addr:$dst, (i1 (COPY_TO_REGCLASS GR8:$mask, VK1WM)),
2155            (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2156
2157 // For the disassembler
2158 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
2159   def VMOVSSZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2160                         (ins VR128X:$src1, FR32X:$src2),
2161                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2162                         IIC_SSE_MOV_S_RR>,
2163                         XS, EVEX_4V, VEX_LIG;
2164   def VMOVSDZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2165                         (ins VR128X:$src1, FR64X:$src2),
2166                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2167                         IIC_SSE_MOV_S_RR>,
2168                         XD, EVEX_4V, VEX_LIG, VEX_W;
2169 }
2170
2171 let Predicates = [HasAVX512] in {
2172   let AddedComplexity = 15 in {
2173   // Move scalar to XMM zero-extended, zeroing a VR128X then do a
2174   // MOVS{S,D} to the lower bits.
2175   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32X:$src)))),
2176             (VMOVSSZrr (v4f32 (V_SET0)), FR32X:$src)>;
2177   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128X:$src))),
2178             (VMOVSSZrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2179   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128X:$src))),
2180             (VMOVSSZrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2181   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64X:$src)))),
2182             (VMOVSDZrr (v2f64 (V_SET0)), FR64X:$src)>;
2183
2184   // Move low f32 and clear high bits.
2185   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256X:$src))),
2186             (SUBREG_TO_REG (i32 0),
2187              (VMOVSSZrr (v4f32 (V_SET0)), 
2188               (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm)), sub_xmm)>;
2189   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256X:$src))),
2190             (SUBREG_TO_REG (i32 0),
2191              (VMOVSSZrr (v4i32 (V_SET0)),
2192                        (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm)), sub_xmm)>;
2193   }
2194
2195   let AddedComplexity = 20 in {
2196   // MOVSSrm zeros the high parts of the register; represent this
2197   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2198   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
2199             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2200   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
2201             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2202   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
2203             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2204
2205   // MOVSDrm zeros the high parts of the register; represent this
2206   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2207   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
2208             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2209   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
2210             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2211   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
2212             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2213   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
2214             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2215   def : Pat<(v2f64 (X86vzload addr:$src)),
2216             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2217
2218   // Represent the same patterns above but in the form they appear for
2219   // 256-bit types
2220   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
2221                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
2222             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
2223   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2224                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
2225             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
2226   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2227                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
2228             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
2229   }
2230   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2231                    (v4f32 (scalar_to_vector FR32X:$src)), (iPTR 0)))),
2232             (SUBREG_TO_REG (i32 0), (v4f32 (VMOVSSZrr (v4f32 (V_SET0)),
2233                                             FR32X:$src)), sub_xmm)>;
2234   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2235                    (v2f64 (scalar_to_vector FR64X:$src)), (iPTR 0)))),
2236             (SUBREG_TO_REG (i64 0), (v2f64 (VMOVSDZrr (v2f64 (V_SET0)),
2237                                      FR64X:$src)), sub_xmm)>;
2238   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
2239                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
2240             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
2241
2242   // Move low f64 and clear high bits.
2243   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256X:$src))),
2244             (SUBREG_TO_REG (i32 0),
2245              (VMOVSDZrr (v2f64 (V_SET0)),
2246                        (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm)), sub_xmm)>;
2247
2248   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256X:$src))),
2249             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (V_SET0)),
2250                        (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm)), sub_xmm)>;
2251
2252   // Extract and store.
2253   def : Pat<(store (f32 (vector_extract (v4f32 VR128X:$src), (iPTR 0))),
2254                    addr:$dst),
2255             (VMOVSSZmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128X:$src), FR32X))>;
2256   def : Pat<(store (f64 (vector_extract (v2f64 VR128X:$src), (iPTR 0))),
2257                    addr:$dst),
2258             (VMOVSDZmr addr:$dst, (COPY_TO_REGCLASS (v2f64 VR128X:$src), FR64X))>;
2259
2260   // Shuffle with VMOVSS
2261   def : Pat<(v4i32 (X86Movss VR128X:$src1, VR128X:$src2)),
2262             (VMOVSSZrr (v4i32 VR128X:$src1),
2263                       (COPY_TO_REGCLASS (v4i32 VR128X:$src2), FR32X))>;
2264   def : Pat<(v4f32 (X86Movss VR128X:$src1, VR128X:$src2)),
2265             (VMOVSSZrr (v4f32 VR128X:$src1),
2266                       (COPY_TO_REGCLASS (v4f32 VR128X:$src2), FR32X))>;
2267
2268   // 256-bit variants
2269   def : Pat<(v8i32 (X86Movss VR256X:$src1, VR256X:$src2)),
2270             (SUBREG_TO_REG (i32 0),
2271               (VMOVSSZrr (EXTRACT_SUBREG (v8i32 VR256X:$src1), sub_xmm),
2272                         (EXTRACT_SUBREG (v8i32 VR256X:$src2), sub_xmm)),
2273               sub_xmm)>;
2274   def : Pat<(v8f32 (X86Movss VR256X:$src1, VR256X:$src2)),
2275             (SUBREG_TO_REG (i32 0),
2276               (VMOVSSZrr (EXTRACT_SUBREG (v8f32 VR256X:$src1), sub_xmm),
2277                         (EXTRACT_SUBREG (v8f32 VR256X:$src2), sub_xmm)),
2278               sub_xmm)>;
2279
2280   // Shuffle with VMOVSD
2281   def : Pat<(v2i64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2282             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2283   def : Pat<(v2f64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2284             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2285   def : Pat<(v4f32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2286             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2287   def : Pat<(v4i32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2288             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2289
2290   // 256-bit variants
2291   def : Pat<(v4i64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2292             (SUBREG_TO_REG (i32 0),
2293               (VMOVSDZrr (EXTRACT_SUBREG (v4i64 VR256X:$src1), sub_xmm),
2294                         (EXTRACT_SUBREG (v4i64 VR256X:$src2), sub_xmm)),
2295               sub_xmm)>;
2296   def : Pat<(v4f64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2297             (SUBREG_TO_REG (i32 0),
2298               (VMOVSDZrr (EXTRACT_SUBREG (v4f64 VR256X:$src1), sub_xmm),
2299                         (EXTRACT_SUBREG (v4f64 VR256X:$src2), sub_xmm)),
2300               sub_xmm)>;
2301
2302   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
2303             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2304   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
2305             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2306   def : Pat<(v4f32 (X86Movlps VR128X:$src1, VR128X:$src2)),
2307             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2308   def : Pat<(v4i32 (X86Movlps VR128X:$src1, VR128X:$src2)),
2309             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2310 }
2311
2312 let AddedComplexity = 15 in
2313 def VMOVZPQILo2PQIZrr : AVX512XSI<0x7E, MRMSrcReg, (outs VR128X:$dst),
2314                                 (ins VR128X:$src),
2315                                 "vmovq\t{$src, $dst|$dst, $src}",
2316                                 [(set VR128X:$dst, (v2i64 (X86vzmovl 
2317                                                    (v2i64 VR128X:$src))))],
2318                                 IIC_SSE_MOVQ_RR>, EVEX, VEX_W;
2319
2320 let AddedComplexity = 20 in
2321 def VMOVZPQILo2PQIZrm : AVX512XSI<0x7E, MRMSrcMem, (outs VR128X:$dst),
2322                                  (ins i128mem:$src),
2323                                  "vmovq\t{$src, $dst|$dst, $src}",
2324                                  [(set VR128X:$dst, (v2i64 (X86vzmovl
2325                                                      (loadv2i64 addr:$src))))],
2326                                  IIC_SSE_MOVDQ>, EVEX, VEX_W,
2327                                  EVEX_CD8<8, CD8VT8>;
2328
2329 let Predicates = [HasAVX512] in {
2330   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
2331   let AddedComplexity = 20 in {
2332     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
2333               (VMOVDI2PDIZrm addr:$src)>;
2334     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
2335               (VMOV64toPQIZrr GR64:$src)>;
2336     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
2337               (VMOVDI2PDIZrr GR32:$src)>;
2338               
2339     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
2340               (VMOVDI2PDIZrm addr:$src)>;
2341     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
2342               (VMOVDI2PDIZrm addr:$src)>;
2343     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
2344             (VMOVZPQILo2PQIZrm addr:$src)>;
2345     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128X:$src))),
2346             (VMOVZPQILo2PQIZrr VR128X:$src)>;
2347     def : Pat<(v2i64 (X86vzload addr:$src)),
2348             (VMOVZPQILo2PQIZrm addr:$src)>;
2349   }
2350
2351   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
2352   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
2353                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
2354             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
2355   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
2356                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
2357             (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
2358 }
2359
2360 def : Pat<(v16i32 (X86Vinsert (v16i32 immAllZerosV), GR32:$src2, (iPTR 0))),
2361         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
2362
2363 def : Pat<(v8i64 (X86Vinsert (bc_v8i64 (v16i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
2364         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
2365
2366 def : Pat<(v16i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
2367         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
2368
2369 def : Pat<(v8i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
2370         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
2371
2372 //===----------------------------------------------------------------------===//
2373 // AVX-512 - Non-temporals
2374 //===----------------------------------------------------------------------===//
2375 let SchedRW = [WriteLoad] in {
2376   def VMOVNTDQAZrm : AVX512PI<0x2A, MRMSrcMem, (outs VR512:$dst),
2377                         (ins i512mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}",
2378                         [(set VR512:$dst, (int_x86_avx512_movntdqa addr:$src))],
2379                         SSEPackedInt>, EVEX, T8PD, EVEX_V512,
2380                         EVEX_CD8<64, CD8VF>;
2381
2382   let Predicates = [HasAVX512, HasVLX] in {
2383     def VMOVNTDQAZ256rm : AVX512PI<0x2A, MRMSrcMem, (outs VR256X:$dst),
2384                              (ins i256mem:$src),
2385                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
2386                              SSEPackedInt>, EVEX, T8PD, EVEX_V256,
2387                              EVEX_CD8<64, CD8VF>;
2388
2389     def VMOVNTDQAZ128rm : AVX512PI<0x2A, MRMSrcMem, (outs VR128X:$dst),
2390                              (ins i128mem:$src),
2391                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
2392                              SSEPackedInt>, EVEX, T8PD, EVEX_V128,
2393                              EVEX_CD8<64, CD8VF>;
2394   }
2395 }
2396
2397 multiclass avx512_movnt<bits<8> opc, string OpcodeStr, PatFrag st_frag,
2398                         ValueType OpVT, RegisterClass RC, X86MemOperand memop,
2399                         Domain d, InstrItinClass itin = IIC_SSE_MOVNT> {
2400   let SchedRW = [WriteStore], mayStore = 1,
2401       AddedComplexity = 400 in
2402   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins memop:$dst, RC:$src),
2403                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2404                     [(st_frag (OpVT RC:$src), addr:$dst)], d, itin>, EVEX;
2405 }
2406
2407 multiclass avx512_movnt_vl<bits<8> opc, string OpcodeStr, PatFrag st_frag,
2408                            string elty, string elsz, string vsz512,
2409                            string vsz256, string vsz128, Domain d,
2410                            Predicate prd, InstrItinClass itin = IIC_SSE_MOVNT> {
2411   let Predicates = [prd] in
2412   defm Z : avx512_movnt<opc, OpcodeStr, st_frag,
2413                         !cast<ValueType>("v"##vsz512##elty##elsz), VR512,
2414                         !cast<X86MemOperand>(elty##"512mem"), d, itin>,
2415                         EVEX_V512;
2416
2417   let Predicates = [prd, HasVLX] in {
2418     defm Z256 : avx512_movnt<opc, OpcodeStr, st_frag,
2419                              !cast<ValueType>("v"##vsz256##elty##elsz), VR256X,
2420                              !cast<X86MemOperand>(elty##"256mem"), d, itin>,
2421                              EVEX_V256;
2422
2423     defm Z128 : avx512_movnt<opc, OpcodeStr, st_frag,
2424                              !cast<ValueType>("v"##vsz128##elty##elsz), VR128X,
2425                              !cast<X86MemOperand>(elty##"128mem"), d, itin>,
2426                              EVEX_V128;
2427   }
2428 }
2429
2430 defm VMOVNTDQ : avx512_movnt_vl<0xE7, "vmovntdq", alignednontemporalstore,
2431                                 "i", "64", "8", "4", "2", SSEPackedInt,
2432                                 HasAVX512>, PD, EVEX_CD8<64, CD8VF>;
2433
2434 defm VMOVNTPD : avx512_movnt_vl<0x2B, "vmovntpd", alignednontemporalstore,
2435                                 "f", "64", "8", "4", "2", SSEPackedDouble,
2436                                 HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2437
2438 defm VMOVNTPS : avx512_movnt_vl<0x2B, "vmovntps", alignednontemporalstore,
2439                                 "f", "32", "16", "8", "4", SSEPackedSingle,
2440                                 HasAVX512>, PS, EVEX_CD8<32, CD8VF>;
2441
2442 //===----------------------------------------------------------------------===//
2443 // AVX-512 - Integer arithmetic
2444 //
2445 multiclass avx512_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2446                         ValueType OpVT, RegisterClass KRC,
2447                         RegisterClass RC, PatFrag memop_frag,
2448                         X86MemOperand x86memop, PatFrag scalar_mfrag,
2449                         X86MemOperand x86scalar_mop, string BrdcstStr,
2450                         OpndItins itins, bit IsCommutable = 0> {
2451   let isCommutable = IsCommutable in
2452     def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2453               (ins RC:$src1, RC:$src2),
2454               !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2455               [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1), (OpVT RC:$src2))))],
2456               itins.rr>, EVEX_4V;
2457   let AddedComplexity = 30 in {
2458     let Constraints = "$src0 = $dst" in
2459       def rrk : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2460                  (ins RC:$src0, KRC:$mask, RC:$src1, RC:$src2),
2461                  !strconcat(OpcodeStr,
2462                     " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2463                  [(set RC:$dst, (OpVT (vselect KRC:$mask,
2464                                   (OpNode (OpVT RC:$src1), (OpVT RC:$src2)),
2465                                   RC:$src0)))],
2466                  itins.rr>, EVEX_4V, EVEX_K;
2467     def rrkz : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2468                 (ins KRC:$mask, RC:$src1, RC:$src2),
2469                 !strconcat(OpcodeStr, " \t{$src2, $src1, $dst {${mask}} {z}" ,
2470                     "|$dst {${mask}} {z}, $src1, $src2}"),
2471                 [(set RC:$dst, (OpVT (vselect KRC:$mask,
2472                                   (OpNode (OpVT RC:$src1), (OpVT RC:$src2)),
2473                                   (OpVT immAllZerosV))))],
2474                 itins.rr>, EVEX_4V, EVEX_KZ;
2475   }
2476
2477   let mayLoad = 1 in {
2478     def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2479               (ins RC:$src1, x86memop:$src2),
2480               !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2481               [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1), (memop_frag addr:$src2))))],
2482               itins.rm>, EVEX_4V;
2483     let AddedComplexity = 30 in {
2484     let Constraints = "$src0 = $dst" in
2485       def rmk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2486                  (ins RC:$src0, KRC:$mask, RC:$src1, x86memop:$src2),
2487                  !strconcat(OpcodeStr,
2488                      " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2489                  [(set RC:$dst, (OpVT (vselect KRC:$mask,
2490                                     (OpNode (OpVT RC:$src1), (memop_frag addr:$src2)),
2491                                     RC:$src0)))],
2492                  itins.rm>, EVEX_4V, EVEX_K;
2493     def rmkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2494                 (ins KRC:$mask, RC:$src1, x86memop:$src2),
2495                 !strconcat(OpcodeStr,
2496                     " \t{$src2, $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, $src2}"),
2497                 [(set RC:$dst, (OpVT (vselect KRC:$mask,
2498                                     (OpNode (OpVT RC:$src1), (memop_frag addr:$src2)),
2499                                     (OpVT immAllZerosV))))],
2500                 itins.rm>, EVEX_4V, EVEX_KZ;
2501     }
2502     def rmb : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2503                (ins RC:$src1, x86scalar_mop:$src2),
2504                !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2505                           ", $src1, $dst|$dst, $src1, ${src2}", BrdcstStr, "}"),
2506                [(set RC:$dst, (OpNode RC:$src1,
2507                                (OpVT (X86VBroadcast (scalar_mfrag addr:$src2)))))],
2508                itins.rm>, EVEX_4V, EVEX_B;
2509     let AddedComplexity = 30 in {
2510     let Constraints = "$src0 = $dst" in
2511       def rmbk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2512                   (ins RC:$src0, KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2513                   !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2514                              ", $src1, $dst {${mask}}|$dst {${mask}}, $src1, ${src2}",
2515                              BrdcstStr, "}"),
2516                   [(set RC:$dst, (OpVT (vselect KRC:$mask,
2517                                     (OpNode (OpVT RC:$src1),
2518                                      (OpVT (X86VBroadcast (scalar_mfrag addr:$src2)))),
2519                                     RC:$src0)))],
2520                   itins.rm>, EVEX_4V, EVEX_B, EVEX_K;
2521     def rmbkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2522                  (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2523                  !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2524                             ", $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, ${src2}",
2525                             BrdcstStr, "}"),
2526                  [(set RC:$dst, (OpVT (vselect KRC:$mask,
2527                                     (OpNode (OpVT RC:$src1),
2528                                      (OpVT (X86VBroadcast (scalar_mfrag addr:$src2)))),
2529                                     (OpVT immAllZerosV))))],
2530                  itins.rm>, EVEX_4V, EVEX_B, EVEX_KZ;
2531     }
2532   }
2533 }
2534
2535 multiclass avx512_binop_rm2<bits<8> opc, string OpcodeStr, ValueType DstVT,
2536                             ValueType SrcVT, RegisterClass KRC, RegisterClass RC,
2537                             PatFrag memop_frag, X86MemOperand x86memop,
2538                             PatFrag scalar_mfrag, X86MemOperand x86scalar_mop,
2539                             string BrdcstStr, OpndItins itins, bit IsCommutable = 0> {
2540   let isCommutable = IsCommutable in
2541   {
2542     def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2543        (ins RC:$src1, RC:$src2),
2544        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2545        []>, EVEX_4V;
2546     def rrk : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2547                (ins KRC:$mask, RC:$src1, RC:$src2),
2548                !strconcat(OpcodeStr,
2549                   " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2550                [], itins.rr>, EVEX_4V, EVEX_K;
2551     def rrkz : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2552                 (ins KRC:$mask, RC:$src1, RC:$src2),
2553                 !strconcat(OpcodeStr, " \t{$src2, $src1, $dst {${mask}} {z}" ,
2554                     "|$dst {${mask}} {z}, $src1, $src2}"),
2555                 [], itins.rr>, EVEX_4V, EVEX_KZ;
2556   }
2557   let mayLoad = 1 in {
2558     def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2559               (ins RC:$src1, x86memop:$src2),
2560               !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2561               []>, EVEX_4V;
2562     def rmk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2563                (ins KRC:$mask, RC:$src1, x86memop:$src2),
2564                !strconcat(OpcodeStr,
2565                    " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2566                [], itins.rm>, EVEX_4V, EVEX_K;
2567     def rmkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2568                 (ins KRC:$mask, RC:$src1, x86memop:$src2),
2569                 !strconcat(OpcodeStr,
2570                     " \t{$src2, $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, $src2}"),
2571                 [], itins.rm>, EVEX_4V, EVEX_KZ;
2572     def rmb : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2573                (ins RC:$src1, x86scalar_mop:$src2),
2574                !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2575                           ", $src1, $dst|$dst, $src1, ${src2}", BrdcstStr, "}"),
2576                [], itins.rm>, EVEX_4V, EVEX_B;
2577     def rmbk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2578                 (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2579                 !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2580                            ", $src1, $dst {${mask}}|$dst {${mask}}, $src1, ${src2}",
2581                            BrdcstStr, "}"),
2582                 [], itins.rm>, EVEX_4V, EVEX_B, EVEX_K;
2583     def rmbkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2584                  (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2585                  !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2586                             ", $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, ${src2}",
2587                             BrdcstStr, "}"),
2588                  [], itins.rm>, EVEX_4V, EVEX_B, EVEX_KZ;
2589   }
2590 }
2591
2592 defm VPADDDZ : avx512_binop_rm<0xFE, "vpaddd", add, v16i32, VK16WM, VR512,
2593                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2594                    SSE_INTALU_ITINS_P, 1>, EVEX_V512, EVEX_CD8<32, CD8VF>;
2595
2596 defm VPSUBDZ : avx512_binop_rm<0xFA, "vpsubd", sub, v16i32, VK16WM, VR512,
2597                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2598                    SSE_INTALU_ITINS_P, 0>, EVEX_V512, EVEX_CD8<32, CD8VF>;
2599
2600 defm VPMULLDZ : avx512_binop_rm<0x40, "vpmulld", mul, v16i32, VK16WM, VR512,
2601                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2602                    SSE_INTALU_ITINS_P, 1>, T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2603
2604 defm VPADDQZ : avx512_binop_rm<0xD4, "vpaddq", add, v8i64, VK8WM, VR512,
2605                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2606                    SSE_INTALU_ITINS_P, 1>, EVEX_CD8<64, CD8VF>, EVEX_V512, VEX_W;
2607
2608 defm VPSUBQZ : avx512_binop_rm<0xFB, "vpsubq", sub, v8i64, VK8WM, VR512,
2609                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2610                    SSE_INTALU_ITINS_P, 0>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2611
2612 defm VPMULDQZ : avx512_binop_rm2<0x28, "vpmuldq", v8i64, v16i32, VK8WM, VR512,
2613                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2614                    SSE_INTALU_ITINS_P, 1>, T8PD, EVEX_V512,
2615                    EVEX_CD8<64, CD8VF>, VEX_W;
2616
2617 defm VPMULUDQZ : avx512_binop_rm2<0xF4, "vpmuludq", v8i64, v16i32, VK8WM, VR512,
2618                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2619                    SSE_INTMUL_ITINS_P, 1>, EVEX_V512, EVEX_CD8<64, CD8VF>, VEX_W;
2620
2621 def : Pat<(v8i64 (X86pmuludq (v16i32 VR512:$src1), (v16i32 VR512:$src2))),
2622           (VPMULUDQZrr VR512:$src1, VR512:$src2)>;
2623
2624 def : Pat<(v8i64 (int_x86_avx512_mask_pmulu_dq_512 (v16i32 VR512:$src1),
2625            (v16i32 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2626           (VPMULUDQZrr VR512:$src1, VR512:$src2)>;
2627 def : Pat<(v8i64 (int_x86_avx512_mask_pmul_dq_512 (v16i32 VR512:$src1),
2628            (v16i32 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2629           (VPMULDQZrr VR512:$src1, VR512:$src2)>;
2630
2631 defm VPMAXUDZ : avx512_binop_rm<0x3F, "vpmaxud", X86umax, v16i32, VK16WM, VR512,
2632                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2633                    SSE_INTALU_ITINS_P, 1>,
2634                    T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2635 defm VPMAXUQZ : avx512_binop_rm<0x3F, "vpmaxuq", X86umax, v8i64, VK8WM, VR512,
2636                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2637                    SSE_INTALU_ITINS_P, 0>,
2638                    T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2639
2640 defm VPMAXSDZ : avx512_binop_rm<0x3D, "vpmaxsd", X86smax, v16i32, VK16WM, VR512,
2641                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2642                    SSE_INTALU_ITINS_P, 1>,
2643                    T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2644 defm VPMAXSQZ : avx512_binop_rm<0x3D, "vpmaxsq", X86smax, v8i64, VK8WM, VR512,
2645                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2646                    SSE_INTALU_ITINS_P, 0>,
2647                    T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2648
2649 defm VPMINUDZ : avx512_binop_rm<0x3B, "vpminud", X86umin, v16i32, VK16WM, VR512,
2650                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2651                    SSE_INTALU_ITINS_P, 1>,
2652                    T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2653 defm VPMINUQZ : avx512_binop_rm<0x3B, "vpminuq", X86umin, v8i64, VK8WM, VR512,
2654                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2655                    SSE_INTALU_ITINS_P, 0>,
2656                    T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2657
2658 defm VPMINSDZ : avx512_binop_rm<0x39, "vpminsd", X86smin, v16i32, VK16WM, VR512,
2659                    memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2660                    SSE_INTALU_ITINS_P, 1>,
2661                    T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2662 defm VPMINSQZ : avx512_binop_rm<0x39, "vpminsq", X86smin, v8i64, VK8WM, VR512,
2663                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2664                    SSE_INTALU_ITINS_P, 0>,
2665                    T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2666
2667 def : Pat <(v16i32 (int_x86_avx512_mask_pmaxs_d_512 (v16i32 VR512:$src1),
2668                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2669            (VPMAXSDZrr VR512:$src1, VR512:$src2)>;
2670 def : Pat <(v16i32 (int_x86_avx512_mask_pmaxu_d_512 (v16i32 VR512:$src1),
2671                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2672            (VPMAXUDZrr VR512:$src1, VR512:$src2)>;
2673 def : Pat <(v8i64 (int_x86_avx512_mask_pmaxs_q_512 (v8i64 VR512:$src1),
2674                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2675            (VPMAXSQZrr VR512:$src1, VR512:$src2)>;
2676 def : Pat <(v8i64 (int_x86_avx512_mask_pmaxu_q_512 (v8i64 VR512:$src1),
2677                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2678            (VPMAXUQZrr VR512:$src1, VR512:$src2)>;
2679 def : Pat <(v16i32 (int_x86_avx512_mask_pmins_d_512 (v16i32 VR512:$src1),
2680                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2681            (VPMINSDZrr VR512:$src1, VR512:$src2)>;
2682 def : Pat <(v16i32 (int_x86_avx512_mask_pminu_d_512 (v16i32 VR512:$src1),
2683                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2684            (VPMINUDZrr VR512:$src1, VR512:$src2)>;
2685 def : Pat <(v8i64 (int_x86_avx512_mask_pmins_q_512 (v8i64 VR512:$src1),
2686                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2687            (VPMINSQZrr VR512:$src1, VR512:$src2)>;
2688 def : Pat <(v8i64 (int_x86_avx512_mask_pminu_q_512 (v8i64 VR512:$src1),
2689                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2690            (VPMINUQZrr VR512:$src1, VR512:$src2)>;
2691 //===----------------------------------------------------------------------===//
2692 // AVX-512 - Unpack Instructions
2693 //===----------------------------------------------------------------------===//
2694
2695 multiclass avx512_unpack_fp<bits<8> opc, SDNode OpNode, ValueType vt,
2696                                    PatFrag mem_frag, RegisterClass RC,
2697                                    X86MemOperand x86memop, string asm,
2698                                    Domain d> {
2699     def rr : AVX512PI<opc, MRMSrcReg,
2700                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2701                 asm, [(set RC:$dst,
2702                            (vt (OpNode RC:$src1, RC:$src2)))],
2703                            d>, EVEX_4V;
2704     def rm : AVX512PI<opc, MRMSrcMem,
2705                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2706                 asm, [(set RC:$dst,
2707                        (vt (OpNode RC:$src1,
2708                             (bitconvert (mem_frag addr:$src2)))))],
2709                         d>, EVEX_4V;
2710 }
2711
2712 defm VUNPCKHPSZ: avx512_unpack_fp<0x15, X86Unpckh, v16f32, memopv8f64,
2713       VR512, f512mem, "vunpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2714       SSEPackedSingle>, PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
2715 defm VUNPCKHPDZ: avx512_unpack_fp<0x15, X86Unpckh, v8f64, memopv8f64,
2716       VR512, f512mem, "vunpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2717       SSEPackedDouble>, PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2718 defm VUNPCKLPSZ: avx512_unpack_fp<0x14, X86Unpckl, v16f32, memopv8f64,
2719       VR512, f512mem, "vunpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2720       SSEPackedSingle>, PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
2721 defm VUNPCKLPDZ: avx512_unpack_fp<0x14, X86Unpckl, v8f64, memopv8f64,
2722       VR512, f512mem, "vunpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2723       SSEPackedDouble>, PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2724
2725 multiclass avx512_unpack_int<bits<8> opc, string OpcodeStr, SDNode OpNode,
2726                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2727                         X86MemOperand x86memop> {
2728   def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2729        (ins RC:$src1, RC:$src2),
2730        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2731        [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1), (OpVT RC:$src2))))], 
2732        IIC_SSE_UNPCK>, EVEX_4V;
2733   def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2734        (ins RC:$src1, x86memop:$src2),
2735        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2736        [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1),
2737                                      (bitconvert (memop_frag addr:$src2)))))],
2738                                      IIC_SSE_UNPCK>, EVEX_4V;
2739 }
2740 defm VPUNPCKLDQZ  : avx512_unpack_int<0x62, "vpunpckldq", X86Unpckl, v16i32,
2741                                 VR512, memopv16i32, i512mem>, EVEX_V512,
2742                                 EVEX_CD8<32, CD8VF>;
2743 defm VPUNPCKLQDQZ : avx512_unpack_int<0x6C, "vpunpcklqdq", X86Unpckl, v8i64,
2744                                 VR512, memopv8i64, i512mem>, EVEX_V512,
2745                                 VEX_W, EVEX_CD8<64, CD8VF>;
2746 defm VPUNPCKHDQZ  : avx512_unpack_int<0x6A, "vpunpckhdq", X86Unpckh, v16i32,
2747                                 VR512, memopv16i32, i512mem>, EVEX_V512,
2748                                 EVEX_CD8<32, CD8VF>;
2749 defm VPUNPCKHQDQZ : avx512_unpack_int<0x6D, "vpunpckhqdq", X86Unpckh, v8i64,
2750                                 VR512, memopv8i64, i512mem>, EVEX_V512,
2751                                 VEX_W, EVEX_CD8<64, CD8VF>;
2752 //===----------------------------------------------------------------------===//
2753 // AVX-512 - PSHUFD
2754 //
2755
2756 multiclass avx512_pshuf_imm<bits<8> opc, string OpcodeStr, RegisterClass RC,
2757                          SDNode OpNode, PatFrag mem_frag, 
2758                          X86MemOperand x86memop, ValueType OpVT> {
2759   def ri : AVX512Ii8<opc, MRMSrcReg, (outs RC:$dst),
2760                      (ins RC:$src1, i8imm:$src2),
2761                      !strconcat(OpcodeStr,
2762                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2763                      [(set RC:$dst,
2764                        (OpVT (OpNode RC:$src1, (i8 imm:$src2))))]>,
2765                      EVEX;
2766   def mi : AVX512Ii8<opc, MRMSrcMem, (outs RC:$dst),
2767                      (ins x86memop:$src1, i8imm:$src2),
2768                      !strconcat(OpcodeStr,
2769                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2770                      [(set RC:$dst,
2771                        (OpVT (OpNode (mem_frag addr:$src1),
2772                               (i8 imm:$src2))))]>, EVEX;
2773 }
2774
2775 defm VPSHUFDZ : avx512_pshuf_imm<0x70, "vpshufd", VR512, X86PShufd, memopv16i32,
2776                       i512mem, v16i32>, PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2777
2778 let ExeDomain = SSEPackedSingle in
2779 defm VPERMILPSZ : avx512_pshuf_imm<0x04, "vpermilps", VR512, X86VPermilpi,
2780                       memopv16f32, i512mem, v16f32>, TAPD, EVEX_V512,
2781                       EVEX_CD8<32, CD8VF>;
2782 let ExeDomain = SSEPackedDouble in
2783 defm VPERMILPDZ : avx512_pshuf_imm<0x05, "vpermilpd", VR512, X86VPermilpi,
2784                       memopv8f64, i512mem, v8f64>, TAPD, EVEX_V512,
2785                       VEX_W, EVEX_CD8<32, CD8VF>;
2786
2787 def : Pat<(v16i32 (X86VPermilpi VR512:$src1, (i8 imm:$imm))),
2788           (VPERMILPSZri VR512:$src1, imm:$imm)>;
2789 def : Pat<(v8i64 (X86VPermilpi VR512:$src1, (i8 imm:$imm))),
2790           (VPERMILPDZri VR512:$src1, imm:$imm)>;
2791
2792 //===----------------------------------------------------------------------===//
2793 // AVX-512  Logical Instructions
2794 //===----------------------------------------------------------------------===//
2795
2796 defm VPANDDZ : avx512_binop_rm<0xDB, "vpandd", and, v16i32, VK16WM, VR512, memopv16i32,
2797                       i512mem, loadi32, i32mem, "{1to16}", SSE_BIT_ITINS_P, 1>,
2798                       EVEX_V512, EVEX_CD8<32, CD8VF>;
2799 defm VPANDQZ : avx512_binop_rm<0xDB, "vpandq", and, v8i64, VK8WM, VR512, memopv8i64,
2800                       i512mem, loadi64, i64mem, "{1to8}", SSE_BIT_ITINS_P, 1>,
2801                       EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2802 defm VPORDZ  : avx512_binop_rm<0xEB, "vpord", or, v16i32, VK16WM, VR512, memopv16i32,
2803                       i512mem, loadi32, i32mem, "{1to16}", SSE_BIT_ITINS_P, 1>,
2804                       EVEX_V512, EVEX_CD8<32, CD8VF>;
2805 defm VPORQZ  : avx512_binop_rm<0xEB, "vporq", or, v8i64, VK8WM, VR512, memopv8i64,
2806                       i512mem, loadi64, i64mem, "{1to8}", SSE_BIT_ITINS_P, 1>,
2807                       EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2808 defm VPXORDZ : avx512_binop_rm<0xEF, "vpxord", xor, v16i32, VK16WM, VR512, memopv16i32,
2809                       i512mem, loadi32, i32mem, "{1to16}", SSE_BIT_ITINS_P, 1>,
2810                       EVEX_V512, EVEX_CD8<32, CD8VF>;
2811 defm VPXORQZ : avx512_binop_rm<0xEF, "vpxorq", xor, v8i64, VK8WM, VR512, memopv8i64,
2812                       i512mem, loadi64, i64mem, "{1to8}", SSE_BIT_ITINS_P, 1>,
2813                       EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2814 defm VPANDNDZ : avx512_binop_rm<0xDF, "vpandnd", X86andnp, v16i32, VK16WM, VR512,
2815                       memopv16i32, i512mem, loadi32, i32mem, "{1to16}",
2816                       SSE_BIT_ITINS_P, 0>, EVEX_V512, EVEX_CD8<32, CD8VF>;
2817 defm VPANDNQZ : avx512_binop_rm<0xDF, "vpandnq", X86andnp, v8i64, VK8WM, VR512,
2818                       memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2819                       SSE_BIT_ITINS_P, 0>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2820
2821 //===----------------------------------------------------------------------===//
2822 // AVX-512  FP arithmetic
2823 //===----------------------------------------------------------------------===//
2824
2825 multiclass avx512_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2826                                   SizeItins itins> {
2827   defm SSZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"), OpNode, FR32X,
2828                              f32mem, itins.s, 0>, XS, EVEX_4V, VEX_LIG,
2829                              EVEX_CD8<32, CD8VT1>;
2830   defm SDZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"), OpNode, FR64X,
2831                              f64mem, itins.d, 0>, XD, VEX_W, EVEX_4V, VEX_LIG,
2832                              EVEX_CD8<64, CD8VT1>;
2833 }
2834
2835 let isCommutable = 1 in {
2836 defm VADD : avx512_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>;
2837 defm VMUL : avx512_binop_s<0x59, "mul", fmul, SSE_ALU_ITINS_S>;
2838 defm VMIN : avx512_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>;
2839 defm VMAX : avx512_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>;
2840 }
2841 let isCommutable = 0 in {
2842 defm VSUB : avx512_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>;
2843 defm VDIV : avx512_binop_s<0x5E, "div", fdiv, SSE_ALU_ITINS_S>;
2844 }
2845
2846 multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
2847                            RegisterClass KRC,
2848                            RegisterClass RC, ValueType vt,
2849                            X86MemOperand x86memop, PatFrag mem_frag,
2850                            X86MemOperand x86scalar_mop, PatFrag scalar_mfrag,
2851                            string BrdcstStr,
2852                            Domain d, OpndItins itins, bit commutable> {
2853   let isCommutable = commutable in {
2854     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2855        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2856        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
2857        EVEX_4V;
2858
2859     def rrk: PI<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src1, RC:$src2),
2860        !strconcat(OpcodeStr,
2861            " \t{$src2, $src1, $dst {${mask}} |$dst {${mask}}, $src1, $src2}"),
2862        [], itins.rr, d>, EVEX_4V, EVEX_K;
2863
2864     def rrkz: PI<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src1, RC:$src2),
2865        !strconcat(OpcodeStr,
2866            " \t{$src2, $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, $src2}"),
2867        [], itins.rr, d>, EVEX_4V, EVEX_KZ;
2868   }
2869
2870   let mayLoad = 1 in {
2871     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2872        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2873        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
2874           itins.rm, d>, EVEX_4V;
2875
2876     def rmb : PI<opc, MRMSrcMem, (outs RC:$dst),
2877        (ins RC:$src1, x86scalar_mop:$src2),
2878        !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2879            ", $src1, $dst|$dst, $src1, ${src2}", BrdcstStr, "}"),
2880        [(set RC:$dst, (OpNode RC:$src1, 
2881                        (vt (X86VBroadcast (scalar_mfrag addr:$src2)))))],
2882        itins.rm, d>, EVEX_4V, EVEX_B;
2883
2884     def rmk : PI<opc, MRMSrcMem, (outs RC:$dst),
2885        (ins KRC:$mask, RC:$src1, x86memop:$src2), !strconcat(OpcodeStr,
2886            "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2887        [], itins.rm, d>, EVEX_4V, EVEX_K;
2888
2889     def rmkz : PI<opc, MRMSrcMem, (outs RC:$dst),
2890        (ins KRC:$mask, RC:$src1, x86memop:$src2), !strconcat(OpcodeStr,
2891            "\t{$src2, $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, $src2}"),
2892        [], itins.rm, d>, EVEX_4V, EVEX_KZ;
2893
2894     def rmbk : PI<opc, MRMSrcMem, (outs RC:$dst),
2895        (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2), !strconcat(OpcodeStr,
2896            " \t{${src2}", BrdcstStr,
2897            ", $src1, $dst {${mask}}|$dst {${mask}}, $src1, ${src2}", BrdcstStr, "}"),
2898        [], itins.rm, d>, EVEX_4V, EVEX_B, EVEX_K;
2899
2900     def rmbkz : PI<opc, MRMSrcMem, (outs RC:$dst),
2901        (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2), !strconcat(OpcodeStr,
2902            " \t{${src2}", BrdcstStr,
2903            ", $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, ${src2}",
2904            BrdcstStr, "}"),
2905        [], itins.rm, d>, EVEX_4V, EVEX_B, EVEX_KZ;
2906   }
2907 }
2908
2909 defm VADDPSZ : avx512_fp_packed<0x58, "addps", fadd, VK16WM, VR512, v16f32, f512mem,
2910                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle, 
2911                    SSE_ALU_ITINS_P.s, 1>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2912                    
2913 defm VADDPDZ : avx512_fp_packed<0x58, "addpd", fadd, VK8WM, VR512, v8f64, f512mem,
2914                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2915                    SSE_ALU_ITINS_P.d, 1>,
2916                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2917
2918 defm VMULPSZ : avx512_fp_packed<0x59, "mulps", fmul, VK16WM, VR512, v16f32, f512mem,
2919                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle,
2920                    SSE_ALU_ITINS_P.s, 1>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2921 defm VMULPDZ : avx512_fp_packed<0x59, "mulpd", fmul, VK8WM, VR512, v8f64, f512mem,
2922                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2923                    SSE_ALU_ITINS_P.d, 1>,
2924                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2925
2926 defm VMINPSZ : avx512_fp_packed<0x5D, "minps", X86fmin, VK16WM, VR512, v16f32, f512mem,
2927                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle,
2928                    SSE_ALU_ITINS_P.s, 1>,
2929                    EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2930 defm VMAXPSZ : avx512_fp_packed<0x5F, "maxps", X86fmax, VK16WM, VR512, v16f32, f512mem,
2931                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle,
2932                    SSE_ALU_ITINS_P.s, 1>,
2933                    EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2934
2935 defm VMINPDZ : avx512_fp_packed<0x5D, "minpd", X86fmin, VK8WM, VR512, v8f64, f512mem,
2936                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2937                    SSE_ALU_ITINS_P.d, 1>,
2938                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2939 defm VMAXPDZ : avx512_fp_packed<0x5F, "maxpd", X86fmax, VK8WM, VR512, v8f64, f512mem,
2940                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2941                    SSE_ALU_ITINS_P.d, 1>,
2942                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2943
2944 defm VSUBPSZ : avx512_fp_packed<0x5C, "subps", fsub, VK16WM, VR512, v16f32, f512mem,
2945                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle,
2946                    SSE_ALU_ITINS_P.s, 0>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2947 defm VDIVPSZ : avx512_fp_packed<0x5E, "divps", fdiv, VK16WM, VR512, v16f32, f512mem,
2948                    memopv16f32, f32mem, loadf32, "{1to16}", SSEPackedSingle,
2949                    SSE_ALU_ITINS_P.s, 0>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
2950
2951 defm VSUBPDZ : avx512_fp_packed<0x5C, "subpd", fsub, VK8WM, VR512, v8f64, f512mem,
2952                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2953                    SSE_ALU_ITINS_P.d, 0>, 
2954                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2955 defm VDIVPDZ : avx512_fp_packed<0x5E, "divpd", fdiv, VK8WM, VR512, v8f64, f512mem,
2956                    memopv8f64, f64mem, loadf64, "{1to8}", SSEPackedDouble,
2957                    SSE_ALU_ITINS_P.d, 0>, 
2958                    EVEX_V512, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2959
2960 def : Pat<(v16f32 (int_x86_avx512_mask_max_ps_512 (v16f32 VR512:$src1),
2961                    (v16f32 VR512:$src2), (bc_v16f32 (v16i32 immAllZerosV)),
2962                    (i16 -1), FROUND_CURRENT)),
2963           (VMAXPSZrr VR512:$src1, VR512:$src2)>;
2964
2965 def : Pat<(v8f64 (int_x86_avx512_mask_max_pd_512 (v8f64 VR512:$src1),
2966                    (v8f64 VR512:$src2), (bc_v8f64 (v16i32 immAllZerosV)),
2967                    (i8 -1), FROUND_CURRENT)),
2968           (VMAXPDZrr VR512:$src1, VR512:$src2)>;
2969
2970 def : Pat<(v16f32 (int_x86_avx512_mask_min_ps_512 (v16f32 VR512:$src1),
2971                    (v16f32 VR512:$src2), (bc_v16f32 (v16i32 immAllZerosV)),
2972                    (i16 -1), FROUND_CURRENT)),
2973           (VMINPSZrr VR512:$src1, VR512:$src2)>;
2974
2975 def : Pat<(v8f64 (int_x86_avx512_mask_min_pd_512 (v8f64 VR512:$src1),
2976                    (v8f64 VR512:$src2), (bc_v8f64 (v16i32 immAllZerosV)),
2977                    (i8 -1), FROUND_CURRENT)),
2978           (VMINPDZrr VR512:$src1, VR512:$src2)>;
2979 //===----------------------------------------------------------------------===//
2980 // AVX-512  VPTESTM instructions
2981 //===----------------------------------------------------------------------===//
2982
2983 multiclass avx512_vptest<bits<8> opc, string OpcodeStr, RegisterClass KRC, 
2984               RegisterClass RC, X86MemOperand x86memop, PatFrag memop_frag, 
2985               SDNode OpNode, ValueType vt> {
2986   def rr : AVX512PI<opc, MRMSrcReg,
2987              (outs KRC:$dst), (ins RC:$src1, RC:$src2), 
2988              !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2989              [(set KRC:$dst, (OpNode (vt RC:$src1), (vt RC:$src2)))],
2990              SSEPackedInt>, EVEX_4V;
2991   def rm : AVX512PI<opc, MRMSrcMem,
2992              (outs KRC:$dst), (ins RC:$src1, x86memop:$src2), 
2993              !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2994              [(set KRC:$dst, (OpNode (vt RC:$src1), 
2995               (bitconvert (memop_frag addr:$src2))))], SSEPackedInt>, EVEX_4V;
2996 }
2997
2998 defm VPTESTMDZ  : avx512_vptest<0x27, "vptestmd", VK16, VR512,  f512mem,
2999                               memopv16i32, X86testm, v16i32>, T8PD, EVEX_V512,
3000                               EVEX_CD8<32, CD8VF>;
3001 defm VPTESTMQZ  : avx512_vptest<0x27, "vptestmq", VK8, VR512,  f512mem,
3002                               memopv8i64, X86testm, v8i64>, T8PD, EVEX_V512, VEX_W,
3003                               EVEX_CD8<64, CD8VF>;
3004
3005 let Predicates = [HasCDI] in {
3006 defm VPTESTNMDZ  : avx512_vptest<0x27, "vptestnmd", VK16, VR512,  f512mem,
3007                               memopv16i32, X86testnm, v16i32>, T8XS, EVEX_V512,
3008                               EVEX_CD8<32, CD8VF>;
3009 defm VPTESTNMQZ  : avx512_vptest<0x27, "vptestnmq", VK8, VR512,  f512mem,
3010                               memopv8i64, X86testnm, v8i64>, T8XS, EVEX_V512, VEX_W,
3011                               EVEX_CD8<64, CD8VF>;
3012 }
3013
3014 def : Pat <(i16 (int_x86_avx512_mask_ptestm_d_512 (v16i32 VR512:$src1),
3015                  (v16i32 VR512:$src2), (i16 -1))),
3016                  (COPY_TO_REGCLASS (VPTESTMDZrr VR512:$src1, VR512:$src2), GR16)>;
3017
3018 def : Pat <(i8 (int_x86_avx512_mask_ptestm_q_512 (v8i64 VR512:$src1),
3019                  (v8i64 VR512:$src2), (i8 -1))),
3020                  (COPY_TO_REGCLASS (VPTESTMQZrr VR512:$src1, VR512:$src2), GR8)>;
3021 //===----------------------------------------------------------------------===//
3022 // AVX-512  Shift instructions
3023 //===----------------------------------------------------------------------===//
3024 multiclass avx512_shift_rmi<bits<8> opc, Format ImmFormR, Format ImmFormM,
3025                          string OpcodeStr, SDNode OpNode, RegisterClass RC,
3026                          ValueType vt, X86MemOperand x86memop, PatFrag mem_frag,
3027                          RegisterClass KRC> {
3028   def ri : AVX512BIi8<opc, ImmFormR, (outs RC:$dst),
3029        (ins RC:$src1, i8imm:$src2),
3030            !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3031        [(set RC:$dst, (vt (OpNode RC:$src1, (i8 imm:$src2))))],
3032         SSE_INTSHIFT_ITINS_P.rr>, EVEX_4V;
3033   def rik : AVX512BIi8<opc, ImmFormR, (outs RC:$dst),
3034        (ins KRC:$mask, RC:$src1, i8imm:$src2),
3035            !strconcat(OpcodeStr,
3036                 " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
3037        [], SSE_INTSHIFT_ITINS_P.rr>, EVEX_4V, EVEX_K;
3038   def mi: AVX512BIi8<opc, ImmFormM, (outs RC:$dst),
3039        (ins x86memop:$src1, i8imm:$src2),
3040            !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3041        [(set RC:$dst, (OpNode (mem_frag addr:$src1),
3042                      (i8 imm:$src2)))], SSE_INTSHIFT_ITINS_P.rm>, EVEX_4V;
3043   def mik: AVX512BIi8<opc, ImmFormM, (outs RC:$dst),
3044        (ins KRC:$mask, x86memop:$src1, i8imm:$src2),
3045            !strconcat(OpcodeStr,
3046                 " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
3047        [], SSE_INTSHIFT_ITINS_P.rm>, EVEX_4V, EVEX_K;
3048 }
3049
3050 multiclass avx512_shift_rrm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3051                           RegisterClass RC, ValueType vt, ValueType SrcVT,
3052                           PatFrag bc_frag, RegisterClass KRC> {
3053   // src2 is always 128-bit
3054   def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
3055        (ins RC:$src1, VR128X:$src2),
3056            !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3057        [(set RC:$dst, (vt (OpNode RC:$src1, (SrcVT VR128X:$src2))))],
3058         SSE_INTSHIFT_ITINS_P.rr>, EVEX_4V;
3059   def rrk : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
3060        (ins KRC:$mask, RC:$src1, VR128X:$src2),
3061            !strconcat(OpcodeStr,
3062                 " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
3063        [], SSE_INTSHIFT_ITINS_P.rr>, EVEX_4V, EVEX_K;
3064   def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
3065        (ins RC:$src1, i128mem:$src2),
3066            !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3067        [(set RC:$dst, (vt (OpNode RC:$src1,
3068                        (bc_frag (memopv2i64 addr:$src2)))))],
3069                         SSE_INTSHIFT_ITINS_P.rm>, EVEX_4V;
3070   def rmk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
3071        (ins KRC:$mask, RC:$src1, i128mem:$src2),
3072            !strconcat(OpcodeStr,
3073                 " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
3074        [], SSE_INTSHIFT_ITINS_P.rm>, EVEX_4V, EVEX_K;
3075 }
3076
3077 defm VPSRLDZ : avx512_shift_rmi<0x72, MRM2r, MRM2m, "vpsrld", X86vsrli,
3078                            VR512, v16i32, i512mem, memopv16i32, VK16WM>,
3079                            EVEX_V512, EVEX_CD8<32, CD8VF>;
3080 defm VPSRLDZ : avx512_shift_rrm<0xD2, "vpsrld", X86vsrl,
3081                            VR512, v16i32, v4i32, bc_v4i32, VK16WM>, EVEX_V512,
3082                            EVEX_CD8<32, CD8VQ>;
3083                            
3084 defm VPSRLQZ : avx512_shift_rmi<0x73, MRM2r, MRM2m, "vpsrlq", X86vsrli,
3085                            VR512, v8i64, i512mem, memopv8i64, VK8WM>, EVEX_V512,
3086                            EVEX_CD8<64, CD8VF>, VEX_W;
3087 defm VPSRLQZ : avx512_shift_rrm<0xD3, "vpsrlq", X86vsrl,
3088                            VR512, v8i64, v2i64, bc_v2i64, VK8WM>, EVEX_V512,
3089                            EVEX_CD8<64, CD8VQ>, VEX_W;
3090
3091 defm VPSLLDZ : avx512_shift_rmi<0x72, MRM6r, MRM6m, "vpslld", X86vshli,
3092                            VR512, v16i32, i512mem, memopv16i32, VK16WM>, EVEX_V512,
3093                            EVEX_CD8<32, CD8VF>;
3094 defm VPSLLDZ : avx512_shift_rrm<0xF2, "vpslld", X86vshl,
3095                            VR512, v16i32, v4i32, bc_v4i32, VK16WM>, EVEX_V512,
3096                            EVEX_CD8<32, CD8VQ>;
3097                            
3098 defm VPSLLQZ : avx512_shift_rmi<0x73, MRM6r, MRM6m, "vpsllq", X86vshli,
3099                            VR512, v8i64, i512mem, memopv8i64, VK8WM>, EVEX_V512,
3100                            EVEX_CD8<64, CD8VF>, VEX_W;
3101 defm VPSLLQZ : avx512_shift_rrm<0xF3, "vpsllq", X86vshl,
3102                            VR512, v8i64, v2i64, bc_v2i64, VK8WM>, EVEX_V512,
3103                            EVEX_CD8<64, CD8VQ>, VEX_W;
3104
3105 defm VPSRADZ : avx512_shift_rmi<0x72, MRM4r, MRM4m, "vpsrad", X86vsrai,
3106                            VR512, v16i32, i512mem, memopv16i32, VK16WM>,
3107                            EVEX_V512, EVEX_CD8<32, CD8VF>;
3108 defm VPSRADZ : avx512_shift_rrm<0xE2, "vpsrad", X86vsra,
3109                            VR512, v16i32, v4i32, bc_v4i32, VK16WM>, EVEX_V512,
3110                            EVEX_CD8<32, CD8VQ>;
3111                            
3112 defm VPSRAQZ : avx512_shift_rmi<0x72, MRM4r, MRM4m, "vpsraq", X86vsrai,
3113                            VR512, v8i64, i512mem, memopv8i64, VK8WM>, EVEX_V512,
3114                            EVEX_CD8<64, CD8VF>, VEX_W;
3115 defm VPSRAQZ : avx512_shift_rrm<0xE2, "vpsraq", X86vsra,
3116                            VR512, v8i64, v2i64, bc_v2i64, VK8WM>, EVEX_V512,
3117                            EVEX_CD8<64, CD8VQ>, VEX_W;
3118
3119 //===-------------------------------------------------------------------===//
3120 // Variable Bit Shifts
3121 //===-------------------------------------------------------------------===//
3122 multiclass avx512_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
3123                            RegisterClass RC, ValueType vt,
3124                            X86MemOperand x86memop, PatFrag mem_frag> {
3125   def rr  : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
3126              (ins RC:$src1, RC:$src2),
3127              !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3128              [(set RC:$dst,
3129                (vt (OpNode RC:$src1, (vt RC:$src2))))]>,
3130              EVEX_4V;
3131   def rm  : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
3132              (ins RC:$src1, x86memop:$src2),
3133              !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3134              [(set RC:$dst,
3135                (vt (OpNode RC:$src1, (mem_frag addr:$src2))))]>,
3136              EVEX_4V;
3137 }
3138
3139 defm VPSLLVDZ : avx512_var_shift<0x47, "vpsllvd", shl, VR512, v16i32, 
3140                                i512mem, memopv16i32>, EVEX_V512,
3141                                EVEX_CD8<32, CD8VF>;
3142 defm VPSLLVQZ : avx512_var_shift<0x47, "vpsllvq", shl, VR512, v8i64, 
3143                                i512mem, memopv8i64>, EVEX_V512, VEX_W,
3144                                EVEX_CD8<64, CD8VF>;
3145 defm VPSRLVDZ : avx512_var_shift<0x45, "vpsrlvd", srl, VR512, v16i32, 
3146                                i512mem, memopv16i32>, EVEX_V512,
3147                                EVEX_CD8<32, CD8VF>;
3148 defm VPSRLVQZ : avx512_var_shift<0x45, "vpsrlvq", srl, VR512, v8i64, 
3149                                i512mem, memopv8i64>, EVEX_V512, VEX_W,
3150                                EVEX_CD8<64, CD8VF>;
3151 defm VPSRAVDZ : avx512_var_shift<0x46, "vpsravd", sra, VR512, v16i32, 
3152                                i512mem, memopv16i32>, EVEX_V512,
3153                                EVEX_CD8<32, CD8VF>;
3154 defm VPSRAVQZ : avx512_var_shift<0x46, "vpsravq", sra, VR512, v8i64, 
3155                                i512mem, memopv8i64>, EVEX_V512, VEX_W,
3156                                EVEX_CD8<64, CD8VF>;
3157
3158 //===----------------------------------------------------------------------===//
3159 // AVX-512 - MOVDDUP
3160 //===----------------------------------------------------------------------===//
3161
3162 multiclass avx512_movddup<string OpcodeStr, RegisterClass RC, ValueType VT, 
3163                         X86MemOperand x86memop, PatFrag memop_frag> {
3164 def rr  : AVX512PDI<0x12, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
3165                     !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
3166                     [(set RC:$dst, (VT (X86Movddup RC:$src)))]>, EVEX;
3167 def rm  : AVX512PDI<0x12, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
3168                     !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
3169                     [(set RC:$dst,
3170                       (VT (X86Movddup (memop_frag addr:$src))))]>, EVEX;
3171 }
3172
3173 defm VMOVDDUPZ : avx512_movddup<"vmovddup", VR512, v8f64, f512mem, memopv8f64>,
3174                  VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
3175 def : Pat<(X86Movddup (v8f64 (scalar_to_vector (loadf64 addr:$src)))),
3176           (VMOVDDUPZrm addr:$src)>;
3177
3178 //===---------------------------------------------------------------------===//
3179 // Replicate Single FP - MOVSHDUP and MOVSLDUP
3180 //===---------------------------------------------------------------------===//
3181 multiclass avx512_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
3182                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
3183                               X86MemOperand x86memop> {
3184   def rr : AVX512XSI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
3185                     !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
3186                       [(set RC:$dst, (vt (OpNode RC:$src)))]>, EVEX;
3187   let mayLoad = 1 in
3188   def rm : AVX512XSI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
3189                     !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
3190                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>, EVEX;
3191 }
3192
3193 defm VMOVSHDUPZ  : avx512_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
3194                        v16f32, VR512, memopv16f32, f512mem>, EVEX_V512,
3195                        EVEX_CD8<32, CD8VF>;
3196 defm VMOVSLDUPZ  : avx512_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
3197                        v16f32, VR512, memopv16f32, f512mem>, EVEX_V512,
3198                        EVEX_CD8<32, CD8VF>;
3199
3200 def : Pat<(v16i32 (X86Movshdup VR512:$src)), (VMOVSHDUPZrr VR512:$src)>;
3201 def : Pat<(v16i32 (X86Movshdup (memopv16i32 addr:$src))),
3202            (VMOVSHDUPZrm addr:$src)>;
3203 def : Pat<(v16i32 (X86Movsldup VR512:$src)), (VMOVSLDUPZrr VR512:$src)>;
3204 def : Pat<(v16i32 (X86Movsldup (memopv16i32 addr:$src))),
3205            (VMOVSLDUPZrm addr:$src)>;
3206
3207 //===----------------------------------------------------------------------===//
3208 // Move Low to High and High to Low packed FP Instructions
3209 //===----------------------------------------------------------------------===//
3210 def VMOVLHPSZrr : AVX512PSI<0x16, MRMSrcReg, (outs VR128X:$dst),
3211           (ins VR128X:$src1, VR128X:$src2),
3212           "vmovlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3213           [(set VR128X:$dst, (v4f32 (X86Movlhps VR128X:$src1, VR128X:$src2)))],
3214            IIC_SSE_MOV_LH>, EVEX_4V;
3215 def VMOVHLPSZrr : AVX512PSI<0x12, MRMSrcReg, (outs VR128X:$dst),
3216           (ins VR128X:$src1, VR128X:$src2),
3217           "vmovhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3218           [(set VR128X:$dst, (v4f32 (X86Movhlps VR128X:$src1, VR128X:$src2)))],
3219           IIC_SSE_MOV_LH>, EVEX_4V;
3220
3221 let Predicates = [HasAVX512] in {
3222   // MOVLHPS patterns
3223   def : Pat<(v4i32 (X86Movlhps VR128X:$src1, VR128X:$src2)),
3224             (VMOVLHPSZrr VR128X:$src1, VR128X:$src2)>;
3225   def : Pat<(v2i64 (X86Movlhps VR128X:$src1, VR128X:$src2)),
3226             (VMOVLHPSZrr (v2i64 VR128X:$src1), VR128X:$src2)>;
3227
3228   // MOVHLPS patterns
3229   def : Pat<(v4i32 (X86Movhlps VR128X:$src1, VR128X:$src2)),
3230             (VMOVHLPSZrr VR128X:$src1, VR128X:$src2)>;
3231 }
3232
3233 //===----------------------------------------------------------------------===//
3234 // FMA - Fused Multiply Operations
3235 //
3236 let Constraints = "$src1 = $dst" in {
3237 multiclass avx512_fma3p_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3238                            X86VectorVTInfo _> {
3239   defm r: AVX512_masking_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
3240           (ins _.RC:$src2, _.RC:$src3),
3241           OpcodeStr, "$src3, $src2", "$src2, $src3",
3242           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>,
3243          AVX512FMA3Base;
3244
3245   let mayLoad = 1 in
3246   def m: AVX512FMA3<opc, MRMSrcMem, (outs _.RC:$dst),
3247           (ins _.RC:$src1, _.RC:$src2, _.MemOp:$src3),
3248           !strconcat(OpcodeStr, " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3249           [(set _.RC:$dst, (_.VT (OpNode _.RC:$src1, _.RC:$src2,
3250                                                (_.MemOpFrag addr:$src3))))]>;
3251    def mb: AVX512FMA3<opc, MRMSrcMem, (outs _.RC:$dst),
3252            (ins _.RC:$src1, _.RC:$src2, _.ScalarMemOp:$src3),
3253            !strconcat(OpcodeStr, " \t{${src3}", _.BroadcastStr,
3254             ", $src2, $dst|$dst, $src2, ${src3}", _.BroadcastStr, "}"),
3255            [(set _.RC:$dst, (OpNode _.RC:$src1, _.RC:$src2,
3256            (_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3)))))]>, EVEX_B;
3257 }
3258 } // Constraints = "$src1 = $dst"
3259
3260 let ExeDomain = SSEPackedSingle in {
3261   defm VFMADD213PSZ    : avx512_fma3p_rm<0xA8, "vfmadd213ps", X86Fmadd,
3262                                          v16f32_info>,
3263                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3264   defm VFMSUB213PSZ    : avx512_fma3p_rm<0xAA, "vfmsub213ps", X86Fmsub,
3265                                          v16f32_info>,
3266                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3267   defm VFMADDSUB213PSZ : avx512_fma3p_rm<0xA6, "vfmaddsub213ps", X86Fmaddsub,
3268                                          v16f32_info>,
3269                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3270   defm VFMSUBADD213PSZ : avx512_fma3p_rm<0xA7, "vfmsubadd213ps", X86Fmsubadd,
3271                                          v16f32_info>,
3272                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3273   defm VFNMADD213PSZ   : avx512_fma3p_rm<0xAC, "vfnmadd213ps", X86Fnmadd,
3274                                          v16f32_info>,
3275                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3276   defm VFNMSUB213PSZ   : avx512_fma3p_rm<0xAE, "vfnmsub213ps", X86Fnmsub,
3277                                          v16f32_info>,
3278                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3279 }
3280 let ExeDomain = SSEPackedDouble in {
3281   defm VFMADD213PDZ    : avx512_fma3p_rm<0xA8, "vfmadd213pd", X86Fmadd,
3282                                          v8f64_info>,
3283                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3284   defm VFMSUB213PDZ    : avx512_fma3p_rm<0xAA, "vfmsub213pd", X86Fmsub,
3285                                          v8f64_info>,
3286                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3287   defm VFMADDSUB213PDZ : avx512_fma3p_rm<0xA6, "vfmaddsub213pd", X86Fmaddsub,
3288                                          v8f64_info>,
3289                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3290   defm VFMSUBADD213PDZ : avx512_fma3p_rm<0xA7, "vfmsubadd213pd", X86Fmsubadd,
3291                                          v8f64_info>,
3292                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3293   defm VFNMADD213PDZ :   avx512_fma3p_rm<0xAC, "vfnmadd213pd", X86Fnmadd,
3294                                          v8f64_info>,
3295                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3296   defm VFNMSUB213PDZ :   avx512_fma3p_rm<0xAE, "vfnmsub213pd", X86Fnmsub,
3297                                          v8f64_info>,
3298                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3299 }
3300
3301 let Constraints = "$src1 = $dst" in {
3302 multiclass avx512_fma3p_m132<bits<8> opc, string OpcodeStr, SDNode OpNode,
3303                              X86VectorVTInfo _> {
3304   let mayLoad = 1 in
3305   def m: AVX512FMA3<opc, MRMSrcMem, (outs _.RC:$dst),
3306           (ins _.RC:$src1, _.RC:$src3, _.MemOp:$src2),
3307           !strconcat(OpcodeStr, " \t{$src2, $src3, $dst|$dst, $src3, $src2}"),
3308           [(set _.RC:$dst, (_.VT (OpNode _.RC:$src1, (_.MemOpFrag addr:$src2),
3309                                                     _.RC:$src3)))]>;
3310    def mb: AVX512FMA3<opc, MRMSrcMem, (outs _.RC:$dst),
3311            (ins _.RC:$src1, _.RC:$src3, _.ScalarMemOp:$src2),
3312            !strconcat(OpcodeStr, " \t{${src2}", _.BroadcastStr,
3313             ", $src3, $dst|$dst, $src3, ${src2}", _.BroadcastStr, "}"),
3314            [(set _.RC:$dst,
3315                (OpNode _.RC:$src1, (_.VT (X86VBroadcast
3316                                             (_.ScalarLdFrag addr:$src2))),
3317                                    _.RC:$src3))]>, EVEX_B;
3318 }
3319 } // Constraints = "$src1 = $dst"
3320
3321
3322 let ExeDomain = SSEPackedSingle in {
3323   defm VFMADD132PSZ    : avx512_fma3p_m132<0x98, "vfmadd132ps", X86Fmadd,
3324                                            v16f32_info>,
3325                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3326   defm VFMSUB132PSZ    : avx512_fma3p_m132<0x9A, "vfmsub132ps", X86Fmsub,
3327                                            v16f32_info>,
3328                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3329   defm VFMADDSUB132PSZ : avx512_fma3p_m132<0x96, "vfmaddsub132ps", X86Fmaddsub,
3330                                            v16f32_info>,
3331                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3332   defm VFMSUBADD132PSZ : avx512_fma3p_m132<0x97, "vfmsubadd132ps", X86Fmsubadd,
3333                                            v16f32_info>,
3334                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3335   defm VFNMADD132PSZ   : avx512_fma3p_m132<0x9C, "vfnmadd132ps", X86Fnmadd,
3336                                            v16f32_info>,
3337                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3338   defm VFNMSUB132PSZ   : avx512_fma3p_m132<0x9E, "vfnmsub132ps", X86Fnmsub,
3339                                            v16f32_info>,
3340                          EVEX_V512, EVEX_CD8<32, CD8VF>;
3341 }
3342 let ExeDomain = SSEPackedDouble in {
3343   defm VFMADD132PDZ    : avx512_fma3p_m132<0x98, "vfmadd132pd", X86Fmadd,
3344                                            v8f64_info>,
3345                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3346   defm VFMSUB132PDZ    : avx512_fma3p_m132<0x9A, "vfmsub132pd", X86Fmsub,
3347                                            v8f64_info>,
3348                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3349   defm VFMADDSUB132PDZ : avx512_fma3p_m132<0x96, "vfmaddsub132pd", X86Fmaddsub,
3350                                            v8f64_info>,
3351                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3352   defm VFMSUBADD132PDZ : avx512_fma3p_m132<0x97, "vfmsubadd132pd", X86Fmsubadd,
3353                                            v8f64_info>,
3354                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3355   defm VFNMADD132PDZ :   avx512_fma3p_m132<0x9C, "vfnmadd132pd", X86Fnmadd,
3356                                            v8f64_info>,
3357                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3358   defm VFNMSUB132PDZ :   avx512_fma3p_m132<0x9E, "vfnmsub132pd", X86Fnmsub,
3359                                            v8f64_info>,
3360                          EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3361 }
3362
3363 // Scalar FMA
3364 let Constraints = "$src1 = $dst" in {
3365 multiclass avx512_fma3s_rm<bits<8> opc, string OpcodeStr, SDNode OpNode, 
3366                  RegisterClass RC, ValueType OpVT, 
3367                  X86MemOperand x86memop, Operand memop, 
3368                  PatFrag mem_frag> {
3369   let isCommutable = 1 in
3370   def r     : AVX512FMA3<opc, MRMSrcReg, (outs RC:$dst),
3371                    (ins RC:$src1, RC:$src2, RC:$src3),
3372                    !strconcat(OpcodeStr,
3373                               " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3374                    [(set RC:$dst,
3375                      (OpVT (OpNode RC:$src2, RC:$src1, RC:$src3)))]>;
3376   let mayLoad = 1 in
3377   def m     : AVX512FMA3<opc, MRMSrcMem, (outs RC:$dst),
3378                    (ins RC:$src1, RC:$src2, f128mem:$src3),
3379                    !strconcat(OpcodeStr,
3380                               " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3381                    [(set RC:$dst,
3382                      (OpVT (OpNode RC:$src2, RC:$src1,
3383                             (mem_frag addr:$src3))))]>;
3384 }
3385
3386 } // Constraints = "$src1 = $dst"
3387
3388 defm VFMADDSSZ  : avx512_fma3s_rm<0xA9, "vfmadd213ss", X86Fmadd, FR32X,
3389                       f32, f32mem, ssmem, loadf32>, EVEX_CD8<32, CD8VT1>;
3390 defm VFMADDSDZ  : avx512_fma3s_rm<0xA9, "vfmadd213sd", X86Fmadd, FR64X,
3391                       f64, f64mem, sdmem, loadf64>, VEX_W, EVEX_CD8<64, CD8VT1>;
3392 defm VFMSUBSSZ  : avx512_fma3s_rm<0xAB, "vfmsub213ss", X86Fmsub, FR32X,
3393                       f32, f32mem, ssmem, loadf32>, EVEX_CD8<32, CD8VT1>;
3394 defm VFMSUBSDZ  : avx512_fma3s_rm<0xAB, "vfmsub213sd", X86Fmsub, FR64X,
3395                       f64, f64mem, sdmem, loadf64>, VEX_W, EVEX_CD8<64, CD8VT1>;
3396 defm VFNMADDSSZ  : avx512_fma3s_rm<0xAD, "vfnmadd213ss", X86Fnmadd, FR32X,
3397                       f32, f32mem, ssmem, loadf32>, EVEX_CD8<32, CD8VT1>;
3398 defm VFNMADDSDZ  : avx512_fma3s_rm<0xAD, "vfnmadd213sd", X86Fnmadd, FR64X,
3399                       f64, f64mem, sdmem, loadf64>, VEX_W, EVEX_CD8<64, CD8VT1>;
3400 defm VFNMSUBSSZ  : avx512_fma3s_rm<0xAF, "vfnmsub213ss", X86Fnmsub, FR32X,
3401                       f32, f32mem, ssmem, loadf32>, EVEX_CD8<32, CD8VT1>;
3402 defm VFNMSUBSDZ  : avx512_fma3s_rm<0xAF, "vfnmsub213sd", X86Fnmsub, FR64X,
3403                       f64, f64mem, sdmem, loadf64>, VEX_W, EVEX_CD8<64, CD8VT1>;
3404
3405 //===----------------------------------------------------------------------===//
3406 // AVX-512  Scalar convert from sign integer to float/double
3407 //===----------------------------------------------------------------------===//
3408
3409 multiclass avx512_vcvtsi<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
3410                           X86MemOperand x86memop, string asm> {
3411 let hasSideEffects = 0 in {
3412   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
3413               !strconcat(asm," \t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
3414               EVEX_4V;
3415   let mayLoad = 1 in
3416   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
3417               (ins DstRC:$src1, x86memop:$src),
3418               !strconcat(asm," \t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
3419               EVEX_4V;
3420 } // hasSideEffects = 0
3421 }
3422 let Predicates = [HasAVX512] in {
3423 defm VCVTSI2SSZ   : avx512_vcvtsi<0x2A, GR32, FR32X, i32mem, "cvtsi2ss{l}">,
3424                                   XS, VEX_LIG, EVEX_CD8<32, CD8VT1>;
3425 defm VCVTSI642SSZ : avx512_vcvtsi<0x2A, GR64, FR32X, i64mem, "cvtsi2ss{q}">,
3426                                   XS, VEX_W, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3427 defm VCVTSI2SDZ   : avx512_vcvtsi<0x2A, GR32, FR64X, i32mem, "cvtsi2sd{l}">,
3428                                   XD, VEX_LIG, EVEX_CD8<32, CD8VT1>;
3429 defm VCVTSI642SDZ : avx512_vcvtsi<0x2A, GR64, FR64X, i64mem, "cvtsi2sd{q}">,
3430                                   XD, VEX_W, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3431
3432 def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
3433           (VCVTSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
3434 def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
3435           (VCVTSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
3436 def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
3437           (VCVTSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
3438 def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
3439           (VCVTSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
3440
3441 def : Pat<(f32 (sint_to_fp GR32:$src)),
3442           (VCVTSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
3443 def : Pat<(f32 (sint_to_fp GR64:$src)),
3444           (VCVTSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
3445 def : Pat<(f64 (sint_to_fp GR32:$src)),
3446           (VCVTSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
3447 def : Pat<(f64 (sint_to_fp GR64:$src)),
3448           (VCVTSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
3449
3450 defm VCVTUSI2SSZ   : avx512_vcvtsi<0x7B, GR32, FR32X, i32mem, "cvtusi2ss{l}">,
3451                                   XS, VEX_LIG, EVEX_CD8<32, CD8VT1>;
3452 defm VCVTUSI642SSZ : avx512_vcvtsi<0x7B, GR64, FR32X, i64mem, "cvtusi2ss{q}">,
3453                                   XS, VEX_W, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3454 defm VCVTUSI2SDZ   : avx512_vcvtsi<0x7B, GR32, FR64X, i32mem, "cvtusi2sd{l}">,
3455                                   XD, VEX_LIG, EVEX_CD8<32, CD8VT1>;
3456 defm VCVTUSI642SDZ : avx512_vcvtsi<0x7B, GR64, FR64X, i64mem, "cvtusi2sd{q}">,
3457                                   XD, VEX_W, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3458
3459 def : Pat<(f32 (uint_to_fp (loadi32 addr:$src))),
3460           (VCVTUSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
3461 def : Pat<(f32 (uint_to_fp (loadi64 addr:$src))),
3462           (VCVTUSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
3463 def : Pat<(f64 (uint_to_fp (loadi32 addr:$src))),
3464           (VCVTUSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
3465 def : Pat<(f64 (uint_to_fp (loadi64 addr:$src))),
3466           (VCVTUSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
3467
3468 def : Pat<(f32 (uint_to_fp GR32:$src)),
3469           (VCVTUSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
3470 def : Pat<(f32 (uint_to_fp GR64:$src)),
3471           (VCVTUSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
3472 def : Pat<(f64 (uint_to_fp GR32:$src)),
3473           (VCVTUSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
3474 def : Pat<(f64 (uint_to_fp GR64:$src)),
3475           (VCVTUSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
3476 }
3477
3478 //===----------------------------------------------------------------------===//
3479 // AVX-512  Scalar convert from float/double to integer
3480 //===----------------------------------------------------------------------===//
3481 multiclass avx512_cvt_s_int<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
3482                           Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
3483                           string asm> {
3484 let hasSideEffects = 0 in {
3485   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
3486               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3487               [(set DstRC:$dst, (Int SrcRC:$src))]>, EVEX, VEX_LIG,
3488               Requires<[HasAVX512]>;
3489   let mayLoad = 1 in
3490   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
3491               !strconcat(asm," \t{$src, $dst|$dst, $src}"), []>, EVEX, VEX_LIG,
3492               Requires<[HasAVX512]>;
3493 } // hasSideEffects = 0
3494 }
3495 let Predicates = [HasAVX512] in {
3496 // Convert float/double to signed/unsigned int 32/64
3497 defm VCVTSS2SIZ:    avx512_cvt_s_int<0x2D, VR128X, GR32, int_x86_sse_cvtss2si,
3498                                    ssmem, sse_load_f32, "cvtss2si">,
3499                                    XS, EVEX_CD8<32, CD8VT1>;
3500 defm VCVTSS2SI64Z:  avx512_cvt_s_int<0x2D, VR128X, GR64, int_x86_sse_cvtss2si64,
3501                                    ssmem, sse_load_f32, "cvtss2si">,
3502                                    XS, VEX_W, EVEX_CD8<32, CD8VT1>;
3503 defm VCVTSS2USIZ:   avx512_cvt_s_int<0x79, VR128X, GR32, int_x86_avx512_cvtss2usi,
3504                                    ssmem, sse_load_f32, "cvtss2usi">,
3505                                    XS, EVEX_CD8<32, CD8VT1>;
3506 defm VCVTSS2USI64Z: avx512_cvt_s_int<0x79, VR128X, GR64,
3507                                    int_x86_avx512_cvtss2usi64, ssmem,
3508                                    sse_load_f32, "cvtss2usi">, XS, VEX_W,
3509                                    EVEX_CD8<32, CD8VT1>;
3510 defm VCVTSD2SIZ:    avx512_cvt_s_int<0x2D, VR128X, GR32, int_x86_sse2_cvtsd2si,
3511                                    sdmem, sse_load_f64, "cvtsd2si">,
3512                                    XD, EVEX_CD8<64, CD8VT1>;
3513 defm VCVTSD2SI64Z:  avx512_cvt_s_int<0x2D, VR128X, GR64, int_x86_sse2_cvtsd2si64,
3514                                    sdmem, sse_load_f64, "cvtsd2si">,
3515                                    XD, VEX_W, EVEX_CD8<64, CD8VT1>;
3516 defm VCVTSD2USIZ:   avx512_cvt_s_int<0x79, VR128X, GR32, int_x86_avx512_cvtsd2usi,
3517                                    sdmem, sse_load_f64, "cvtsd2usi">,
3518                                    XD, EVEX_CD8<64, CD8VT1>;
3519 defm VCVTSD2USI64Z: avx512_cvt_s_int<0x79, VR128X, GR64,
3520                                    int_x86_avx512_cvtsd2usi64, sdmem,
3521                                    sse_load_f64, "cvtsd2usi">, XD, VEX_W,
3522                                    EVEX_CD8<64, CD8VT1>;
3523
3524 let isCodeGenOnly = 1 in {
3525   defm Int_VCVTSI2SSZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
3526             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
3527             SSE_CVT_Scalar, 0>, XS, EVEX_4V;
3528   defm Int_VCVTSI2SS64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
3529             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
3530             SSE_CVT_Scalar, 0>, XS, EVEX_4V, VEX_W;
3531   defm Int_VCVTSI2SDZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
3532             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
3533             SSE_CVT_Scalar, 0>, XD, EVEX_4V;
3534   defm Int_VCVTSI2SD64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
3535             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
3536             SSE_CVT_Scalar, 0>, XD, EVEX_4V, VEX_W;
3537
3538   defm Int_VCVTUSI2SSZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
3539             int_x86_avx512_cvtusi2ss, i32mem, loadi32, "cvtusi2ss{l}",
3540             SSE_CVT_Scalar, 0>, XS, EVEX_4V;
3541   defm Int_VCVTUSI2SS64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
3542             int_x86_avx512_cvtusi642ss, i64mem, loadi64, "cvtusi2ss{q}",
3543             SSE_CVT_Scalar, 0>, XS, EVEX_4V, VEX_W;
3544   defm Int_VCVTUSI2SDZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
3545             int_x86_avx512_cvtusi2sd, i32mem, loadi32, "cvtusi2sd{l}",
3546             SSE_CVT_Scalar, 0>, XD, EVEX_4V;
3547   defm Int_VCVTUSI2SD64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
3548             int_x86_avx512_cvtusi642sd, i64mem, loadi64, "cvtusi2sd{q}",
3549             SSE_CVT_Scalar, 0>, XD, EVEX_4V, VEX_W;
3550 } // isCodeGenOnly = 1
3551
3552 // Convert float/double to signed/unsigned int 32/64 with truncation
3553 let isCodeGenOnly = 1 in {
3554   defm Int_VCVTTSS2SIZ : avx512_cvt_s_int<0x2C, VR128X, GR32, int_x86_sse_cvttss2si,
3555                                      ssmem, sse_load_f32, "cvttss2si">,
3556                                      XS, EVEX_CD8<32, CD8VT1>;
3557   defm Int_VCVTTSS2SI64Z : avx512_cvt_s_int<0x2C, VR128X, GR64,
3558                                      int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
3559                                      "cvttss2si">, XS, VEX_W,
3560                                      EVEX_CD8<32, CD8VT1>;
3561   defm Int_VCVTTSD2SIZ : avx512_cvt_s_int<0x2C, VR128X, GR32, int_x86_sse2_cvttsd2si,
3562                                      sdmem, sse_load_f64, "cvttsd2si">, XD,
3563                                      EVEX_CD8<64, CD8VT1>;
3564   defm Int_VCVTTSD2SI64Z : avx512_cvt_s_int<0x2C, VR128X, GR64,
3565                                      int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
3566                                      "cvttsd2si">, XD, VEX_W,
3567                                      EVEX_CD8<64, CD8VT1>;
3568   defm Int_VCVTTSS2USIZ : avx512_cvt_s_int<0x78, VR128X, GR32,
3569                                      int_x86_avx512_cvttss2usi, ssmem, sse_load_f32,
3570                                      "cvttss2usi">, XS, EVEX_CD8<32, CD8VT1>;
3571   defm Int_VCVTTSS2USI64Z : avx512_cvt_s_int<0x78, VR128X, GR64,
3572                                      int_x86_avx512_cvttss2usi64, ssmem,
3573                                      sse_load_f32, "cvttss2usi">, XS, VEX_W,
3574                                      EVEX_CD8<32, CD8VT1>;
3575   defm Int_VCVTTSD2USIZ : avx512_cvt_s_int<0x78, VR128X, GR32,
3576                                      int_x86_avx512_cvttsd2usi,
3577                                      sdmem, sse_load_f64, "cvttsd2usi">, XD,
3578                                      EVEX_CD8<64, CD8VT1>;
3579   defm Int_VCVTTSD2USI64Z : avx512_cvt_s_int<0x78, VR128X, GR64,
3580                                      int_x86_avx512_cvttsd2usi64, sdmem,
3581                                      sse_load_f64, "cvttsd2usi">, XD, VEX_W,
3582                                      EVEX_CD8<64, CD8VT1>;
3583 } // isCodeGenOnly = 1
3584
3585 multiclass avx512_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
3586                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
3587                          string asm> {
3588   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
3589               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3590               [(set DstRC:$dst, (OpNode SrcRC:$src))]>, EVEX;
3591   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
3592               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3593               [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>, EVEX;
3594 }
3595
3596 defm VCVTTSS2SIZ    : avx512_cvt_s<0x2C, FR32X, GR32, fp_to_sint, f32mem,
3597                                   loadf32, "cvttss2si">, XS,
3598                                   EVEX_CD8<32, CD8VT1>;
3599 defm VCVTTSS2USIZ   : avx512_cvt_s<0x78, FR32X, GR32, fp_to_uint, f32mem,
3600                                   loadf32, "cvttss2usi">, XS,
3601                                   EVEX_CD8<32, CD8VT1>;
3602 defm VCVTTSS2SI64Z  : avx512_cvt_s<0x2C, FR32X, GR64, fp_to_sint, f32mem,
3603                                   loadf32, "cvttss2si">, XS, VEX_W,
3604                                   EVEX_CD8<32, CD8VT1>;
3605 defm VCVTTSS2USI64Z : avx512_cvt_s<0x78, FR32X, GR64, fp_to_uint, f32mem,
3606                                   loadf32, "cvttss2usi">, XS, VEX_W,
3607                                   EVEX_CD8<32, CD8VT1>;
3608 defm VCVTTSD2SIZ    : avx512_cvt_s<0x2C, FR64X, GR32, fp_to_sint, f64mem,
3609                                   loadf64, "cvttsd2si">, XD,
3610                                   EVEX_CD8<64, CD8VT1>;
3611 defm VCVTTSD2USIZ   : avx512_cvt_s<0x78, FR64X, GR32, fp_to_uint, f64mem,
3612                                   loadf64, "cvttsd2usi">, XD,
3613                                   EVEX_CD8<64, CD8VT1>;
3614 defm VCVTTSD2SI64Z  : avx512_cvt_s<0x2C, FR64X, GR64, fp_to_sint, f64mem,
3615                                   loadf64, "cvttsd2si">, XD, VEX_W,
3616                                   EVEX_CD8<64, CD8VT1>;
3617 defm VCVTTSD2USI64Z : avx512_cvt_s<0x78, FR64X, GR64, fp_to_uint, f64mem,
3618                                   loadf64, "cvttsd2usi">, XD, VEX_W,
3619                                   EVEX_CD8<64, CD8VT1>;
3620 } // HasAVX512
3621 //===----------------------------------------------------------------------===//
3622 // AVX-512  Convert form float to double and back
3623 //===----------------------------------------------------------------------===//
3624 let hasSideEffects = 0 in {
3625 def VCVTSS2SDZrr : AVX512XSI<0x5A, MRMSrcReg, (outs FR64X:$dst),
3626                     (ins FR32X:$src1, FR32X:$src2),
3627                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3628                     []>, EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
3629 let mayLoad = 1 in
3630 def VCVTSS2SDZrm : AVX512XSI<0x5A, MRMSrcMem, (outs FR64X:$dst),
3631                     (ins FR32X:$src1, f32mem:$src2),
3632                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3633                     []>, EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>,
3634                     EVEX_CD8<32, CD8VT1>;
3635
3636 // Convert scalar double to scalar single
3637 def VCVTSD2SSZrr  : AVX512XDI<0x5A, MRMSrcReg, (outs FR32X:$dst),
3638                       (ins FR64X:$src1, FR64X:$src2),
3639                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3640                       []>, EVEX_4V, VEX_LIG, VEX_W, Sched<[WriteCvtF2F]>;
3641 let mayLoad = 1 in
3642 def VCVTSD2SSZrm  : AVX512XDI<0x5A, MRMSrcMem, (outs FR32X:$dst),
3643                       (ins FR64X:$src1, f64mem:$src2),
3644                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3645                       []>, EVEX_4V, VEX_LIG, VEX_W,
3646                       Sched<[WriteCvtF2FLd, ReadAfterLd]>, EVEX_CD8<64, CD8VT1>;
3647 }
3648
3649 def : Pat<(f64 (fextend FR32X:$src)), (VCVTSS2SDZrr FR32X:$src, FR32X:$src)>,
3650       Requires<[HasAVX512]>;
3651 def : Pat<(fextend (loadf32 addr:$src)),
3652     (VCVTSS2SDZrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512]>;
3653
3654 def : Pat<(extloadf32 addr:$src),
3655     (VCVTSS2SDZrm (f32 (IMPLICIT_DEF)), addr:$src)>,
3656       Requires<[HasAVX512, OptForSize]>;
3657
3658 def : Pat<(extloadf32 addr:$src),
3659     (VCVTSS2SDZrr (f32 (IMPLICIT_DEF)), (VMOVSSZrm addr:$src))>,
3660     Requires<[HasAVX512, OptForSpeed]>;
3661
3662 def : Pat<(f32 (fround FR64X:$src)), (VCVTSD2SSZrr FR64X:$src, FR64X:$src)>,
3663            Requires<[HasAVX512]>;
3664
3665 multiclass avx512_vcvt_fp_with_rc<bits<8> opc, string asm, RegisterClass SrcRC, 
3666                RegisterClass DstRC, SDNode OpNode, PatFrag mem_frag, 
3667                X86MemOperand x86memop, ValueType OpVT, ValueType InVT,
3668                Domain d> {
3669 let hasSideEffects = 0 in {
3670   def rr : AVX512PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
3671               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3672               [(set DstRC:$dst,
3673                 (OpVT (OpNode (InVT SrcRC:$src))))], d>, EVEX;
3674   def rrb : AVX512PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src, AVX512RC:$rc),
3675               !strconcat(asm," \t{$rc, $src, $dst|$dst, $src, $rc}"),
3676               [], d>, EVEX, EVEX_B, EVEX_RC;
3677   let mayLoad = 1 in
3678   def rm : AVX512PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
3679               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3680               [(set DstRC:$dst,
3681                 (OpVT (OpNode (InVT (bitconvert (mem_frag addr:$src))))))], d>, EVEX;
3682 } // hasSideEffects = 0
3683 }
3684
3685 multiclass avx512_vcvt_fp<bits<8> opc, string asm, RegisterClass SrcRC,
3686                RegisterClass DstRC, SDNode OpNode, PatFrag mem_frag,
3687                X86MemOperand x86memop, ValueType OpVT, ValueType InVT,
3688                Domain d> {
3689 let hasSideEffects = 0 in {
3690   def rr : AVX512PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
3691               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3692               [(set DstRC:$dst,
3693                 (OpVT (OpNode (InVT SrcRC:$src))))], d>, EVEX;
3694   let mayLoad = 1 in
3695   def rm : AVX512PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
3696               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3697               [(set DstRC:$dst,
3698                 (OpVT (OpNode (InVT (bitconvert (mem_frag addr:$src))))))], d>, EVEX;
3699 } // hasSideEffects = 0
3700 }
3701
3702 defm VCVTPD2PSZ : avx512_vcvt_fp_with_rc<0x5A, "vcvtpd2ps", VR512, VR256X, fround,
3703                                 memopv8f64, f512mem, v8f32, v8f64,
3704                                 SSEPackedSingle>, EVEX_V512, VEX_W, PD,
3705                                 EVEX_CD8<64, CD8VF>;
3706
3707 defm VCVTPS2PDZ : avx512_vcvt_fp<0x5A, "vcvtps2pd", VR256X, VR512, fextend,
3708                                 memopv4f64, f256mem, v8f64, v8f32,
3709                                 SSEPackedDouble>, EVEX_V512, PS,
3710                                 EVEX_CD8<32, CD8VH>;
3711 def : Pat<(v8f64 (extloadv8f32 addr:$src)),
3712             (VCVTPS2PDZrm addr:$src)>;
3713             
3714 def : Pat<(v8f32 (int_x86_avx512_mask_cvtpd2ps_512 (v8f64 VR512:$src),
3715                    (bc_v8f32(v8i32 immAllZerosV)), (i8 -1), (i32 FROUND_CURRENT))),
3716           (VCVTPD2PSZrr VR512:$src)>;
3717
3718 def : Pat<(v8f32 (int_x86_avx512_mask_cvtpd2ps_512 (v8f64 VR512:$src),
3719                    (bc_v8f32(v8i32 immAllZerosV)), (i8 -1), imm:$rc)),
3720           (VCVTPD2PSZrrb VR512:$src, imm:$rc)>;
3721
3722 //===----------------------------------------------------------------------===//
3723 // AVX-512  Vector convert from sign integer to float/double
3724 //===----------------------------------------------------------------------===//
3725
3726 defm VCVTDQ2PSZ : avx512_vcvt_fp_with_rc<0x5B, "vcvtdq2ps", VR512, VR512, sint_to_fp,
3727                                 memopv8i64, i512mem, v16f32, v16i32,
3728                                 SSEPackedSingle>, EVEX_V512, PS,
3729                                 EVEX_CD8<32, CD8VF>;
3730
3731 defm VCVTDQ2PDZ : avx512_vcvt_fp<0xE6, "vcvtdq2pd", VR256X, VR512, sint_to_fp,
3732                                 memopv4i64, i256mem, v8f64, v8i32,
3733                                 SSEPackedDouble>, EVEX_V512, XS,
3734                                 EVEX_CD8<32, CD8VH>;
3735
3736 defm VCVTTPS2DQZ : avx512_vcvt_fp<0x5B, "vcvttps2dq", VR512, VR512, fp_to_sint,
3737                                  memopv16f32, f512mem, v16i32, v16f32,
3738                                  SSEPackedSingle>, EVEX_V512, XS,
3739                                  EVEX_CD8<32, CD8VF>;
3740
3741 defm VCVTTPD2DQZ : avx512_vcvt_fp<0xE6, "vcvttpd2dq", VR512, VR256X, fp_to_sint,
3742                                  memopv8f64, f512mem, v8i32, v8f64, 
3743                                  SSEPackedDouble>, EVEX_V512, PD, VEX_W,
3744                                  EVEX_CD8<64, CD8VF>;
3745
3746 defm VCVTTPS2UDQZ : avx512_vcvt_fp<0x78, "vcvttps2udq", VR512, VR512, fp_to_uint,
3747                                  memopv16f32, f512mem, v16i32, v16f32,
3748                                  SSEPackedSingle>, EVEX_V512, PS,
3749                                  EVEX_CD8<32, CD8VF>;
3750
3751 // cvttps2udq (src, 0, mask-all-ones, sae-current)
3752 def : Pat<(v16i32 (int_x86_avx512_mask_cvttps2udq_512 (v16f32 VR512:$src),
3753                    (v16i32 immAllZerosV), (i16 -1), FROUND_CURRENT)),
3754           (VCVTTPS2UDQZrr VR512:$src)>;
3755
3756 defm VCVTTPD2UDQZ : avx512_vcvt_fp<0x78, "vcvttpd2udq", VR512, VR256X, fp_to_uint,
3757                                  memopv8f64, f512mem, v8i32, v8f64,
3758                                  SSEPackedDouble>, EVEX_V512, PS, VEX_W,
3759                                  EVEX_CD8<64, CD8VF>;
3760                                  
3761 // cvttpd2udq (src, 0, mask-all-ones, sae-current)
3762 def : Pat<(v8i32 (int_x86_avx512_mask_cvttpd2udq_512 (v8f64 VR512:$src),
3763                    (v8i32 immAllZerosV), (i8 -1), FROUND_CURRENT)),
3764           (VCVTTPD2UDQZrr VR512:$src)>;
3765
3766 defm VCVTUDQ2PDZ : avx512_vcvt_fp<0x7A, "vcvtudq2pd", VR256X, VR512, uint_to_fp,
3767                                  memopv4i64, f256mem, v8f64, v8i32,
3768                                  SSEPackedDouble>, EVEX_V512, XS,
3769                                  EVEX_CD8<32, CD8VH>;
3770                                  
3771 defm VCVTUDQ2PSZ : avx512_vcvt_fp_with_rc<0x7A, "vcvtudq2ps", VR512, VR512, uint_to_fp,
3772                                  memopv16i32, f512mem, v16f32, v16i32,
3773                                  SSEPackedSingle>, EVEX_V512, XD,
3774                                  EVEX_CD8<32, CD8VF>;
3775
3776 def : Pat<(v8i32 (fp_to_uint (v8f32 VR256X:$src1))),
3777           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr 
3778            (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
3779                                  
3780 def : Pat<(v4i32 (fp_to_uint (v4f32 VR128X:$src1))),
3781           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
3782            (v16f32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_xmm)>;
3783
3784 def : Pat<(v8f32 (uint_to_fp (v8i32 VR256X:$src1))),
3785           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
3786            (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
3787            
3788 def : Pat<(v4f32 (uint_to_fp (v4i32 VR128X:$src1))),
3789           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
3790            (v16i32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_xmm)>;
3791
3792 def : Pat<(v4f64 (uint_to_fp (v4i32 VR128X:$src1))),
3793           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
3794            (v8i32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_ymm)>;
3795
3796 def : Pat<(v16f32 (int_x86_avx512_mask_cvtdq2ps_512 (v16i32 VR512:$src),
3797                    (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1), imm:$rc)),
3798           (VCVTDQ2PSZrrb VR512:$src, imm:$rc)>;
3799 def : Pat<(v8f64 (int_x86_avx512_mask_cvtdq2pd_512 (v8i32 VR256X:$src),
3800                    (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
3801           (VCVTDQ2PDZrr VR256X:$src)>;
3802 def : Pat<(v16f32 (int_x86_avx512_mask_cvtudq2ps_512 (v16i32 VR512:$src),
3803                    (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1), imm:$rc)),
3804           (VCVTUDQ2PSZrrb VR512:$src, imm:$rc)>;
3805 def : Pat<(v8f64 (int_x86_avx512_mask_cvtudq2pd_512 (v8i32 VR256X:$src),
3806                    (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
3807           (VCVTUDQ2PDZrr VR256X:$src)>;
3808
3809 multiclass avx512_vcvt_fp2int<bits<8> opc, string asm, RegisterClass SrcRC,
3810                RegisterClass DstRC, PatFrag mem_frag,
3811                X86MemOperand x86memop, Domain d> {
3812 let hasSideEffects = 0 in {
3813   def rr : AVX512PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
3814               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3815               [], d>, EVEX;
3816   def rrb : AVX512PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src, AVX512RC:$rc),
3817               !strconcat(asm," \t{$rc, $src, $dst|$dst, $src, $rc}"),
3818               [], d>, EVEX, EVEX_B, EVEX_RC;
3819   let mayLoad = 1 in
3820   def rm : AVX512PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
3821               !strconcat(asm," \t{$src, $dst|$dst, $src}"),
3822               [], d>, EVEX;
3823 } // hasSideEffects = 0
3824 }
3825
3826 defm VCVTPS2DQZ : avx512_vcvt_fp2int<0x5B, "vcvtps2dq", VR512, VR512,
3827                                  memopv16f32, f512mem, SSEPackedSingle>, PD,
3828                                  EVEX_V512, EVEX_CD8<32, CD8VF>;
3829 defm VCVTPD2DQZ : avx512_vcvt_fp2int<0xE6, "vcvtpd2dq", VR512, VR256X,
3830                                  memopv8f64, f512mem, SSEPackedDouble>, XD, VEX_W,
3831                                  EVEX_V512, EVEX_CD8<64, CD8VF>;
3832
3833 def : Pat <(v16i32 (int_x86_avx512_mask_cvtps2dq_512 (v16f32 VR512:$src),
3834                     (v16i32 immAllZerosV), (i16 -1), imm:$rc)),
3835            (VCVTPS2DQZrrb VR512:$src, imm:$rc)>;
3836
3837 def : Pat <(v8i32 (int_x86_avx512_mask_cvtpd2dq_512 (v8f64 VR512:$src),
3838                     (v8i32 immAllZerosV), (i8 -1), imm:$rc)),
3839            (VCVTPD2DQZrrb VR512:$src, imm:$rc)>;
3840
3841 defm VCVTPS2UDQZ : avx512_vcvt_fp2int<0x79, "vcvtps2udq", VR512, VR512,
3842                                  memopv16f32, f512mem, SSEPackedSingle>,
3843                                  PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
3844 defm VCVTPD2UDQZ : avx512_vcvt_fp2int<0x79, "vcvtpd2udq", VR512, VR256X,
3845                                  memopv8f64, f512mem, SSEPackedDouble>, VEX_W,
3846                                  PS, EVEX_V512, EVEX_CD8<64, CD8VF>;
3847
3848 def : Pat <(v16i32 (int_x86_avx512_mask_cvtps2udq_512 (v16f32 VR512:$src),
3849                     (v16i32 immAllZerosV), (i16 -1), imm:$rc)),
3850            (VCVTPS2UDQZrrb VR512:$src, imm:$rc)>;
3851
3852 def : Pat <(v8i32 (int_x86_avx512_mask_cvtpd2udq_512 (v8f64 VR512:$src),
3853                     (v8i32 immAllZerosV), (i8 -1), imm:$rc)),
3854            (VCVTPD2UDQZrrb VR512:$src, imm:$rc)>;
3855
3856 let Predicates = [HasAVX512] in {
3857   def : Pat<(v8f32 (fround (loadv8f64 addr:$src))),
3858             (VCVTPD2PSZrm addr:$src)>;
3859   def : Pat<(v8f64 (extloadv8f32 addr:$src)),
3860             (VCVTPS2PDZrm addr:$src)>;
3861 }
3862
3863 //===----------------------------------------------------------------------===//
3864 // Half precision conversion instructions
3865 //===----------------------------------------------------------------------===//
3866 multiclass avx512_cvtph2ps<RegisterClass destRC, RegisterClass srcRC,
3867                              X86MemOperand x86memop> {
3868   def rr : AVX5128I<0x13, MRMSrcReg, (outs destRC:$dst), (ins srcRC:$src),
3869              "vcvtph2ps\t{$src, $dst|$dst, $src}",
3870              []>, EVEX;
3871   let hasSideEffects = 0, mayLoad = 1 in
3872   def rm : AVX5128I<0x13, MRMSrcMem, (outs destRC:$dst), (ins x86memop:$src),
3873              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, EVEX;
3874 }
3875
3876 multiclass avx512_cvtps2ph<RegisterClass destRC, RegisterClass srcRC,
3877                              X86MemOperand x86memop> {
3878   def rr : AVX512AIi8<0x1D, MRMDestReg, (outs destRC:$dst),
3879                (ins srcRC:$src1, i32i8imm:$src2),
3880                "vcvtps2ph \t{$src2, $src1, $dst|$dst, $src1, $src2}",
3881                []>, EVEX;
3882   let hasSideEffects = 0, mayStore = 1 in
3883   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
3884                (ins x86memop:$dst, srcRC:$src1, i32i8imm:$src2),
3885                "vcvtps2ph \t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, EVEX;
3886 }
3887
3888 defm VCVTPH2PSZ : avx512_cvtph2ps<VR512, VR256X, f256mem>, EVEX_V512,
3889                                     EVEX_CD8<32, CD8VH>;
3890 defm VCVTPS2PHZ : avx512_cvtps2ph<VR256X, VR512, f256mem>, EVEX_V512,
3891                                     EVEX_CD8<32, CD8VH>;
3892
3893 def : Pat<(v16i16 (int_x86_avx512_mask_vcvtps2ph_512 (v16f32 VR512:$src),
3894            imm:$rc, (bc_v16i16(v8i32 immAllZerosV)), (i16 -1))),
3895            (VCVTPS2PHZrr VR512:$src, imm:$rc)>;
3896
3897 def : Pat<(v16f32 (int_x86_avx512_mask_vcvtph2ps_512 (v16i16 VR256X:$src),
3898            (bc_v16f32(v16i32 immAllZerosV)), (i16 -1), (i32 FROUND_CURRENT))),
3899            (VCVTPH2PSZrr VR256X:$src)>;
3900
3901 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
3902   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
3903                                  "ucomiss">, PS, EVEX, VEX_LIG,
3904                                  EVEX_CD8<32, CD8VT1>;
3905   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
3906                                   "ucomisd">, PD, EVEX,
3907                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
3908   let Pattern = []<dag> in {
3909     defm VCOMISSZ  : sse12_ord_cmp<0x2F, VR128X, undef, v4f32, f128mem, load,
3910                                    "comiss">, PS, EVEX, VEX_LIG,
3911                                    EVEX_CD8<32, CD8VT1>;
3912     defm VCOMISDZ  : sse12_ord_cmp<0x2F, VR128X, undef, v2f64, f128mem, load,
3913                                    "comisd">, PD, EVEX,
3914                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
3915   }
3916   let isCodeGenOnly = 1 in {
3917     defm Int_VUCOMISSZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v4f32, f128mem,
3918                               load, "ucomiss">, PS, EVEX, VEX_LIG,
3919                               EVEX_CD8<32, CD8VT1>;
3920     defm Int_VUCOMISDZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v2f64, f128mem,
3921                               load, "ucomisd">, PD, EVEX,
3922                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
3923
3924     defm Int_VCOMISSZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v4f32, f128mem,
3925                               load, "comiss">, PS, EVEX, VEX_LIG,
3926                               EVEX_CD8<32, CD8VT1>;
3927     defm Int_VCOMISDZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v2f64, f128mem,
3928                               load, "comisd">, PD, EVEX,
3929                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
3930   }
3931 }
3932   
3933 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
3934 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
3935                             X86MemOperand x86memop> {
3936   let hasSideEffects = 0 in {
3937   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
3938                (ins RC:$src1, RC:$src2),
3939                !strconcat(OpcodeStr,
3940                " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, EVEX_4V;
3941   let mayLoad = 1 in {
3942   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
3943                (ins RC:$src1, x86memop:$src2),
3944                !strconcat(OpcodeStr,
3945                " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, EVEX_4V;
3946   }
3947 }
3948 }
3949
3950 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", FR32X, f32mem>,
3951                   EVEX_CD8<32, CD8VT1>;
3952 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", FR64X, f64mem>,
3953                   VEX_W, EVEX_CD8<64, CD8VT1>;
3954 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", FR32X, f32mem>,
3955                   EVEX_CD8<32, CD8VT1>;
3956 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", FR64X, f64mem>,
3957                   VEX_W, EVEX_CD8<64, CD8VT1>;
3958
3959 def : Pat <(v4f32 (int_x86_avx512_rcp14_ss (v4f32 VR128X:$src1),
3960               (v4f32 VR128X:$src2), (bc_v4f32 (v4i32 immAllZerosV)), (i8 -1))),
3961            (COPY_TO_REGCLASS (VRCP14SSrr (COPY_TO_REGCLASS VR128X:$src1, FR32X),
3962                        (COPY_TO_REGCLASS VR128X:$src2, FR32X)), VR128X)>;
3963
3964 def : Pat <(v2f64 (int_x86_avx512_rcp14_sd (v2f64 VR128X:$src1),
3965               (v2f64 VR128X:$src2), (bc_v2f64 (v4i32 immAllZerosV)), (i8 -1))),
3966            (COPY_TO_REGCLASS (VRCP14SDrr (COPY_TO_REGCLASS VR128X:$src1, FR64X),
3967                        (COPY_TO_REGCLASS VR128X:$src2, FR64X)), VR128X)>;
3968
3969 def : Pat <(v4f32 (int_x86_avx512_rsqrt14_ss (v4f32 VR128X:$src1),
3970               (v4f32 VR128X:$src2), (bc_v4f32 (v4i32 immAllZerosV)), (i8 -1))),
3971            (COPY_TO_REGCLASS (VRSQRT14SSrr (COPY_TO_REGCLASS VR128X:$src1, FR32X),
3972                        (COPY_TO_REGCLASS VR128X:$src2, FR32X)), VR128X)>;
3973
3974 def : Pat <(v2f64 (int_x86_avx512_rsqrt14_sd (v2f64 VR128X:$src1),
3975               (v2f64 VR128X:$src2), (bc_v2f64 (v4i32 immAllZerosV)), (i8 -1))),
3976            (COPY_TO_REGCLASS (VRSQRT14SDrr (COPY_TO_REGCLASS VR128X:$src1, FR64X),
3977                        (COPY_TO_REGCLASS VR128X:$src2, FR64X)), VR128X)>;
3978
3979 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
3980 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3981                          RegisterClass RC, X86MemOperand x86memop,
3982                          PatFrag mem_frag, ValueType OpVt> {
3983   def r : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
3984                         !strconcat(OpcodeStr,
3985                                    " \t{$src, $dst|$dst, $src}"),
3986                         [(set RC:$dst, (OpVt (OpNode RC:$src)))]>,
3987                         EVEX;
3988   def m : AVX5128I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
3989                         !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
3990                         [(set RC:$dst, (OpVt (OpNode (mem_frag addr:$src))))]>,
3991                         EVEX;
3992 }
3993 defm VRSQRT14PSZ : avx512_fp14_p<0x4E, "vrsqrt14ps", X86frsqrt, VR512, f512mem,
3994                         memopv16f32, v16f32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
3995 defm VRSQRT14PDZ : avx512_fp14_p<0x4E, "vrsqrt14pd", X86frsqrt, VR512, f512mem,
3996                         memopv8f64, v8f64>, VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
3997 defm VRCP14PSZ : avx512_fp14_p<0x4C, "vrcp14ps", X86frcp, VR512, f512mem,
3998                         memopv16f32, v16f32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
3999 defm VRCP14PDZ : avx512_fp14_p<0x4C, "vrcp14pd", X86frcp, VR512, f512mem,
4000                         memopv8f64, v8f64>, VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4001
4002 def : Pat <(v16f32 (int_x86_avx512_rsqrt14_ps_512 (v16f32 VR512:$src),
4003               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
4004            (VRSQRT14PSZr VR512:$src)>;
4005 def : Pat <(v8f64 (int_x86_avx512_rsqrt14_pd_512 (v8f64 VR512:$src),
4006               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
4007            (VRSQRT14PDZr VR512:$src)>;
4008
4009 def : Pat <(v16f32 (int_x86_avx512_rcp14_ps_512 (v16f32 VR512:$src),
4010               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
4011            (VRCP14PSZr VR512:$src)>;
4012 def : Pat <(v8f64 (int_x86_avx512_rcp14_pd_512 (v8f64 VR512:$src),
4013               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
4014            (VRCP14PDZr VR512:$src)>;
4015
4016 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
4017 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
4018                             X86MemOperand x86memop> {
4019   let hasSideEffects = 0, Predicates = [HasERI] in {
4020   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
4021                (ins RC:$src1, RC:$src2),
4022                !strconcat(OpcodeStr,
4023                " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, EVEX_4V;
4024   def rrb : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
4025                (ins RC:$src1, RC:$src2),
4026                !strconcat(OpcodeStr,
4027                " \t{{sae}, $src2, $src1, $dst|$dst, $src1, $src2, {sae}}"),
4028                []>, EVEX_4V, EVEX_B;
4029   let mayLoad = 1 in {
4030   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4031                (ins RC:$src1, x86memop:$src2),
4032                !strconcat(OpcodeStr,
4033                " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>, EVEX_4V;
4034   }
4035 }
4036 }
4037
4038 defm VRCP28SS   : avx512_fp28_s<0xCB, "vrcp28ss", FR32X, f32mem>,
4039                   EVEX_CD8<32, CD8VT1>;
4040 defm VRCP28SD   : avx512_fp28_s<0xCB, "vrcp28sd", FR64X, f64mem>,
4041                   VEX_W, EVEX_CD8<64, CD8VT1>;
4042 defm VRSQRT28SS   : avx512_fp28_s<0xCD, "vrsqrt28ss", FR32X, f32mem>,
4043                   EVEX_CD8<32, CD8VT1>;
4044 defm VRSQRT28SD   : avx512_fp28_s<0xCD, "vrsqrt28sd", FR64X, f64mem>,
4045                   VEX_W, EVEX_CD8<64, CD8VT1>;
4046
4047 def : Pat <(v4f32 (int_x86_avx512_rcp28_ss (v4f32 VR128X:$src1),
4048               (v4f32 VR128X:$src2), (bc_v4f32 (v4i32 immAllZerosV)), (i8 -1),
4049                    FROUND_NO_EXC)),
4050            (COPY_TO_REGCLASS (VRCP28SSrrb (COPY_TO_REGCLASS VR128X:$src1, FR32X),
4051                        (COPY_TO_REGCLASS VR128X:$src2, FR32X)), VR128X)>;
4052
4053 def : Pat <(v2f64 (int_x86_avx512_rcp28_sd (v2f64 VR128X:$src1),
4054               (v2f64 VR128X:$src2), (bc_v2f64 (v4i32 immAllZerosV)), (i8 -1),
4055                    FROUND_NO_EXC)),
4056            (COPY_TO_REGCLASS (VRCP28SDrrb (COPY_TO_REGCLASS VR128X:$src1, FR64X),
4057                        (COPY_TO_REGCLASS VR128X:$src2, FR64X)), VR128X)>;
4058
4059 def : Pat <(v4f32 (int_x86_avx512_rsqrt28_ss (v4f32 VR128X:$src1),
4060               (v4f32 VR128X:$src2), (bc_v4f32 (v4i32 immAllZerosV)), (i8 -1),
4061                    FROUND_NO_EXC)),
4062            (COPY_TO_REGCLASS (VRSQRT28SSrrb (COPY_TO_REGCLASS VR128X:$src1, FR32X),
4063                        (COPY_TO_REGCLASS VR128X:$src2, FR32X)), VR128X)>;
4064
4065 def : Pat <(v2f64 (int_x86_avx512_rsqrt28_sd (v2f64 VR128X:$src1),
4066               (v2f64 VR128X:$src2), (bc_v2f64 (v4i32 immAllZerosV)), (i8 -1),
4067                    FROUND_NO_EXC)),
4068            (COPY_TO_REGCLASS (VRSQRT28SDrrb (COPY_TO_REGCLASS VR128X:$src1, FR64X),
4069                        (COPY_TO_REGCLASS VR128X:$src2, FR64X)), VR128X)>;
4070
4071 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
4072 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr,
4073                          RegisterClass RC, X86MemOperand x86memop> {
4074   let hasSideEffects = 0, Predicates = [HasERI] in {
4075   def r : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4076                         !strconcat(OpcodeStr,
4077                                    " \t{$src, $dst|$dst, $src}"),
4078                         []>, EVEX;
4079   def rb : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4080                         !strconcat(OpcodeStr,
4081                                    " \t{{sae}, $src, $dst|$dst, $src, {sae}}"),
4082                         []>, EVEX, EVEX_B;
4083   def m : AVX5128I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4084                         !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
4085                         []>, EVEX;
4086   }
4087 }
4088 defm VRSQRT28PSZ : avx512_fp28_p<0xCC, "vrsqrt28ps", VR512, f512mem>,
4089                         EVEX_V512, EVEX_CD8<32, CD8VF>;
4090 defm VRSQRT28PDZ : avx512_fp28_p<0xCC, "vrsqrt28pd", VR512, f512mem>,
4091                         VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4092 defm VRCP28PSZ : avx512_fp28_p<0xCA, "vrcp28ps", VR512, f512mem>,
4093                         EVEX_V512, EVEX_CD8<32, CD8VF>;
4094 defm VRCP28PDZ : avx512_fp28_p<0xCA, "vrcp28pd", VR512, f512mem>,
4095                         VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4096
4097 def : Pat <(v16f32 (int_x86_avx512_rsqrt28_ps (v16f32 VR512:$src),
4098               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1), FROUND_NO_EXC)),
4099            (VRSQRT28PSZrb VR512:$src)>;
4100 def : Pat <(v8f64 (int_x86_avx512_rsqrt28_pd (v8f64 VR512:$src),
4101               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1), FROUND_NO_EXC)),
4102            (VRSQRT28PDZrb VR512:$src)>;
4103
4104 def : Pat <(v16f32 (int_x86_avx512_rcp28_ps (v16f32 VR512:$src),
4105               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1), FROUND_NO_EXC)),
4106            (VRCP28PSZrb VR512:$src)>;
4107 def : Pat <(v8f64 (int_x86_avx512_rcp28_pd (v8f64 VR512:$src),
4108               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1), FROUND_NO_EXC)),
4109            (VRCP28PDZrb VR512:$src)>;
4110
4111 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
4112                               OpndItins itins_s, OpndItins itins_d> {
4113   def PSZrr :AVX512PSI<opc, MRMSrcReg, (outs VR512:$dst), (ins VR512:$src),
4114              !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
4115              [(set VR512:$dst, (v16f32 (OpNode VR512:$src)))], itins_s.rr>,
4116              EVEX, EVEX_V512;
4117
4118   let mayLoad = 1 in
4119   def PSZrm : AVX512PSI<opc, MRMSrcMem, (outs VR512:$dst), (ins f512mem:$src),
4120               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
4121               [(set VR512:$dst, 
4122                 (OpNode (v16f32 (bitconvert (memopv16f32 addr:$src)))))],
4123               itins_s.rm>, EVEX, EVEX_V512, EVEX_CD8<32, CD8VF>;
4124
4125   def PDZrr : AVX512PDI<opc, MRMSrcReg, (outs VR512:$dst), (ins VR512:$src),
4126               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
4127               [(set VR512:$dst, (v8f64 (OpNode VR512:$src)))], itins_d.rr>,
4128               EVEX, EVEX_V512;
4129
4130   let mayLoad = 1 in
4131     def PDZrm : AVX512PDI<opc, MRMSrcMem, (outs VR512:$dst), (ins f512mem:$src),
4132                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
4133                 [(set VR512:$dst, (OpNode
4134                   (v8f64 (bitconvert (memopv16f32 addr:$src)))))],
4135                 itins_d.rm>, EVEX, EVEX_V512, EVEX_CD8<64, CD8VF>;
4136
4137 }
4138
4139 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,
4140                           Intrinsic F32Int, Intrinsic F64Int,
4141                           OpndItins itins_s, OpndItins itins_d> {
4142   def SSZr : SI<opc, MRMSrcReg, (outs FR32X:$dst),
4143                (ins FR32X:$src1, FR32X:$src2),
4144                !strconcat(OpcodeStr,
4145                           "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4146                       [], itins_s.rr>, XS, EVEX_4V;
4147   let isCodeGenOnly = 1 in
4148   def SSZr_Int : SIi8<opc, MRMSrcReg, (outs VR128X:$dst),
4149                (ins VR128X:$src1, VR128X:$src2),
4150                !strconcat(OpcodeStr,
4151                 "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4152                [(set VR128X:$dst, 
4153                  (F32Int VR128X:$src1, VR128X:$src2))],
4154                itins_s.rr>, XS, EVEX_4V;
4155   let mayLoad = 1 in {
4156   def SSZm : SI<opc, MRMSrcMem, (outs FR32X:$dst),
4157                (ins FR32X:$src1, f32mem:$src2),
4158                !strconcat(OpcodeStr,
4159                           "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4160                       [], itins_s.rm>, XS, EVEX_4V, EVEX_CD8<32, CD8VT1>;
4161   let isCodeGenOnly = 1 in
4162   def SSZm_Int : SIi8<opc, MRMSrcMem, (outs VR128X:$dst),
4163                    (ins VR128X:$src1, ssmem:$src2),
4164                    !strconcat(OpcodeStr,
4165                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4166                    [(set VR128X:$dst, 
4167                      (F32Int VR128X:$src1, sse_load_f32:$src2))],
4168                    itins_s.rm>, XS, EVEX_4V, EVEX_CD8<32, CD8VT1>;
4169   }
4170   def SDZr : SI<opc, MRMSrcReg, (outs FR64X:$dst),
4171                (ins FR64X:$src1, FR64X:$src2),
4172                !strconcat(OpcodeStr,
4173                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
4174                       XD, EVEX_4V, VEX_W;
4175   let isCodeGenOnly = 1 in
4176   def SDZr_Int : SIi8<opc, MRMSrcReg, (outs VR128X:$dst),
4177                (ins VR128X:$src1, VR128X:$src2),
4178                !strconcat(OpcodeStr,
4179                 "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4180                [(set VR128X:$dst, 
4181                  (F64Int VR128X:$src1, VR128X:$src2))],
4182                itins_s.rr>, XD, EVEX_4V, VEX_W;
4183   let mayLoad = 1 in {
4184   def SDZm : SI<opc, MRMSrcMem, (outs FR64X:$dst),
4185                (ins FR64X:$src1, f64mem:$src2),
4186                !strconcat(OpcodeStr,
4187                   "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
4188                XD, EVEX_4V, VEX_W, EVEX_CD8<64, CD8VT1>;
4189   let isCodeGenOnly = 1 in
4190   def SDZm_Int : SIi8<opc, MRMSrcMem, (outs VR128X:$dst),
4191                   (ins VR128X:$src1, sdmem:$src2),
4192                    !strconcat(OpcodeStr,
4193                   "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4194                   [(set VR128X:$dst, 
4195                     (F64Int VR128X:$src1, sse_load_f64:$src2))]>, 
4196                   XD, EVEX_4V, VEX_W, EVEX_CD8<64, CD8VT1>;
4197   }
4198 }
4199
4200
4201 defm VSQRT  : avx512_sqrt_scalar<0x51, "sqrt", 
4202                 int_x86_avx512_sqrt_ss, int_x86_avx512_sqrt_sd, 
4203                 SSE_SQRTSS, SSE_SQRTSD>,
4204               avx512_sqrt_packed<0x51, "vsqrt", fsqrt,
4205                 SSE_SQRTPS, SSE_SQRTPD>;
4206
4207 let Predicates = [HasAVX512] in {
4208   def : Pat<(v16f32 (int_x86_avx512_sqrt_ps_512 (v16f32 VR512:$src1),
4209                     (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1), FROUND_CURRENT)),
4210                    (VSQRTPSZrr VR512:$src1)>;
4211   def : Pat<(v8f64 (int_x86_avx512_sqrt_pd_512 (v8f64 VR512:$src1),
4212                     (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1), FROUND_CURRENT)),
4213                    (VSQRTPDZrr VR512:$src1)>;
4214   
4215   def : Pat<(f32 (fsqrt FR32X:$src)),
4216             (VSQRTSSZr (f32 (IMPLICIT_DEF)), FR32X:$src)>;
4217   def : Pat<(f32 (fsqrt (load addr:$src))),
4218             (VSQRTSSZm (f32 (IMPLICIT_DEF)), addr:$src)>,
4219             Requires<[OptForSize]>;
4220   def : Pat<(f64 (fsqrt FR64X:$src)),
4221             (VSQRTSDZr (f64 (IMPLICIT_DEF)), FR64X:$src)>;
4222   def : Pat<(f64 (fsqrt (load addr:$src))),
4223             (VSQRTSDZm (f64 (IMPLICIT_DEF)), addr:$src)>,
4224             Requires<[OptForSize]>;
4225
4226   def : Pat<(f32 (X86frsqrt FR32X:$src)),
4227             (VRSQRT14SSrr (f32 (IMPLICIT_DEF)), FR32X:$src)>;
4228   def : Pat<(f32 (X86frsqrt (load addr:$src))),
4229             (VRSQRT14SSrm (f32 (IMPLICIT_DEF)), addr:$src)>,
4230             Requires<[OptForSize]>;
4231
4232   def : Pat<(f32 (X86frcp FR32X:$src)),
4233             (VRCP14SSrr (f32 (IMPLICIT_DEF)), FR32X:$src)>;
4234   def : Pat<(f32 (X86frcp (load addr:$src))),
4235             (VRCP14SSrm (f32 (IMPLICIT_DEF)), addr:$src)>,
4236             Requires<[OptForSize]>;
4237
4238   def : Pat<(int_x86_sse_sqrt_ss VR128X:$src),
4239             (COPY_TO_REGCLASS (VSQRTSSZr (f32 (IMPLICIT_DEF)),
4240                                         (COPY_TO_REGCLASS VR128X:$src, FR32)),
4241                               VR128X)>;
4242   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
4243             (VSQRTSSZm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
4244
4245   def : Pat<(int_x86_sse2_sqrt_sd VR128X:$src),
4246             (COPY_TO_REGCLASS (VSQRTSDZr (f64 (IMPLICIT_DEF)),
4247                                         (COPY_TO_REGCLASS VR128X:$src, FR64)),
4248                               VR128X)>;
4249   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
4250             (VSQRTSDZm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
4251 }
4252
4253
4254 multiclass avx512_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
4255                             X86MemOperand x86memop, RegisterClass RC,
4256                             PatFrag mem_frag32, PatFrag mem_frag64,
4257                             Intrinsic V4F32Int, Intrinsic V2F64Int,
4258                             CD8VForm VForm> {
4259 let ExeDomain = SSEPackedSingle in {
4260   // Intrinsic operation, reg.
4261   // Vector intrinsic operation, reg
4262   def PSr : AVX512AIi8<opcps, MRMSrcReg,
4263                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
4264                     !strconcat(OpcodeStr,
4265                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4266                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>;
4267
4268   // Vector intrinsic operation, mem
4269   def PSm : AVX512AIi8<opcps, MRMSrcMem,
4270                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
4271                     !strconcat(OpcodeStr,
4272                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4273                     [(set RC:$dst,
4274                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
4275                     EVEX_CD8<32, VForm>;
4276 } // ExeDomain = SSEPackedSingle
4277
4278 let ExeDomain = SSEPackedDouble in {
4279   // Vector intrinsic operation, reg
4280   def PDr : AVX512AIi8<opcpd, MRMSrcReg,
4281                      (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
4282                      !strconcat(OpcodeStr,
4283                      "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4284                      [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>;
4285
4286   // Vector intrinsic operation, mem
4287   def PDm : AVX512AIi8<opcpd, MRMSrcMem,
4288                      (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
4289                      !strconcat(OpcodeStr,
4290                      "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4291                      [(set RC:$dst,
4292                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
4293                      EVEX_CD8<64, VForm>;
4294 } // ExeDomain = SSEPackedDouble
4295 }
4296
4297 multiclass avx512_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
4298                             string OpcodeStr,
4299                             Intrinsic F32Int,
4300                             Intrinsic F64Int> {
4301 let ExeDomain = GenericDomain in {
4302   // Operation, reg.
4303   let hasSideEffects = 0 in
4304   def SSr : AVX512AIi8<opcss, MRMSrcReg,
4305       (outs FR32X:$dst), (ins FR32X:$src1, FR32X:$src2, i32i8imm:$src3),
4306       !strconcat(OpcodeStr,
4307               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4308       []>;
4309
4310   // Intrinsic operation, reg.
4311   let isCodeGenOnly = 1 in
4312   def SSr_Int : AVX512AIi8<opcss, MRMSrcReg,
4313         (outs VR128X:$dst), (ins VR128X:$src1, VR128X:$src2, i32i8imm:$src3),
4314         !strconcat(OpcodeStr,
4315                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4316         [(set VR128X:$dst, (F32Int VR128X:$src1, VR128X:$src2, imm:$src3))]>;
4317
4318   // Intrinsic operation, mem.
4319   def SSm : AVX512AIi8<opcss, MRMSrcMem, (outs VR128X:$dst),
4320                      (ins VR128X:$src1, ssmem:$src2, i32i8imm:$src3),
4321                      !strconcat(OpcodeStr,
4322                    "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4323                      [(set VR128X:$dst, (F32Int VR128X:$src1, 
4324                                          sse_load_f32:$src2, imm:$src3))]>,
4325                      EVEX_CD8<32, CD8VT1>;
4326
4327   // Operation, reg.
4328   let hasSideEffects = 0 in
4329   def SDr : AVX512AIi8<opcsd, MRMSrcReg,
4330         (outs FR64X:$dst), (ins FR64X:$src1, FR64X:$src2, i32i8imm:$src3),
4331         !strconcat(OpcodeStr,
4332                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4333         []>, VEX_W;
4334
4335   // Intrinsic operation, reg.
4336   let isCodeGenOnly = 1 in
4337   def SDr_Int : AVX512AIi8<opcsd, MRMSrcReg,
4338         (outs VR128X:$dst), (ins VR128X:$src1, VR128X:$src2, i32i8imm:$src3),
4339         !strconcat(OpcodeStr,
4340                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4341         [(set VR128X:$dst, (F64Int VR128X:$src1, VR128X:$src2, imm:$src3))]>,
4342         VEX_W;
4343
4344   // Intrinsic operation, mem.
4345   def SDm : AVX512AIi8<opcsd, MRMSrcMem,
4346         (outs VR128X:$dst), (ins VR128X:$src1, sdmem:$src2, i32i8imm:$src3),
4347         !strconcat(OpcodeStr,
4348                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4349         [(set VR128X:$dst,
4350               (F64Int VR128X:$src1, sse_load_f64:$src2, imm:$src3))]>,
4351         VEX_W, EVEX_CD8<64, CD8VT1>;
4352 } // ExeDomain = GenericDomain
4353 }
4354
4355 multiclass avx512_rndscale<bits<8> opc, string OpcodeStr,
4356                             X86MemOperand x86memop, RegisterClass RC,
4357                             PatFrag mem_frag, Domain d> {
4358 let ExeDomain = d in {
4359   // Intrinsic operation, reg.
4360   // Vector intrinsic operation, reg
4361   def r : AVX512AIi8<opc, MRMSrcReg,
4362                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
4363                     !strconcat(OpcodeStr,
4364                     " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4365                     []>, EVEX;
4366
4367   // Vector intrinsic operation, mem
4368   def m : AVX512AIi8<opc, MRMSrcMem,
4369                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
4370                     !strconcat(OpcodeStr,
4371                     " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4372                     []>, EVEX;
4373 } // ExeDomain
4374 }
4375
4376
4377 defm VRNDSCALEPSZ : avx512_rndscale<0x08, "vrndscaleps", f512mem, VR512,
4378                                 memopv16f32, SSEPackedSingle>, EVEX_V512,
4379                                 EVEX_CD8<32, CD8VF>;
4380
4381 def : Pat<(v16f32 (int_x86_avx512_mask_rndscale_ps_512 (v16f32 VR512:$src1),
4382                    imm:$src2, (v16f32 VR512:$src1), (i16 -1),
4383                    FROUND_CURRENT)),
4384                    (VRNDSCALEPSZr VR512:$src1, imm:$src2)>;
4385
4386
4387 defm VRNDSCALEPDZ : avx512_rndscale<0x09, "vrndscalepd", f512mem, VR512,
4388                                 memopv8f64, SSEPackedDouble>, EVEX_V512,
4389                                 VEX_W, EVEX_CD8<64, CD8VF>;
4390
4391 def : Pat<(v8f64 (int_x86_avx512_mask_rndscale_pd_512 (v8f64 VR512:$src1),
4392                   imm:$src2, (v8f64 VR512:$src1), (i8 -1),
4393                   FROUND_CURRENT)),
4394                    (VRNDSCALEPDZr VR512:$src1, imm:$src2)>;
4395
4396 multiclass avx512_rndscale_scalar<bits<8> opc, string OpcodeStr,
4397                      Operand x86memop, RegisterClass RC, Domain d> {
4398 let ExeDomain = d in {
4399   def r : AVX512AIi8<opc, MRMSrcReg,
4400                     (outs RC:$dst), (ins RC:$src1, RC:$src2, i32i8imm:$src3),
4401                     !strconcat(OpcodeStr,
4402                     " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4403                     []>, EVEX_4V;
4404
4405   def m : AVX512AIi8<opc, MRMSrcMem,
4406                     (outs RC:$dst), (ins RC:$src1, x86memop:$src2,  i32i8imm:$src3),
4407                     !strconcat(OpcodeStr,
4408                     " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4409                     []>, EVEX_4V;
4410 } // ExeDomain
4411 }
4412
4413 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", ssmem, FR32X,
4414                                 SSEPackedSingle>, EVEX_CD8<32, CD8VT1>;
4415                                 
4416 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", sdmem, FR64X,
4417                                 SSEPackedDouble>, EVEX_CD8<64, CD8VT1>;
4418
4419 def : Pat<(ffloor FR32X:$src),
4420           (VRNDSCALESSr (f32 (IMPLICIT_DEF)), FR32X:$src, (i32 0x1))>;
4421 def : Pat<(f64 (ffloor FR64X:$src)),
4422           (VRNDSCALESDr (f64 (IMPLICIT_DEF)), FR64X:$src, (i32 0x1))>;
4423 def : Pat<(f32 (fnearbyint FR32X:$src)),
4424           (VRNDSCALESSr (f32 (IMPLICIT_DEF)), FR32X:$src, (i32 0xC))>;
4425 def : Pat<(f64 (fnearbyint FR64X:$src)),
4426           (VRNDSCALESDr (f64 (IMPLICIT_DEF)), FR64X:$src, (i32 0xC))>;
4427 def : Pat<(f32 (fceil FR32X:$src)),
4428           (VRNDSCALESSr (f32 (IMPLICIT_DEF)), FR32X:$src, (i32 0x2))>;
4429 def : Pat<(f64 (fceil FR64X:$src)),
4430           (VRNDSCALESDr (f64 (IMPLICIT_DEF)), FR64X:$src, (i32 0x2))>;
4431 def : Pat<(f32 (frint FR32X:$src)),
4432           (VRNDSCALESSr (f32 (IMPLICIT_DEF)), FR32X:$src, (i32 0x4))>;
4433 def : Pat<(f64 (frint FR64X:$src)),
4434           (VRNDSCALESDr (f64 (IMPLICIT_DEF)), FR64X:$src, (i32 0x4))>;
4435 def : Pat<(f32 (ftrunc FR32X:$src)),
4436           (VRNDSCALESSr (f32 (IMPLICIT_DEF)), FR32X:$src, (i32 0x3))>;
4437 def : Pat<(f64 (ftrunc FR64X:$src)),
4438           (VRNDSCALESDr (f64 (IMPLICIT_DEF)), FR64X:$src, (i32 0x3))>;
4439
4440 def : Pat<(v16f32 (ffloor VR512:$src)),
4441           (VRNDSCALEPSZr VR512:$src, (i32 0x1))>;
4442 def : Pat<(v16f32 (fnearbyint VR512:$src)),
4443           (VRNDSCALEPSZr VR512:$src, (i32 0xC))>;
4444 def : Pat<(v16f32 (fceil VR512:$src)),
4445           (VRNDSCALEPSZr VR512:$src, (i32 0x2))>;
4446 def : Pat<(v16f32 (frint VR512:$src)),
4447           (VRNDSCALEPSZr VR512:$src, (i32 0x4))>;
4448 def : Pat<(v16f32 (ftrunc VR512:$src)),
4449           (VRNDSCALEPSZr VR512:$src, (i32 0x3))>;
4450
4451 def : Pat<(v8f64 (ffloor VR512:$src)),
4452           (VRNDSCALEPDZr VR512:$src, (i32 0x1))>;
4453 def : Pat<(v8f64 (fnearbyint VR512:$src)),
4454           (VRNDSCALEPDZr VR512:$src, (i32 0xC))>;
4455 def : Pat<(v8f64 (fceil VR512:$src)),
4456           (VRNDSCALEPDZr VR512:$src, (i32 0x2))>;
4457 def : Pat<(v8f64 (frint VR512:$src)),
4458           (VRNDSCALEPDZr VR512:$src, (i32 0x4))>;
4459 def : Pat<(v8f64 (ftrunc VR512:$src)),
4460           (VRNDSCALEPDZr VR512:$src, (i32 0x3))>;
4461
4462 //-------------------------------------------------
4463 // Integer truncate and extend operations
4464 //-------------------------------------------------
4465
4466 multiclass avx512_trunc_sat<bits<8> opc, string OpcodeStr,
4467                           RegisterClass dstRC, RegisterClass srcRC,
4468                           RegisterClass KRC, X86MemOperand x86memop> {
4469   def rr : AVX512XS8I<opc, MRMDestReg, (outs dstRC:$dst),
4470                (ins srcRC:$src),
4471                !strconcat(OpcodeStr," \t{$src, $dst|$dst, $src}"),
4472                []>, EVEX;
4473
4474   def rrk : AVX512XS8I<opc, MRMDestReg, (outs dstRC:$dst),
4475                (ins KRC:$mask, srcRC:$src),
4476                !strconcat(OpcodeStr,
4477                  " \t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
4478                []>, EVEX, EVEX_K;
4479
4480   def rrkz : AVX512XS8I<opc, MRMDestReg, (outs dstRC:$dst),
4481                (ins KRC:$mask, srcRC:$src),
4482                !strconcat(OpcodeStr,
4483                  " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
4484                []>, EVEX, EVEX_KZ;
4485
4486   def mr : AVX512XS8I<opc, MRMDestMem, (outs), (ins x86memop:$dst, srcRC:$src),
4487                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
4488                []>, EVEX;
4489
4490   def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
4491                (ins x86memop:$dst, KRC:$mask, srcRC:$src),
4492                !strconcat(OpcodeStr, " \t{$src, $dst {${mask}}|${dst} {${mask}}, $src}"),
4493                []>, EVEX, EVEX_K;
4494
4495 }
4496 defm VPMOVQB    : avx512_trunc_sat<0x32, "vpmovqb",   VR128X, VR512, VK8WM, 
4497                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VO>;
4498 defm VPMOVSQB   : avx512_trunc_sat<0x22, "vpmovsqb",  VR128X, VR512, VK8WM,
4499                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VO>;
4500 defm VPMOVUSQB  : avx512_trunc_sat<0x12, "vpmovusqb", VR128X, VR512, VK8WM,
4501                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VO>;
4502 defm VPMOVQW    : avx512_trunc_sat<0x34, "vpmovqw",   VR128X, VR512, VK8WM,
4503                                  i128mem>, EVEX_V512, EVEX_CD8<16, CD8VQ>;
4504 defm VPMOVSQW   : avx512_trunc_sat<0x24, "vpmovsqw",  VR128X, VR512, VK8WM,
4505                                  i128mem>, EVEX_V512, EVEX_CD8<16, CD8VQ>;
4506 defm VPMOVUSQW  : avx512_trunc_sat<0x14, "vpmovusqw", VR128X, VR512, VK8WM,
4507                                  i128mem>, EVEX_V512, EVEX_CD8<16, CD8VQ>;
4508 defm VPMOVQD    : avx512_trunc_sat<0x35, "vpmovqd",   VR256X, VR512, VK8WM,
4509                                  i256mem>, EVEX_V512, EVEX_CD8<32, CD8VH>;
4510 defm VPMOVSQD   : avx512_trunc_sat<0x25, "vpmovsqd",  VR256X, VR512, VK8WM,
4511                                  i256mem>, EVEX_V512, EVEX_CD8<32, CD8VH>;
4512 defm VPMOVUSQD  : avx512_trunc_sat<0x15, "vpmovusqd", VR256X, VR512, VK8WM,
4513                                  i256mem>, EVEX_V512, EVEX_CD8<32, CD8VH>;
4514 defm VPMOVDW    : avx512_trunc_sat<0x33, "vpmovdw",   VR256X, VR512, VK16WM,
4515                                  i256mem>, EVEX_V512, EVEX_CD8<16, CD8VH>;
4516 defm VPMOVSDW   : avx512_trunc_sat<0x23, "vpmovsdw",  VR256X, VR512, VK16WM,
4517                                  i256mem>, EVEX_V512, EVEX_CD8<16, CD8VH>;
4518 defm VPMOVUSDW  : avx512_trunc_sat<0x13, "vpmovusdw", VR256X, VR512, VK16WM,
4519                                  i256mem>, EVEX_V512, EVEX_CD8<16, CD8VH>;
4520 defm VPMOVDB    : avx512_trunc_sat<0x31, "vpmovdb",   VR128X, VR512, VK16WM,
4521                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VQ>;
4522 defm VPMOVSDB   : avx512_trunc_sat<0x21, "vpmovsdb",  VR128X, VR512, VK16WM,
4523                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VQ>;
4524 defm VPMOVUSDB  : avx512_trunc_sat<0x11, "vpmovusdb", VR128X, VR512, VK16WM,
4525                                  i128mem>, EVEX_V512, EVEX_CD8<8, CD8VQ>;
4526
4527 def : Pat<(v16i8  (X86vtrunc (v8i64  VR512:$src))), (VPMOVQBrr  VR512:$src)>;
4528 def : Pat<(v8i16  (X86vtrunc (v8i64  VR512:$src))), (VPMOVQWrr  VR512:$src)>;
4529 def : Pat<(v16i16 (X86vtrunc (v16i32 VR512:$src))), (VPMOVDWrr  VR512:$src)>;
4530 def : Pat<(v16i8  (X86vtrunc (v16i32 VR512:$src))), (VPMOVDBrr  VR512:$src)>;
4531 def : Pat<(v8i32  (X86vtrunc (v8i64  VR512:$src))), (VPMOVQDrr  VR512:$src)>;
4532
4533 def : Pat<(v16i8  (X86vtruncm VK16WM:$mask, (v16i32 VR512:$src))),
4534                   (VPMOVDBrrkz VK16WM:$mask, VR512:$src)>;
4535 def : Pat<(v16i16 (X86vtruncm VK16WM:$mask, (v16i32 VR512:$src))),
4536                   (VPMOVDWrrkz VK16WM:$mask, VR512:$src)>;
4537 def : Pat<(v8i16  (X86vtruncm VK8WM:$mask,  (v8i64 VR512:$src))),
4538                   (VPMOVQWrrkz  VK8WM:$mask, VR512:$src)>;
4539 def : Pat<(v8i32  (X86vtruncm VK8WM:$mask,  (v8i64 VR512:$src))),
4540                   (VPMOVQDrrkz  VK8WM:$mask, VR512:$src)>;
4541
4542
4543 multiclass avx512_extend<bits<8> opc, string OpcodeStr, RegisterClass KRC,
4544                       RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode,
4545                       PatFrag mem_frag, X86MemOperand x86memop,
4546                       ValueType OpVT, ValueType InVT> {
4547
4548   def rr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst),
4549               (ins SrcRC:$src),
4550               !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
4551               [(set DstRC:$dst, (OpVT (OpNode (InVT SrcRC:$src))))]>, EVEX;
4552
4553   def rrk : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst),
4554               (ins KRC:$mask, SrcRC:$src),
4555               !strconcat(OpcodeStr, " \t{$src, $dst {${mask}} |$dst {${mask}}, $src}"),
4556               []>, EVEX, EVEX_K;
4557
4558   def rrkz : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst),
4559               (ins KRC:$mask, SrcRC:$src),
4560               !strconcat(OpcodeStr, " \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
4561               []>, EVEX, EVEX_KZ;
4562
4563   let mayLoad = 1 in {
4564     def rm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst),
4565               (ins x86memop:$src),
4566               !strconcat(OpcodeStr," \t{$src, $dst|$dst, $src}"),
4567               [(set DstRC:$dst,
4568                 (OpVT (OpNode (InVT (bitconvert (mem_frag addr:$src))))))]>,
4569               EVEX;
4570
4571     def rmk : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst),
4572               (ins KRC:$mask, x86memop:$src),
4573               !strconcat(OpcodeStr," \t{$src, $dst {${mask}} |$dst {${mask}}, $src}"),
4574               []>,
4575               EVEX, EVEX_K;
4576
4577     def rmkz : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst),
4578               (ins KRC:$mask, x86memop:$src),
4579               !strconcat(OpcodeStr," \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
4580               []>,
4581               EVEX, EVEX_KZ;
4582   }
4583 }
4584
4585 defm VPMOVZXBDZ: avx512_extend<0x31, "vpmovzxbd", VK16WM, VR512, VR128X, X86vzext,
4586                              memopv2i64, i128mem, v16i32, v16i8>, EVEX_V512,
4587                              EVEX_CD8<8, CD8VQ>;
4588 defm VPMOVZXBQZ: avx512_extend<0x32, "vpmovzxbq", VK8WM, VR512, VR128X, X86vzext,
4589                              memopv2i64, i128mem, v8i64, v16i8>, EVEX_V512,
4590                              EVEX_CD8<8, CD8VO>;
4591 defm VPMOVZXWDZ: avx512_extend<0x33, "vpmovzxwd", VK16WM, VR512, VR256X, X86vzext,
4592                              memopv4i64, i256mem, v16i32, v16i16>, EVEX_V512,
4593                              EVEX_CD8<16, CD8VH>;
4594 defm VPMOVZXWQZ: avx512_extend<0x34, "vpmovzxwq", VK8WM, VR512, VR128X, X86vzext,
4595                              memopv2i64, i128mem, v8i64, v8i16>, EVEX_V512,
4596                              EVEX_CD8<16, CD8VQ>;
4597 defm VPMOVZXDQZ: avx512_extend<0x35, "vpmovzxdq", VK8WM, VR512, VR256X, X86vzext,
4598                              memopv4i64, i256mem, v8i64, v8i32>, EVEX_V512,
4599                              EVEX_CD8<32, CD8VH>;
4600
4601 defm VPMOVSXBDZ: avx512_extend<0x21, "vpmovsxbd", VK16WM, VR512, VR128X, X86vsext,
4602                              memopv2i64, i128mem, v16i32, v16i8>, EVEX_V512,
4603                              EVEX_CD8<8, CD8VQ>;
4604 defm VPMOVSXBQZ: avx512_extend<0x22, "vpmovsxbq", VK8WM, VR512, VR128X, X86vsext,
4605                              memopv2i64, i128mem, v8i64, v16i8>, EVEX_V512,
4606                              EVEX_CD8<8, CD8VO>;
4607 defm VPMOVSXWDZ: avx512_extend<0x23, "vpmovsxwd", VK16WM, VR512, VR256X, X86vsext,
4608                              memopv4i64, i256mem, v16i32, v16i16>, EVEX_V512,
4609                              EVEX_CD8<16, CD8VH>;
4610 defm VPMOVSXWQZ: avx512_extend<0x24, "vpmovsxwq", VK8WM, VR512, VR128X, X86vsext,
4611                              memopv2i64, i128mem, v8i64, v8i16>, EVEX_V512,
4612                              EVEX_CD8<16, CD8VQ>;
4613 defm VPMOVSXDQZ: avx512_extend<0x25, "vpmovsxdq", VK8WM, VR512, VR256X, X86vsext,
4614                              memopv4i64, i256mem, v8i64, v8i32>, EVEX_V512,
4615                              EVEX_CD8<32, CD8VH>;
4616
4617 //===----------------------------------------------------------------------===//
4618 // GATHER - SCATTER Operations
4619
4620 multiclass avx512_gather<bits<8> opc, string OpcodeStr, RegisterClass KRC,
4621                        RegisterClass RC, X86MemOperand memop> {
4622 let mayLoad = 1,
4623   Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb" in
4624   def rm  : AVX5128I<opc, MRMSrcMem, (outs RC:$dst, KRC:$mask_wb),
4625             (ins RC:$src1, KRC:$mask, memop:$src2),
4626             !strconcat(OpcodeStr,
4627             " \t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
4628             []>, EVEX, EVEX_K;
4629 }
4630
4631 let ExeDomain = SSEPackedDouble in {
4632 defm VGATHERDPDZ : avx512_gather<0x92, "vgatherdpd", VK8WM, VR512, vy64xmem>,
4633                                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4634 defm VGATHERQPDZ : avx512_gather<0x93, "vgatherqpd", VK8WM, VR512, vz64mem>,
4635                                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4636 }
4637
4638 let ExeDomain = SSEPackedSingle in {
4639 defm VGATHERDPSZ : avx512_gather<0x92, "vgatherdps", VK16WM, VR512, vz32mem>,
4640                                  EVEX_V512, EVEX_CD8<32, CD8VT1>;
4641 defm VGATHERQPSZ : avx512_gather<0x93, "vgatherqps", VK8WM, VR256X, vz64mem>,
4642                                  EVEX_V512, EVEX_CD8<32, CD8VT1>;
4643 }
4644   
4645 defm VPGATHERDQZ : avx512_gather<0x90, "vpgatherdq", VK8WM, VR512,  vy64xmem>,
4646                                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4647 defm VPGATHERDDZ : avx512_gather<0x90, "vpgatherdd", VK16WM, VR512, vz32mem>,
4648                                  EVEX_V512, EVEX_CD8<32, CD8VT1>;
4649
4650 defm VPGATHERQQZ : avx512_gather<0x91, "vpgatherqq", VK8WM, VR512,  vz64mem>,
4651                                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4652 defm VPGATHERQDZ : avx512_gather<0x91, "vpgatherqd", VK8WM, VR256X,  vz64mem>,
4653                                  EVEX_V512, EVEX_CD8<32, CD8VT1>;
4654
4655 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, RegisterClass KRC,
4656                        RegisterClass RC, X86MemOperand memop> {
4657 let mayStore = 1, Constraints = "$mask = $mask_wb" in
4658   def mr  : AVX5128I<opc, MRMDestMem, (outs KRC:$mask_wb),
4659             (ins memop:$dst, KRC:$mask, RC:$src2),
4660             !strconcat(OpcodeStr,
4661             " \t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
4662             []>, EVEX, EVEX_K;
4663 }
4664
4665 let ExeDomain = SSEPackedDouble in {
4666 defm VSCATTERDPDZ : avx512_scatter<0xA2, "vscatterdpd", VK8WM, VR512, vy64xmem>,
4667                                    EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4668 defm VSCATTERQPDZ : avx512_scatter<0xA3, "vscatterqpd", VK8WM, VR512, vz64mem>,
4669                                    EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4670 }
4671
4672 let ExeDomain = SSEPackedSingle in {
4673 defm VSCATTERDPSZ : avx512_scatter<0xA2, "vscatterdps", VK16WM, VR512, vz32mem>,
4674                                    EVEX_V512, EVEX_CD8<32, CD8VT1>;
4675 defm VSCATTERQPSZ : avx512_scatter<0xA3, "vscatterqps", VK8WM, VR256X, vz64mem>,
4676                                    EVEX_V512, EVEX_CD8<32, CD8VT1>;
4677 }
4678
4679 defm VPSCATTERDQZ : avx512_scatter<0xA0, "vpscatterdq", VK8WM, VR512, vy64xmem>,
4680                                    EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4681 defm VPSCATTERDDZ : avx512_scatter<0xA0, "vpscatterdd", VK16WM, VR512, vz32mem>,
4682                                    EVEX_V512, EVEX_CD8<32, CD8VT1>;
4683
4684 defm VPSCATTERQQZ : avx512_scatter<0xA1, "vpscatterqq", VK8WM, VR512, vz64mem>,
4685                                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4686 defm VPSCATTERQDZ : avx512_scatter<0xA1, "vpscatterqd", VK8WM, VR256X, vz64mem>,
4687                                   EVEX_V512, EVEX_CD8<32, CD8VT1>;
4688
4689 // prefetch
4690 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
4691                        RegisterClass KRC, X86MemOperand memop> {
4692   let Predicates = [HasPFI], hasSideEffects = 1 in
4693   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
4694             !strconcat(OpcodeStr, " \t{$src {${mask}}|{${mask}}, $src}"),
4695             []>, EVEX, EVEX_K;
4696 }
4697
4698 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
4699                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
4700
4701 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
4702                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
4703
4704 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
4705                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
4706
4707 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
4708                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4709                      
4710 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
4711                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
4712
4713 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
4714                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
4715
4716 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
4717                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
4718
4719 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
4720                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4721
4722 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
4723                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
4724
4725 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
4726                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
4727
4728 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
4729                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
4730
4731 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
4732                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4733
4734 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
4735                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
4736
4737 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
4738                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
4739
4740 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
4741                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
4742
4743 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
4744                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
4745 //===----------------------------------------------------------------------===//
4746 // VSHUFPS - VSHUFPD Operations
4747
4748 multiclass avx512_shufp<RegisterClass RC, X86MemOperand x86memop,
4749                       ValueType vt, string OpcodeStr, PatFrag mem_frag,
4750                       Domain d> {
4751   def rmi : AVX512PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
4752                    (ins RC:$src1, x86memop:$src2, i8imm:$src3),
4753                    !strconcat(OpcodeStr,
4754                    " \t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4755                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
4756                                        (i8 imm:$src3))))], d, IIC_SSE_SHUFP>,
4757                    EVEX_4V, Sched<[WriteShuffleLd, ReadAfterLd]>;
4758   def rri : AVX512PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
4759                    (ins RC:$src1, RC:$src2, i8imm:$src3),
4760                    !strconcat(OpcodeStr,
4761                    " \t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4762                    [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
4763                                        (i8 imm:$src3))))], d, IIC_SSE_SHUFP>,
4764                    EVEX_4V, Sched<[WriteShuffle]>;
4765 }
4766
4767 defm VSHUFPSZ  : avx512_shufp<VR512, f512mem, v16f32, "vshufps", memopv16f32,
4768                   SSEPackedSingle>, PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
4769 defm VSHUFPDZ  : avx512_shufp<VR512, f512mem, v8f64, "vshufpd", memopv8f64,
4770                   SSEPackedDouble>, PD, VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4771
4772 def : Pat<(v16i32 (X86Shufp VR512:$src1, VR512:$src2, (i8 imm:$imm))),
4773           (VSHUFPSZrri VR512:$src1, VR512:$src2, imm:$imm)>;
4774 def : Pat<(v16i32 (X86Shufp VR512:$src1,
4775                     (memopv16i32 addr:$src2), (i8 imm:$imm))),
4776           (VSHUFPSZrmi VR512:$src1, addr:$src2, imm:$imm)>;
4777
4778 def : Pat<(v8i64 (X86Shufp VR512:$src1, VR512:$src2, (i8 imm:$imm))),
4779           (VSHUFPDZrri VR512:$src1, VR512:$src2, imm:$imm)>;
4780 def : Pat<(v8i64 (X86Shufp VR512:$src1,
4781                             (memopv8i64 addr:$src2), (i8 imm:$imm))),
4782           (VSHUFPDZrmi VR512:$src1, addr:$src2, imm:$imm)>;
4783
4784 multiclass avx512_valign<X86VectorVTInfo _> {
4785   defm rri : AVX512_masking<0x03, MRMSrcReg, _, (outs _.RC:$dst),
4786                      (ins _.RC:$src1, _.RC:$src2, i8imm:$src3),
4787                      "valign"##_.Suffix,
4788                      "$src3, $src2, $src1", "$src1, $src2, $src3",
4789                      (_.VT (X86VAlign _.RC:$src2, _.RC:$src1,
4790                                       (i8 imm:$src3)))>,
4791              AVX512AIi8Base, EVEX_4V;
4792
4793   // Also match valign of packed floats.
4794   def : Pat<(_.FloatVT (X86VAlign _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
4795             (!cast<Instruction>(NAME##rri) _.RC:$src2, _.RC:$src1, imm:$imm)>;
4796
4797   let mayLoad = 1 in
4798   def rmi : AVX512AIi8<0x03, MRMSrcMem, (outs _.RC:$dst),
4799                      (ins _.RC:$src1, _.MemOp:$src2, i8imm:$src3),
4800                      !strconcat("valign"##_.Suffix,
4801                      " \t{$src3, $src2, $src1, $dst|"
4802                          "$dst, $src1, $src2, $src3}"),
4803                      []>, EVEX_4V;
4804 }
4805 defm VALIGND : avx512_valign<v16i32_info>, EVEX_V512, EVEX_CD8<32, CD8VF>;
4806 defm VALIGNQ : avx512_valign<v8i64_info>, VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4807
4808 // Helper fragments to match sext vXi1 to vXiY.
4809 def v16i1sextv16i32  : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
4810 def v8i1sextv8i64  : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
4811
4812 multiclass avx512_vpabs<bits<8> opc, string OpcodeStr, ValueType OpVT,
4813                         RegisterClass KRC, RegisterClass RC,
4814                         X86MemOperand x86memop, X86MemOperand x86scalar_mop,
4815                         string BrdcstStr> {
4816   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4817             !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
4818             []>, EVEX;
4819   def rrk : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src),
4820              !strconcat(OpcodeStr, " \t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
4821              []>, EVEX, EVEX_K;
4822   def rrkz : AVX5128I<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src),
4823               !strconcat(OpcodeStr,
4824                          " \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
4825               []>, EVEX, EVEX_KZ;
4826   let mayLoad = 1 in {
4827     def rm : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4828               (ins x86memop:$src),
4829               !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
4830               []>, EVEX;
4831     def rmk : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4832                (ins KRC:$mask, x86memop:$src),
4833                !strconcat(OpcodeStr,
4834                           " \t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
4835                []>, EVEX, EVEX_K;
4836     def rmkz : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4837                 (ins KRC:$mask, x86memop:$src),
4838                 !strconcat(OpcodeStr,
4839                            " \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
4840                 []>, EVEX, EVEX_KZ;
4841     def rmb : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4842                (ins x86scalar_mop:$src),
4843                !strconcat(OpcodeStr, " \t{${src}", BrdcstStr,
4844                           ", $dst|$dst, ${src}", BrdcstStr, "}"),
4845                []>, EVEX, EVEX_B;
4846     def rmbk : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4847                 (ins KRC:$mask, x86scalar_mop:$src),
4848                 !strconcat(OpcodeStr, " \t{${src}", BrdcstStr,
4849                            ", $dst {${mask}}|$dst {${mask}}, ${src}", BrdcstStr, "}"),
4850                 []>, EVEX, EVEX_B, EVEX_K;
4851     def rmbkz : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst),
4852                  (ins KRC:$mask, x86scalar_mop:$src),
4853                  !strconcat(OpcodeStr, " \t{${src}", BrdcstStr,
4854                             ", $dst {${mask}} {z}|$dst {${mask}} {z}, ${src}",
4855                             BrdcstStr, "}"),
4856                  []>, EVEX, EVEX_B, EVEX_KZ;
4857   }
4858 }
4859
4860 defm VPABSDZ : avx512_vpabs<0x1E, "vpabsd", v16i32, VK16WM, VR512,
4861                            i512mem, i32mem, "{1to16}">, EVEX_V512,
4862                            EVEX_CD8<32, CD8VF>;
4863 defm VPABSQZ : avx512_vpabs<0x1F, "vpabsq", v8i64, VK8WM, VR512,
4864                            i512mem, i64mem, "{1to8}">, EVEX_V512, VEX_W,
4865                            EVEX_CD8<64, CD8VF>;
4866
4867 def : Pat<(xor
4868           (bc_v16i32 (v16i1sextv16i32)),
4869           (bc_v16i32 (add (v16i32 VR512:$src), (v16i1sextv16i32)))),
4870           (VPABSDZrr VR512:$src)>;
4871 def : Pat<(xor
4872           (bc_v8i64 (v8i1sextv8i64)),
4873           (bc_v8i64 (add (v8i64 VR512:$src), (v8i1sextv8i64)))),
4874           (VPABSQZrr VR512:$src)>;
4875
4876 def : Pat<(v16i32 (int_x86_avx512_mask_pabs_d_512 (v16i32 VR512:$src),
4877                    (v16i32 immAllZerosV), (i16 -1))),
4878           (VPABSDZrr VR512:$src)>;
4879 def : Pat<(v8i64 (int_x86_avx512_mask_pabs_q_512 (v8i64 VR512:$src),
4880                    (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
4881           (VPABSQZrr VR512:$src)>;
4882
4883 multiclass avx512_conflict<bits<8> opc, string OpcodeStr, 
4884                         RegisterClass RC, RegisterClass KRC,
4885                         X86MemOperand x86memop,
4886                         X86MemOperand x86scalar_mop, string BrdcstStr> {
4887   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
4888        (ins RC:$src),
4889        !strconcat(OpcodeStr, " \t{$src, ${dst} |${dst}, $src}"),
4890        []>, EVEX;
4891   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4892        (ins x86memop:$src),
4893        !strconcat(OpcodeStr, " \t{$src, ${dst}|${dst}, $src}"),
4894        []>, EVEX;
4895   def rmb : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4896        (ins x86scalar_mop:$src),
4897        !strconcat(OpcodeStr, " \t{${src}", BrdcstStr,
4898                   ", ${dst}|${dst}, ${src}", BrdcstStr, "}"),
4899        []>, EVEX, EVEX_B;
4900   def rrkz : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
4901        (ins KRC:$mask, RC:$src),
4902        !strconcat(OpcodeStr,
4903                   " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
4904        []>, EVEX, EVEX_KZ;
4905   def rmkz : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4906        (ins KRC:$mask, x86memop:$src),
4907        !strconcat(OpcodeStr,
4908                   " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
4909        []>, EVEX, EVEX_KZ;
4910   def rmbkz : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4911        (ins KRC:$mask, x86scalar_mop:$src),
4912        !strconcat(OpcodeStr, " \t{${src}", BrdcstStr,
4913                   ", ${dst} {${mask}} {z}|${dst} {${mask}} {z}, ${src}",
4914                   BrdcstStr, "}"),
4915        []>, EVEX, EVEX_KZ, EVEX_B;
4916        
4917   let Constraints = "$src1 = $dst" in {
4918   def rrk : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
4919        (ins RC:$src1, KRC:$mask, RC:$src2),
4920        !strconcat(OpcodeStr,
4921                   " \t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
4922        []>, EVEX, EVEX_K;
4923   def rmk : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4924        (ins RC:$src1, KRC:$mask, x86memop:$src2),
4925        !strconcat(OpcodeStr,
4926                   " \t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
4927        []>, EVEX, EVEX_K;
4928   def rmbk : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
4929        (ins RC:$src1, KRC:$mask, x86scalar_mop:$src2),
4930        !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
4931                   ", ${dst} {${mask}}|${dst} {${mask}}, ${src2}", BrdcstStr, "}"),
4932        []>, EVEX, EVEX_K, EVEX_B;
4933    }
4934 }
4935
4936 let Predicates = [HasCDI] in {
4937 defm VPCONFLICTD : avx512_conflict<0xC4, "vpconflictd", VR512, VK16WM,
4938                     i512mem, i32mem, "{1to16}">,
4939                     EVEX_V512, EVEX_CD8<32, CD8VF>;
4940
4941
4942 defm VPCONFLICTQ : avx512_conflict<0xC4, "vpconflictq", VR512, VK8WM,
4943                     i512mem, i64mem, "{1to8}">,
4944                     EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
4945
4946 }
4947
4948 def : Pat<(int_x86_avx512_mask_conflict_d_512 VR512:$src2, VR512:$src1,
4949                                               GR16:$mask),
4950           (VPCONFLICTDrrk VR512:$src1,
4951            (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), VR512:$src2)>;
4952
4953 def : Pat<(int_x86_avx512_mask_conflict_q_512 VR512:$src2, VR512:$src1,
4954                                               GR8:$mask),
4955           (VPCONFLICTQrrk VR512:$src1,
4956            (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), VR512:$src2)>;
4957
4958 let Predicates = [HasCDI] in {
4959 defm VPLZCNTD : avx512_conflict<0x44, "vplzcntd", VR512, VK16WM,
4960                     i512mem, i32mem, "{1to16}">,
4961                     EVEX_V512, EVEX_CD8<32, CD8VF>;
4962
4963
4964 defm VPLZCNTQ : avx512_conflict<0x44, "vplzcntq", VR512, VK8WM,
4965                     i512mem, i64mem, "{1to8}">,
4966                     EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
4967
4968 }
4969
4970 def : Pat<(int_x86_avx512_mask_lzcnt_d_512 VR512:$src2, VR512:$src1,
4971                                               GR16:$mask),
4972           (VPLZCNTDrrk VR512:$src1,
4973            (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), VR512:$src2)>;
4974
4975 def : Pat<(int_x86_avx512_mask_lzcnt_q_512 VR512:$src2, VR512:$src1,
4976                                               GR8:$mask),
4977           (VPLZCNTQrrk VR512:$src1,
4978            (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), VR512:$src2)>;
4979
4980 def : Pat<(v16i32 (ctlz (memopv16i32 addr:$src))),
4981           (VPLZCNTDrm addr:$src)>;
4982 def : Pat<(v16i32 (ctlz (v16i32 VR512:$src))),
4983           (VPLZCNTDrr VR512:$src)>;
4984 def : Pat<(v8i64 (ctlz (memopv8i64 addr:$src))),
4985           (VPLZCNTQrm addr:$src)>;
4986 def : Pat<(v8i64 (ctlz (v8i64 VR512:$src))),
4987           (VPLZCNTQrr VR512:$src)>;
4988
4989 def : Pat<(store (i1 -1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
4990 def : Pat<(store (i1  1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
4991 def : Pat<(store (i1  0), addr:$dst), (MOV8mi addr:$dst, (i8 0))>;
4992
4993 def : Pat<(store VK1:$src, addr:$dst),
4994           (KMOVWmk addr:$dst, (COPY_TO_REGCLASS VK1:$src, VK16))>;
4995
4996 def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
4997                            (truncstore node:$val, node:$ptr), [{
4998   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
4999 }]>;
5000
5001 def : Pat<(truncstorei1 GR8:$src, addr:$dst),
5002           (MOV8mr addr:$dst, GR8:$src)>;
5003
5004 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
5005 def rr : AVX512XS8I<opc, MRMDestReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
5006                   !strconcat(OpcodeStr##Vec.Suffix, " \t{$src, $dst|$dst, $src}"),
5007                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
5008 }
5009           
5010 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
5011                                  string OpcodeStr, Predicate prd> {
5012 let Predicates = [prd] in
5013   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
5014
5015   let Predicates = [prd, HasVLX] in {
5016     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
5017     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
5018   }
5019 }
5020
5021 multiclass avx512_convert_mask_to_vector<string OpcodeStr> {
5022   defm NAME##B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info,  OpcodeStr,
5023                                        HasBWI>;
5024   defm NAME##W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, OpcodeStr,
5025                                        HasBWI>, VEX_W;
5026   defm NAME##D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, OpcodeStr,
5027                                        HasDQI>;
5028   defm NAME##Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, OpcodeStr,
5029                                        HasDQI>, VEX_W;
5030 }
5031           
5032 defm VPMOVM2 : avx512_convert_mask_to_vector<"vpmovm2">;