3c9bcf64848c28a74126421a6368304a9046e531
[oota-llvm.git] / lib / Target / X86 / X86InstrAVX512.td
1 //===-- X86InstrAVX512.td - AVX512 Instruction Set ---------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 AVX512 instruction set, defining the
11 // instructions, and properties of the instructions which are needed for code
12 // generation, machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16 // Group template arguments that can be derived from the vector type (EltNum x
17 // EltVT).  These are things like the register class for the writemask, etc.
18 // The idea is to pass one of these as the template argument rather than the
19 // individual arguments.
20 // The template is also used for scalar types, in this case numelts is 1.
21 class X86VectorVTInfo<int numelts, ValueType eltvt, RegisterClass rc,
22                       string suffix = ""> {
23   RegisterClass RC = rc;
24   ValueType EltVT = eltvt;
25   int NumElts = numelts;
26
27   // Corresponding mask register class.
28   RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
29
30   // Corresponding write-mask register class.
31   RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
32
33   // The GPR register class that can hold the write mask.  Use GR8 for fewer
34   // than 8 elements.  Use shift-right and equal to work around the lack of
35   // !lt in tablegen.
36   RegisterClass MRC =
37     !cast<RegisterClass>("GR" #
38                          !if (!eq (!srl(NumElts, 3), 0), 8, NumElts));
39
40   // Suffix used in the instruction mnemonic.
41   string Suffix = suffix;
42
43   // VTName is a string name for vector VT. For vector types it will be
44   // v # NumElts # EltVT, so for vector of 8 elements of i32 it will be v8i32
45   // It is a little bit complex for scalar types, where NumElts = 1.
46   // In this case we build v4f32 or v2f64
47   string VTName = "v" # !if (!eq (NumElts, 1),
48                         !if (!eq (EltVT.Size, 32), 4,
49                         !if (!eq (EltVT.Size, 64), 2, NumElts)), NumElts) # EltVT;
50
51   // The vector VT.
52   ValueType VT = !cast<ValueType>(VTName);
53
54   string EltTypeName = !cast<string>(EltVT);
55   // Size of the element type in bits, e.g. 32 for v16i32.
56   string EltSizeName = !subst("i", "", !subst("f", "", EltTypeName));
57   int EltSize = EltVT.Size;
58
59   // "i" for integer types and "f" for floating-point types
60   string TypeVariantName = !subst(EltSizeName, "", EltTypeName);
61
62   // Size of RC in bits, e.g. 512 for VR512.
63   int Size = VT.Size;
64
65   // The corresponding memory operand, e.g. i512mem for VR512.
66   X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
67   X86MemOperand ScalarMemOp = !cast<X86MemOperand>(EltVT # "mem");
68
69   // Load patterns
70   // Note: For 128/256-bit integer VT we choose loadv2i64/loadv4i64
71   //       due to load promotion during legalization
72   PatFrag LdFrag = !cast<PatFrag>("load" #
73                                   !if (!eq (TypeVariantName, "i"),
74                                        !if (!eq (Size, 128), "v2i64",
75                                        !if (!eq (Size, 256), "v4i64",
76                                             VTName)), VTName));
77
78   PatFrag AlignedLdFrag = !cast<PatFrag>("alignedload" #
79                           !if (!eq (TypeVariantName, "i"),
80                                 !if (!eq (Size, 128), "v2i64",
81                                 !if (!eq (Size, 256), "v4i64",
82                                 !if (!eq (Size, 512),
83                                     !if (!eq (EltSize, 64), "v8i64", "v16i32"),
84                                     VTName))), VTName));
85
86   PatFrag ScalarLdFrag = !cast<PatFrag>("load" # EltVT);
87
88   // The corresponding float type, e.g. v16f32 for v16i32
89   // Note: For EltSize < 32, FloatVT is illegal and TableGen
90   //       fails to compile, so we choose FloatVT = VT
91   ValueType FloatVT = !cast<ValueType>(
92                         !if (!eq (!srl(EltSize,5),0),
93                              VTName,
94                              !if (!eq(TypeVariantName, "i"),
95                                   "v" # NumElts # "f" # EltSize,
96                                   VTName)));
97
98   // The string to specify embedded broadcast in assembly.
99   string BroadcastStr = "{1to" # NumElts # "}";
100
101   // 8-bit compressed displacement tuple/subvector format.  This is only
102   // defined for NumElts <= 8.
103   CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0),
104                                !cast<CD8VForm>("CD8VT" # NumElts), ?);
105
106   SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
107                           !if (!eq (Size, 256), sub_ymm, ?));
108
109   Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
110                      !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
111                      SSEPackedInt));
112
113   RegisterClass FRC = !if (!eq (EltTypeName, "f32"), FR32X, FR64X);
114
115   // A vector type of the same width with element type i32.  This is used to
116   // create the canonical constant zero node ImmAllZerosV.
117   ValueType i32VT = !cast<ValueType>("v" # !srl(Size, 5) # "i32");
118   dag ImmAllZerosV = (VT (bitconvert (i32VT immAllZerosV)));
119
120   string ZSuffix = !if (!eq (Size, 128), "Z128",
121                    !if (!eq (Size, 256), "Z256", "Z"));
122 }
123
124 def v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
125 def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
126 def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
127 def v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
128 def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
129 def v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
130
131 // "x" in v32i8x_info means RC = VR256X
132 def v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
133 def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
134 def v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
135 def v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
136 def v8f32x_info  : X86VectorVTInfo<8,  f32, VR256X, "ps">;
137 def v4f64x_info  : X86VectorVTInfo<4,  f64, VR256X, "pd">;
138
139 def v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
140 def v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
141 def v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
142 def v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
143 def v4f32x_info  : X86VectorVTInfo<4,  f32, VR128X, "ps">;
144 def v2f64x_info  : X86VectorVTInfo<2,  f64, VR128X, "pd">;
145
146 // We map scalar types to the smallest (128-bit) vector type
147 // with the appropriate element type. This allows to use the same masking logic.
148 def i32x_info    : X86VectorVTInfo<1,  i32, GR32, "si">;
149 def i64x_info    : X86VectorVTInfo<1,  i64, GR64, "sq">;
150 def f32x_info    : X86VectorVTInfo<1,  f32, VR128X, "ss">;
151 def f64x_info    : X86VectorVTInfo<1,  f64, VR128X, "sd">;
152
153 class AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
154                            X86VectorVTInfo i128> {
155   X86VectorVTInfo info512 = i512;
156   X86VectorVTInfo info256 = i256;
157   X86VectorVTInfo info128 = i128;
158 }
159
160 def avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
161                                              v16i8x_info>;
162 def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
163                                              v8i16x_info>;
164 def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
165                                              v4i32x_info>;
166 def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
167                                              v2i64x_info>;
168 def avx512vl_f32_info : AVX512VLVectorVTInfo<v16f32_info, v8f32x_info,
169                                              v4f32x_info>;
170 def avx512vl_f64_info : AVX512VLVectorVTInfo<v8f64_info, v4f64x_info,
171                                              v2f64x_info>;
172
173 // This multiclass generates the masking variants from the non-masking
174 // variant.  It only provides the assembly pieces for the masking variants.
175 // It assumes custom ISel patterns for masking which can be provided as
176 // template arguments.
177 multiclass AVX512_maskable_custom<bits<8> O, Format F,
178                                   dag Outs,
179                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
180                                   string OpcodeStr,
181                                   string AttSrcAsm, string IntelSrcAsm,
182                                   list<dag> Pattern,
183                                   list<dag> MaskingPattern,
184                                   list<dag> ZeroMaskingPattern,
185                                   string MaskingConstraint = "",
186                                   InstrItinClass itin = NoItinerary,
187                                   bit IsCommutable = 0> {
188   let isCommutable = IsCommutable in
189     def NAME: AVX512<O, F, Outs, Ins,
190                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
191                                      "$dst , "#IntelSrcAsm#"}",
192                        Pattern, itin>;
193
194   // Prefer over VMOV*rrk Pat<>
195   let AddedComplexity = 20 in
196     def NAME#k: AVX512<O, F, Outs, MaskingIns,
197                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
198                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
199                        MaskingPattern, itin>,
200               EVEX_K {
201       // In case of the 3src subclass this is overridden with a let.
202       string Constraints = MaskingConstraint;
203   }
204   let AddedComplexity = 30 in // Prefer over VMOV*rrkz Pat<>
205     def NAME#kz: AVX512<O, F, Outs, ZeroMaskingIns,
206                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}} {z}|"#
207                                      "$dst {${mask}} {z}, "#IntelSrcAsm#"}",
208                        ZeroMaskingPattern,
209                        itin>,
210               EVEX_KZ;
211 }
212
213
214 // Common base class of AVX512_maskable and AVX512_maskable_3src.
215 multiclass AVX512_maskable_common<bits<8> O, Format F, X86VectorVTInfo _,
216                                   dag Outs,
217                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
218                                   string OpcodeStr,
219                                   string AttSrcAsm, string IntelSrcAsm,
220                                   dag RHS, dag MaskingRHS,
221                                   SDNode Select = vselect,
222                                   string MaskingConstraint = "",
223                                   InstrItinClass itin = NoItinerary,
224                                   bit IsCommutable = 0> :
225   AVX512_maskable_custom<O, F, Outs, Ins, MaskingIns, ZeroMaskingIns, OpcodeStr,
226                          AttSrcAsm, IntelSrcAsm,
227                          [(set _.RC:$dst, RHS)],
228                          [(set _.RC:$dst, MaskingRHS)],
229                          [(set _.RC:$dst,
230                                (Select _.KRCWM:$mask, RHS, _.ImmAllZerosV))],
231                          MaskingConstraint, NoItinerary, IsCommutable>;
232
233 // This multiclass generates the unconditional/non-masking, the masking and
234 // the zero-masking variant of the vector instruction.  In the masking case, the
235 // perserved vector elements come from a new dummy input operand tied to $dst.
236 multiclass AVX512_maskable<bits<8> O, Format F, X86VectorVTInfo _,
237                            dag Outs, dag Ins, string OpcodeStr,
238                            string AttSrcAsm, string IntelSrcAsm,
239                            dag RHS,
240                            InstrItinClass itin = NoItinerary,
241                            bit IsCommutable = 0> :
242    AVX512_maskable_common<O, F, _, Outs, Ins,
243                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
244                           !con((ins _.KRCWM:$mask), Ins),
245                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
246                           (vselect _.KRCWM:$mask, RHS, _.RC:$src0), vselect,
247                           "$src0 = $dst", itin, IsCommutable>;
248
249 // This multiclass generates the unconditional/non-masking, the masking and
250 // the zero-masking variant of the scalar instruction.
251 multiclass AVX512_maskable_scalar<bits<8> O, Format F, X86VectorVTInfo _,
252                            dag Outs, dag Ins, string OpcodeStr,
253                            string AttSrcAsm, string IntelSrcAsm,
254                            dag RHS,
255                            InstrItinClass itin = NoItinerary,
256                            bit IsCommutable = 0> :
257    AVX512_maskable_common<O, F, _, Outs, Ins,
258                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
259                           !con((ins _.KRCWM:$mask), Ins),
260                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
261                           (X86select _.KRCWM:$mask, RHS, _.RC:$src0), X86select,
262                           "$src0 = $dst", itin, IsCommutable>;
263
264 // Similar to AVX512_maskable but in this case one of the source operands
265 // ($src1) is already tied to $dst so we just use that for the preserved
266 // vector elements.  NOTE that the NonTiedIns (the ins dag) should exclude
267 // $src1.
268 multiclass AVX512_maskable_3src<bits<8> O, Format F, X86VectorVTInfo _,
269                                 dag Outs, dag NonTiedIns, string OpcodeStr,
270                                 string AttSrcAsm, string IntelSrcAsm,
271                                 dag RHS> :
272    AVX512_maskable_common<O, F, _, Outs,
273                           !con((ins _.RC:$src1), NonTiedIns),
274                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
275                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
276                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
277                           (vselect _.KRCWM:$mask, RHS, _.RC:$src1)>;
278
279 multiclass AVX512_maskable_3src_scalar<bits<8> O, Format F, X86VectorVTInfo _,
280                                      dag Outs, dag NonTiedIns, string OpcodeStr,
281                                      string AttSrcAsm, string IntelSrcAsm,
282                                      dag RHS> :
283    AVX512_maskable_common<O, F, _, Outs,
284                           !con((ins _.RC:$src1), NonTiedIns),
285                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
286                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
287                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
288                           (X86select _.KRCWM:$mask, RHS, _.RC:$src1)>;
289
290 multiclass AVX512_maskable_in_asm<bits<8> O, Format F, X86VectorVTInfo _,
291                                   dag Outs, dag Ins,
292                                   string OpcodeStr,
293                                   string AttSrcAsm, string IntelSrcAsm,
294                                   list<dag> Pattern> :
295    AVX512_maskable_custom<O, F, Outs, Ins,
296                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
297                           !con((ins _.KRCWM:$mask), Ins),
298                           OpcodeStr, AttSrcAsm, IntelSrcAsm, Pattern, [], [],
299                           "$src0 = $dst">;
300
301
302 // Instruction with mask that puts result in mask register,
303 // like "compare" and "vptest"
304 multiclass AVX512_maskable_custom_cmp<bits<8> O, Format F,
305                                   dag Outs,
306                                   dag Ins, dag MaskingIns,
307                                   string OpcodeStr,
308                                   string AttSrcAsm, string IntelSrcAsm,
309                                   list<dag> Pattern,
310                                   list<dag> MaskingPattern,
311                                   string Round = "",
312                                   InstrItinClass itin = NoItinerary> {
313     def NAME: AVX512<O, F, Outs, Ins,
314                        OpcodeStr#"\t{"#AttSrcAsm#", $dst "#Round#"|"#
315                                      "$dst "#Round#", "#IntelSrcAsm#"}",
316                        Pattern, itin>;
317
318     def NAME#k: AVX512<O, F, Outs, MaskingIns,
319                        OpcodeStr#"\t{"#Round#AttSrcAsm#", $dst {${mask}}|"#
320                                      "$dst {${mask}}, "#IntelSrcAsm#Round#"}",
321                        MaskingPattern, itin>, EVEX_K;
322 }
323
324 multiclass AVX512_maskable_common_cmp<bits<8> O, Format F, X86VectorVTInfo _,
325                                   dag Outs,
326                                   dag Ins, dag MaskingIns,
327                                   string OpcodeStr,
328                                   string AttSrcAsm, string IntelSrcAsm,
329                                   dag RHS, dag MaskingRHS,
330                                   string Round = "",
331                                   InstrItinClass itin = NoItinerary> :
332   AVX512_maskable_custom_cmp<O, F, Outs, Ins, MaskingIns, OpcodeStr,
333                          AttSrcAsm, IntelSrcAsm,
334                          [(set _.KRC:$dst, RHS)],
335                          [(set _.KRC:$dst, MaskingRHS)],
336                          Round, NoItinerary>;
337
338 multiclass AVX512_maskable_cmp<bits<8> O, Format F, X86VectorVTInfo _,
339                            dag Outs, dag Ins, string OpcodeStr,
340                            string AttSrcAsm, string IntelSrcAsm,
341                            dag RHS, string Round = "",
342                            InstrItinClass itin = NoItinerary> :
343    AVX512_maskable_common_cmp<O, F, _, Outs, Ins,
344                           !con((ins _.KRCWM:$mask), Ins),
345                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
346                           (and _.KRCWM:$mask, RHS),
347                           Round, itin>;
348
349 multiclass AVX512_maskable_cmp_alt<bits<8> O, Format F, X86VectorVTInfo _,
350                            dag Outs, dag Ins, string OpcodeStr,
351                            string AttSrcAsm, string IntelSrcAsm> :
352    AVX512_maskable_custom_cmp<O, F, Outs,
353                              Ins, !con((ins _.KRCWM:$mask),Ins), OpcodeStr,
354                              AttSrcAsm, IntelSrcAsm,
355                              [],[],"", NoItinerary>;
356
357 // Bitcasts between 512-bit vector types. Return the original type since
358 // no instruction is needed for the conversion
359 let Predicates = [HasAVX512] in {
360   def : Pat<(v8f64  (bitconvert (v8i64 VR512:$src))),  (v8f64 VR512:$src)>;
361   def : Pat<(v8f64  (bitconvert (v16i32 VR512:$src))), (v8f64 VR512:$src)>;
362   def : Pat<(v8f64  (bitconvert (v32i16 VR512:$src))),  (v8f64 VR512:$src)>;
363   def : Pat<(v8f64  (bitconvert (v64i8 VR512:$src))), (v8f64 VR512:$src)>;
364   def : Pat<(v8f64  (bitconvert (v16f32 VR512:$src))), (v8f64 VR512:$src)>;
365   def : Pat<(v16f32 (bitconvert (v8i64 VR512:$src))),  (v16f32 VR512:$src)>;
366   def : Pat<(v16f32 (bitconvert (v16i32 VR512:$src))), (v16f32 VR512:$src)>;
367   def : Pat<(v16f32 (bitconvert (v32i16 VR512:$src))), (v16f32 VR512:$src)>;
368   def : Pat<(v16f32 (bitconvert (v64i8 VR512:$src))), (v16f32 VR512:$src)>;
369   def : Pat<(v16f32 (bitconvert (v8f64 VR512:$src))),  (v16f32 VR512:$src)>;
370   def : Pat<(v8i64  (bitconvert (v16i32 VR512:$src))), (v8i64 VR512:$src)>;
371   def : Pat<(v8i64  (bitconvert (v32i16 VR512:$src))), (v8i64 VR512:$src)>;
372   def : Pat<(v8i64  (bitconvert (v64i8 VR512:$src))), (v8i64 VR512:$src)>;
373   def : Pat<(v8i64  (bitconvert (v8f64 VR512:$src))),  (v8i64 VR512:$src)>;
374   def : Pat<(v8i64  (bitconvert (v16f32 VR512:$src))), (v8i64 VR512:$src)>;
375   def : Pat<(v16i32 (bitconvert (v8i64 VR512:$src))), (v16i32 VR512:$src)>;
376   def : Pat<(v16i32 (bitconvert (v16f32 VR512:$src))), (v16i32 VR512:$src)>;
377   def : Pat<(v16i32 (bitconvert (v32i16 VR512:$src))),  (v16i32 VR512:$src)>;
378   def : Pat<(v16i32 (bitconvert (v64i8 VR512:$src))),  (v16i32 VR512:$src)>;
379   def : Pat<(v16i32 (bitconvert (v8f64 VR512:$src))),  (v16i32 VR512:$src)>;
380   def : Pat<(v32i16 (bitconvert (v8i64 VR512:$src))), (v32i16 VR512:$src)>;
381   def : Pat<(v32i16 (bitconvert (v16i32 VR512:$src))),  (v32i16 VR512:$src)>;
382   def : Pat<(v32i16 (bitconvert (v64i8 VR512:$src))),  (v32i16 VR512:$src)>;
383   def : Pat<(v32i16 (bitconvert (v8f64 VR512:$src))),  (v32i16 VR512:$src)>;
384   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
385   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
386   def : Pat<(v64i8  (bitconvert (v8i64 VR512:$src))), (v64i8 VR512:$src)>;
387   def : Pat<(v64i8  (bitconvert (v16i32 VR512:$src))), (v64i8 VR512:$src)>;
388   def : Pat<(v64i8  (bitconvert (v32i16 VR512:$src))), (v64i8 VR512:$src)>;
389   def : Pat<(v64i8  (bitconvert (v8f64 VR512:$src))),  (v64i8 VR512:$src)>;
390   def : Pat<(v64i8  (bitconvert (v16f32 VR512:$src))), (v64i8 VR512:$src)>;
391
392   def : Pat<(v2i64 (bitconvert (v4i32 VR128X:$src))), (v2i64 VR128X:$src)>;
393   def : Pat<(v2i64 (bitconvert (v8i16 VR128X:$src))), (v2i64 VR128X:$src)>;
394   def : Pat<(v2i64 (bitconvert (v16i8 VR128X:$src))), (v2i64 VR128X:$src)>;
395   def : Pat<(v2i64 (bitconvert (v2f64 VR128X:$src))), (v2i64 VR128X:$src)>;
396   def : Pat<(v2i64 (bitconvert (v4f32 VR128X:$src))), (v2i64 VR128X:$src)>;
397   def : Pat<(v4i32 (bitconvert (v2i64 VR128X:$src))), (v4i32 VR128X:$src)>;
398   def : Pat<(v4i32 (bitconvert (v8i16 VR128X:$src))), (v4i32 VR128X:$src)>;
399   def : Pat<(v4i32 (bitconvert (v16i8 VR128X:$src))), (v4i32 VR128X:$src)>;
400   def : Pat<(v4i32 (bitconvert (v2f64 VR128X:$src))), (v4i32 VR128X:$src)>;
401   def : Pat<(v4i32 (bitconvert (v4f32 VR128X:$src))), (v4i32 VR128X:$src)>;
402   def : Pat<(v8i16 (bitconvert (v2i64 VR128X:$src))), (v8i16 VR128X:$src)>;
403   def : Pat<(v8i16 (bitconvert (v4i32 VR128X:$src))), (v8i16 VR128X:$src)>;
404   def : Pat<(v8i16 (bitconvert (v16i8 VR128X:$src))), (v8i16 VR128X:$src)>;
405   def : Pat<(v8i16 (bitconvert (v2f64 VR128X:$src))), (v8i16 VR128X:$src)>;
406   def : Pat<(v8i16 (bitconvert (v4f32 VR128X:$src))), (v8i16 VR128X:$src)>;
407   def : Pat<(v16i8 (bitconvert (v2i64 VR128X:$src))), (v16i8 VR128X:$src)>;
408   def : Pat<(v16i8 (bitconvert (v4i32 VR128X:$src))), (v16i8 VR128X:$src)>;
409   def : Pat<(v16i8 (bitconvert (v8i16 VR128X:$src))), (v16i8 VR128X:$src)>;
410   def : Pat<(v16i8 (bitconvert (v2f64 VR128X:$src))), (v16i8 VR128X:$src)>;
411   def : Pat<(v16i8 (bitconvert (v4f32 VR128X:$src))), (v16i8 VR128X:$src)>;
412   def : Pat<(v4f32 (bitconvert (v2i64 VR128X:$src))), (v4f32 VR128X:$src)>;
413   def : Pat<(v4f32 (bitconvert (v4i32 VR128X:$src))), (v4f32 VR128X:$src)>;
414   def : Pat<(v4f32 (bitconvert (v8i16 VR128X:$src))), (v4f32 VR128X:$src)>;
415   def : Pat<(v4f32 (bitconvert (v16i8 VR128X:$src))), (v4f32 VR128X:$src)>;
416   def : Pat<(v4f32 (bitconvert (v2f64 VR128X:$src))), (v4f32 VR128X:$src)>;
417   def : Pat<(v2f64 (bitconvert (v2i64 VR128X:$src))), (v2f64 VR128X:$src)>;
418   def : Pat<(v2f64 (bitconvert (v4i32 VR128X:$src))), (v2f64 VR128X:$src)>;
419   def : Pat<(v2f64 (bitconvert (v8i16 VR128X:$src))), (v2f64 VR128X:$src)>;
420   def : Pat<(v2f64 (bitconvert (v16i8 VR128X:$src))), (v2f64 VR128X:$src)>;
421   def : Pat<(v2f64 (bitconvert (v4f32 VR128X:$src))), (v2f64 VR128X:$src)>;
422
423 // Bitcasts between 256-bit vector types. Return the original type since
424 // no instruction is needed for the conversion
425   def : Pat<(v4f64  (bitconvert (v8f32 VR256X:$src))),  (v4f64 VR256X:$src)>;
426   def : Pat<(v4f64  (bitconvert (v8i32 VR256X:$src))),  (v4f64 VR256X:$src)>;
427   def : Pat<(v4f64  (bitconvert (v4i64 VR256X:$src))),  (v4f64 VR256X:$src)>;
428   def : Pat<(v4f64  (bitconvert (v16i16 VR256X:$src))), (v4f64 VR256X:$src)>;
429   def : Pat<(v4f64  (bitconvert (v32i8 VR256X:$src))),  (v4f64 VR256X:$src)>;
430   def : Pat<(v8f32  (bitconvert (v8i32 VR256X:$src))),  (v8f32 VR256X:$src)>;
431   def : Pat<(v8f32  (bitconvert (v4i64 VR256X:$src))),  (v8f32 VR256X:$src)>;
432   def : Pat<(v8f32  (bitconvert (v4f64 VR256X:$src))),  (v8f32 VR256X:$src)>;
433   def : Pat<(v8f32  (bitconvert (v32i8 VR256X:$src))),  (v8f32 VR256X:$src)>;
434   def : Pat<(v8f32  (bitconvert (v16i16 VR256X:$src))), (v8f32 VR256X:$src)>;
435   def : Pat<(v4i64  (bitconvert (v8f32 VR256X:$src))),  (v4i64 VR256X:$src)>;
436   def : Pat<(v4i64  (bitconvert (v8i32 VR256X:$src))),  (v4i64 VR256X:$src)>;
437   def : Pat<(v4i64  (bitconvert (v4f64 VR256X:$src))),  (v4i64 VR256X:$src)>;
438   def : Pat<(v4i64  (bitconvert (v32i8 VR256X:$src))),  (v4i64 VR256X:$src)>;
439   def : Pat<(v4i64  (bitconvert (v16i16 VR256X:$src))), (v4i64 VR256X:$src)>;
440   def : Pat<(v32i8  (bitconvert (v4f64 VR256X:$src))),  (v32i8 VR256X:$src)>;
441   def : Pat<(v32i8  (bitconvert (v4i64 VR256X:$src))),  (v32i8 VR256X:$src)>;
442   def : Pat<(v32i8  (bitconvert (v8f32 VR256X:$src))),  (v32i8 VR256X:$src)>;
443   def : Pat<(v32i8  (bitconvert (v8i32 VR256X:$src))),  (v32i8 VR256X:$src)>;
444   def : Pat<(v32i8  (bitconvert (v16i16 VR256X:$src))), (v32i8 VR256X:$src)>;
445   def : Pat<(v8i32  (bitconvert (v32i8 VR256X:$src))),  (v8i32 VR256X:$src)>;
446   def : Pat<(v8i32  (bitconvert (v16i16 VR256X:$src))), (v8i32 VR256X:$src)>;
447   def : Pat<(v8i32  (bitconvert (v8f32 VR256X:$src))),  (v8i32 VR256X:$src)>;
448   def : Pat<(v8i32  (bitconvert (v4i64 VR256X:$src))),  (v8i32 VR256X:$src)>;
449   def : Pat<(v8i32  (bitconvert (v4f64 VR256X:$src))),  (v8i32 VR256X:$src)>;
450   def : Pat<(v16i16 (bitconvert (v8f32 VR256X:$src))),  (v16i16 VR256X:$src)>;
451   def : Pat<(v16i16 (bitconvert (v8i32 VR256X:$src))),  (v16i16 VR256X:$src)>;
452   def : Pat<(v16i16 (bitconvert (v4i64 VR256X:$src))),  (v16i16 VR256X:$src)>;
453   def : Pat<(v16i16 (bitconvert (v4f64 VR256X:$src))),  (v16i16 VR256X:$src)>;
454   def : Pat<(v16i16 (bitconvert (v32i8 VR256X:$src))),  (v16i16 VR256X:$src)>;
455 }
456
457 //
458 // AVX-512: VPXOR instruction writes zero to its upper part, it's safe build zeros.
459 //
460
461 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
462     isPseudo = 1, Predicates = [HasAVX512] in {
463 def AVX512_512_SET0 : I<0, Pseudo, (outs VR512:$dst), (ins), "",
464                [(set VR512:$dst, (v16f32 immAllZerosV))]>;
465 }
466
467 let Predicates = [HasAVX512] in {
468 def : Pat<(v8i64 immAllZerosV), (AVX512_512_SET0)>;
469 def : Pat<(v16i32 immAllZerosV), (AVX512_512_SET0)>;
470 def : Pat<(v8f64 immAllZerosV), (AVX512_512_SET0)>;
471 }
472
473 //===----------------------------------------------------------------------===//
474 // AVX-512 - VECTOR INSERT
475 //
476 multiclass vinsert_for_size<int Opcode, X86VectorVTInfo From, X86VectorVTInfo To,
477                                                        PatFrag vinsert_insert> {
478   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
479     defm rr : AVX512_maskable<Opcode, MRMSrcReg, To, (outs To.RC:$dst),
480                    (ins To.RC:$src1, From.RC:$src2, i32u8imm:$src3),
481                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
482                    "$src3, $src2, $src1", "$src1, $src2, $src3",
483                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
484                                          (From.VT From.RC:$src2),
485                                          (iPTR imm))>, AVX512AIi8Base, EVEX_4V;
486
487   let mayLoad = 1 in
488     defm rm : AVX512_maskable<Opcode, MRMSrcMem, To, (outs To.RC:$dst),
489                    (ins To.RC:$src1, From.MemOp:$src2, i32u8imm:$src3),
490                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
491                    "$src3, $src2, $src1", "$src1, $src2, $src3",
492                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
493                                (From.VT (bitconvert (From.LdFrag addr:$src2))),
494                                (iPTR imm))>, AVX512AIi8Base, EVEX_4V,
495                    EVEX_CD8<From.EltSize, From.CD8TupleForm>;
496   }
497 }
498
499 multiclass vinsert_for_size_lowering<string InstrStr, X86VectorVTInfo From,
500                        X86VectorVTInfo To, PatFrag vinsert_insert,
501                        SDNodeXForm INSERT_get_vinsert_imm , list<Predicate> p> {
502   let Predicates = p in {
503     def : Pat<(vinsert_insert:$ins
504                      (To.VT To.RC:$src1), (From.VT From.RC:$src2), (iPTR imm)),
505               (To.VT (!cast<Instruction>(InstrStr#"rr")
506                      To.RC:$src1, From.RC:$src2,
507                      (INSERT_get_vinsert_imm To.RC:$ins)))>;
508
509     def : Pat<(vinsert_insert:$ins
510                   (To.VT To.RC:$src1),
511                   (From.VT (bitconvert (From.LdFrag addr:$src2))),
512                   (iPTR imm)),
513               (To.VT (!cast<Instruction>(InstrStr#"rm")
514                   To.RC:$src1, addr:$src2,
515                   (INSERT_get_vinsert_imm To.RC:$ins)))>;
516   }
517 }
518
519 multiclass vinsert_for_type<ValueType EltVT32, int Opcode128,
520                             ValueType EltVT64, int Opcode256> {
521
522   let Predicates = [HasVLX] in
523     defm NAME # "32x4Z256" : vinsert_for_size<Opcode128,
524                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
525                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
526                                  vinsert128_insert>, EVEX_V256;
527
528   defm NAME # "32x4Z" : vinsert_for_size<Opcode128,
529                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
530                                  X86VectorVTInfo<16, EltVT32, VR512>,
531                                  vinsert128_insert>, EVEX_V512;
532
533   defm NAME # "64x4Z" : vinsert_for_size<Opcode256,
534                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
535                                  X86VectorVTInfo< 8, EltVT64, VR512>,
536                                  vinsert256_insert>, VEX_W, EVEX_V512;
537
538   let Predicates = [HasVLX, HasDQI] in
539     defm NAME # "64x2Z256" : vinsert_for_size<Opcode128,
540                                    X86VectorVTInfo< 2, EltVT64, VR128X>,
541                                    X86VectorVTInfo< 4, EltVT64, VR256X>,
542                                    vinsert128_insert>, VEX_W, EVEX_V256;
543
544   let Predicates = [HasDQI] in {
545     defm NAME # "64x2Z" : vinsert_for_size<Opcode128,
546                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
547                                  X86VectorVTInfo< 8, EltVT64, VR512>,
548                                  vinsert128_insert>, VEX_W, EVEX_V512;
549
550     defm NAME # "32x8Z" : vinsert_for_size<Opcode256,
551                                    X86VectorVTInfo< 8, EltVT32, VR256X>,
552                                    X86VectorVTInfo<16, EltVT32, VR512>,
553                                    vinsert256_insert>, EVEX_V512;
554   }
555 }
556
557 defm VINSERTF : vinsert_for_type<f32, 0x18, f64, 0x1a>;
558 defm VINSERTI : vinsert_for_type<i32, 0x38, i64, 0x3a>;
559
560 // Codegen pattern with the alternative types,
561 // Only add this if 64x2 and its friends are not supported natively via AVX512DQ.
562 defm : vinsert_for_size_lowering<"VINSERTF32x4Z256", v2f64x_info, v4f64x_info,
563               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
564 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v2i64x_info, v4i64x_info,
565               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
566
567 defm : vinsert_for_size_lowering<"VINSERTF32x4Z", v2f64x_info, v8f64_info,
568               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
569 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v2i64x_info, v8i64_info,
570               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
571
572 defm : vinsert_for_size_lowering<"VINSERTF64x4Z", v8f32x_info, v16f32_info,
573               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
574 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v8i32x_info, v16i32_info,
575               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
576
577 // Codegen pattern with the alternative types insert VEC128 into VEC256
578 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v8i16x_info, v16i16x_info,
579               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
580 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v16i8x_info, v32i8x_info,
581               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
582 // Codegen pattern with the alternative types insert VEC128 into VEC512
583 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v8i16x_info, v32i16_info,
584               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
585 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v16i8x_info, v64i8_info,
586                vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
587 // Codegen pattern with the alternative types insert VEC256 into VEC512
588 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v16i16x_info, v32i16_info,
589               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
590 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v32i8x_info, v64i8_info,
591               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
592
593 // vinsertps - insert f32 to XMM
594 def VINSERTPSzrr : AVX512AIi8<0x21, MRMSrcReg, (outs VR128X:$dst),
595       (ins VR128X:$src1, VR128X:$src2, u8imm:$src3),
596       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
597       [(set VR128X:$dst, (X86insertps VR128X:$src1, VR128X:$src2, imm:$src3))]>,
598       EVEX_4V;
599 def VINSERTPSzrm: AVX512AIi8<0x21, MRMSrcMem, (outs VR128X:$dst),
600       (ins VR128X:$src1, f32mem:$src2, u8imm:$src3),
601       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
602       [(set VR128X:$dst, (X86insertps VR128X:$src1,
603                           (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
604                           imm:$src3))]>, EVEX_4V, EVEX_CD8<32, CD8VT1>;
605
606 //===----------------------------------------------------------------------===//
607 // AVX-512 VECTOR EXTRACT
608 //---
609
610 multiclass vextract_for_size_first_position_lowering<X86VectorVTInfo From,
611                                                      X86VectorVTInfo To> {
612   // A subvector extract from the first vector position is
613   // a subregister copy that needs no instruction.
614   def NAME # To.NumElts:
615       Pat<(To.VT (extract_subvector (From.VT From.RC:$src),(iPTR 0))),
616           (To.VT (EXTRACT_SUBREG (From.VT From.RC:$src), To.SubRegIdx))>;
617 }
618
619 multiclass vextract_for_size<int Opcode,
620                                     X86VectorVTInfo From, X86VectorVTInfo To,
621                                     PatFrag vextract_extract> :
622   vextract_for_size_first_position_lowering<From, To> {
623
624   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
625     // use AVX512_maskable_in_asm (AVX512_maskable can't be used due to
626     // vextract_extract), we interesting only in patterns without mask,
627     // intrinsics pattern match generated bellow.
628     defm rr : AVX512_maskable_in_asm<Opcode, MRMDestReg, To, (outs To.RC:$dst),
629                 (ins From.RC:$src1, i32u8imm:$idx),
630                 "vextract" # To.EltTypeName # "x" # To.NumElts,
631                 "$idx, $src1", "$src1, $idx",
632                 [(set To.RC:$dst, (vextract_extract:$idx (From.VT From.RC:$src1),
633                                                          (iPTR imm)))]>,
634               AVX512AIi8Base, EVEX;
635     let mayStore = 1 in {
636       def rm  : AVX512AIi8<Opcode, MRMDestMem, (outs),
637                       (ins To.MemOp:$dst, From.RC:$src1, i32u8imm:$src2),
638                       "vextract" # To.EltTypeName # "x" # To.NumElts #
639                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
640                       []>, EVEX;
641
642       def rmk : AVX512AIi8<Opcode, MRMDestMem, (outs),
643                       (ins To.MemOp:$dst, To.KRCWM:$mask,
644                                           From.RC:$src1, i32u8imm:$src2),
645                        "vextract" # To.EltTypeName # "x" # To.NumElts #
646                             "\t{$src2, $src1, $dst {${mask}}|"
647                             "$dst {${mask}}, $src1, $src2}",
648                       []>, EVEX_K, EVEX;
649     }//mayStore = 1
650   }
651
652   // Intrinsic call with masking.
653   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
654                               "x" # To.NumElts # "_" # From.Size)
655                 From.RC:$src1, (iPTR imm:$idx), To.RC:$src0, To.MRC:$mask),
656             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
657                                 From.ZSuffix # "rrk")
658                 To.RC:$src0,
659                 (COPY_TO_REGCLASS To.MRC:$mask, To.KRCWM),
660                 From.RC:$src1, imm:$idx)>;
661
662   // Intrinsic call with zero-masking.
663   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
664                               "x" # To.NumElts # "_" # From.Size)
665                 From.RC:$src1, (iPTR imm:$idx), To.ImmAllZerosV, To.MRC:$mask),
666             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
667                                 From.ZSuffix # "rrkz")
668                 (COPY_TO_REGCLASS To.MRC:$mask, To.KRCWM),
669                 From.RC:$src1, imm:$idx)>;
670
671   // Intrinsic call without masking.
672   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
673                               "x" # To.NumElts # "_" # From.Size)
674                 From.RC:$src1, (iPTR imm:$idx), To.ImmAllZerosV, (i8 -1)),
675             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
676                                 From.ZSuffix # "rr")
677                 From.RC:$src1, imm:$idx)>;
678 }
679
680 // This multiclass generates patterns for matching vextract with common types
681 // (X86VectorVTInfo From , X86VectorVTInfo To) and alternative types
682 // (X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo)
683 multiclass vextract_for_size_all<int Opcode,
684                              X86VectorVTInfo From, X86VectorVTInfo To,
685                              X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo,
686                              PatFrag vextract_extract,
687                              SDNodeXForm EXTRACT_get_vextract_imm> :
688   vextract_for_size<Opcode, From, To, vextract_extract>,
689   vextract_for_size_first_position_lowering<AltFrom, AltTo> {
690
691   // Codegen pattern with the alternative types.
692   // Only add this if operation not supported natively via AVX512DQ
693   let Predicates = [NoDQI] in
694     def : Pat<(vextract_extract:$ext (AltFrom.VT AltFrom.RC:$src1), (iPTR imm)),
695               (AltTo.VT (!cast<Instruction>(NAME # To.EltSize # "x" #
696                                             To.NumElts # From.ZSuffix # "rr")
697                          AltFrom.RC:$src1,
698                          (EXTRACT_get_vextract_imm To.RC:$ext)))>;
699 }
700
701 multiclass vextract_for_type<ValueType EltVT32, int Opcode128,
702                              ValueType EltVT64, int Opcode256> {
703   defm NAME # "32x4Z" : vextract_for_size_all<Opcode128,
704                                  X86VectorVTInfo<16, EltVT32, VR512>,
705                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
706                                  X86VectorVTInfo< 8, EltVT64, VR512>,
707                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
708                                  vextract128_extract,
709                                  EXTRACT_get_vextract128_imm>,
710                                      EVEX_V512, EVEX_CD8<32, CD8VT4>;
711   defm NAME # "64x4Z" : vextract_for_size_all<Opcode256,
712                                  X86VectorVTInfo< 8, EltVT64, VR512>,
713                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
714                                  X86VectorVTInfo<16, EltVT32, VR512>,
715                                  X86VectorVTInfo< 8, EltVT32, VR256>,
716                                  vextract256_extract,
717                                  EXTRACT_get_vextract256_imm>,
718                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT4>;
719   let Predicates = [HasVLX] in
720     defm NAME # "32x4Z256" : vextract_for_size_all<Opcode128,
721                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
722                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
723                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
724                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
725                                  vextract128_extract,
726                                  EXTRACT_get_vextract128_imm>,
727                                      EVEX_V256, EVEX_CD8<32, CD8VT4>;
728   let Predicates = [HasVLX, HasDQI] in
729     defm NAME # "64x2Z256" : vextract_for_size<Opcode128,
730                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
731                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
732                                  vextract128_extract>,
733                                      VEX_W, EVEX_V256, EVEX_CD8<64, CD8VT2>;
734   let Predicates = [HasDQI] in {
735     defm NAME # "64x2Z" : vextract_for_size<Opcode128,
736                                  X86VectorVTInfo< 8, EltVT64, VR512>,
737                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
738                                  vextract128_extract>,
739                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT2>;
740     defm NAME # "32x8Z" : vextract_for_size<Opcode256,
741                                  X86VectorVTInfo<16, EltVT32, VR512>,
742                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
743                                  vextract256_extract>,
744                                      EVEX_V512, EVEX_CD8<32, CD8VT8>;
745   }
746 }
747
748 defm VEXTRACTF : vextract_for_type<f32, 0x19, f64, 0x1b>;
749 defm VEXTRACTI : vextract_for_type<i32, 0x39, i64, 0x3b>;
750
751 // A 128-bit subvector insert to the first 512-bit vector position
752 // is a subregister copy that needs no instruction.
753 def : Pat<(insert_subvector undef, (v2i64 VR128X:$src), (iPTR 0)),
754           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)),
755           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
756           sub_ymm)>;
757 def : Pat<(insert_subvector undef, (v2f64 VR128X:$src), (iPTR 0)),
758           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)),
759           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
760           sub_ymm)>;
761 def : Pat<(insert_subvector undef, (v4i32 VR128X:$src), (iPTR 0)),
762           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
763           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
764           sub_ymm)>;
765 def : Pat<(insert_subvector undef, (v4f32 VR128X:$src), (iPTR 0)),
766           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
767           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
768           sub_ymm)>;
769
770 def : Pat<(insert_subvector undef, (v4i64 VR256X:$src), (iPTR 0)),
771           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
772 def : Pat<(insert_subvector undef, (v4f64 VR256X:$src), (iPTR 0)),
773           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
774 def : Pat<(insert_subvector undef, (v8i32 VR256X:$src), (iPTR 0)),
775           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
776 def : Pat<(insert_subvector undef, (v8f32 VR256X:$src), (iPTR 0)),
777           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
778
779 // vextractps - extract 32 bits from XMM
780 def VEXTRACTPSzrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32:$dst),
781       (ins VR128X:$src1, u8imm:$src2),
782       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
783       [(set GR32:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
784       EVEX;
785
786 def VEXTRACTPSzmr : AVX512AIi8<0x17, MRMDestMem, (outs),
787       (ins f32mem:$dst, VR128X:$src1, u8imm:$src2),
788       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
789       [(store (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2),
790                           addr:$dst)]>, EVEX, EVEX_CD8<32, CD8VT1>;
791
792 //===---------------------------------------------------------------------===//
793 // AVX-512 BROADCAST
794 //---
795 multiclass avx512_fp_broadcast<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
796                               ValueType svt, X86VectorVTInfo _> {
797   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
798                    (ins SrcRC:$src), "vbroadcast"## !subst("p", "s", _.Suffix),
799                    "$src", "$src", (_.VT (OpNode (svt SrcRC:$src)))>,
800                    T8PD, EVEX;
801
802   let mayLoad = 1 in {
803     defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
804                      (ins _.ScalarMemOp:$src),
805                      "vbroadcast"##!subst("p", "s", _.Suffix), "$src", "$src",
806                      (_.VT (OpNode (_.ScalarLdFrag addr:$src)))>,
807                      T8PD, EVEX;
808   }
809 }
810
811 multiclass avx512_fp_broadcast_vl<bits<8> opc, SDNode OpNode,
812                                   AVX512VLVectorVTInfo _> {
813   defm Z  : avx512_fp_broadcast<opc, OpNode, VR128X, _.info128.VT, _.info512>,
814                              EVEX_V512;
815
816   let Predicates = [HasVLX] in {
817     defm Z256  : avx512_fp_broadcast<opc, OpNode, VR128X, _.info128.VT, _.info256>,
818                                   EVEX_V256;
819   }
820 }
821
822 let ExeDomain = SSEPackedSingle in {
823   defm VBROADCASTSS  : avx512_fp_broadcast_vl<0x18, X86VBroadcast,
824                               avx512vl_f32_info>, EVEX_CD8<32, CD8VT1>;
825    let Predicates = [HasVLX] in {
826      defm VBROADCASTSSZ128  : avx512_fp_broadcast<0x18, X86VBroadcast, VR128X,
827                                      v4f32, v4f32x_info>, EVEX_V128,
828                                      EVEX_CD8<32, CD8VT1>;
829    }
830 }
831
832 let ExeDomain = SSEPackedDouble in {
833   defm VBROADCASTSD  : avx512_fp_broadcast_vl<0x19, X86VBroadcast,
834                               avx512vl_f64_info>, VEX_W, EVEX_CD8<64, CD8VT1>;
835 }
836
837 // avx512_broadcast_pat introduces patterns for broadcast with a scalar argument.
838 // Later, we can canonize broadcast instructions before ISel phase and
839 // eliminate additional patterns on ISel.
840 // SrcRC_v and SrcRC_s are RegisterClasses for vector and scalar
841 // representations of source
842 multiclass avx512_broadcast_pat<string InstName, SDNode OpNode,
843                                 X86VectorVTInfo _, RegisterClass SrcRC_v,
844                                 RegisterClass SrcRC_s> {
845   def : Pat<(_.VT (OpNode  (_.EltVT SrcRC_s:$src))),
846             (!cast<Instruction>(InstName##"r")
847               (COPY_TO_REGCLASS SrcRC_s:$src, SrcRC_v))>;
848
849   let AddedComplexity = 30 in {
850     def : Pat<(_.VT (vselect _.KRCWM:$mask,
851                 (OpNode (_.EltVT SrcRC_s:$src)), _.RC:$src0)),
852               (!cast<Instruction>(InstName##"rk") _.RC:$src0, _.KRCWM:$mask,
853                 (COPY_TO_REGCLASS SrcRC_s:$src, SrcRC_v))>;
854
855     def : Pat<(_.VT(vselect _.KRCWM:$mask,
856                 (OpNode (_.EltVT SrcRC_s:$src)), _.ImmAllZerosV)),
857               (!cast<Instruction>(InstName##"rkz") _.KRCWM:$mask,
858                 (COPY_TO_REGCLASS SrcRC_s:$src, SrcRC_v))>;
859   }
860 }
861
862 defm : avx512_broadcast_pat<"VBROADCASTSSZ", X86VBroadcast, v16f32_info,
863                             VR128X, FR32X>;
864 defm : avx512_broadcast_pat<"VBROADCASTSDZ", X86VBroadcast, v8f64_info,
865                             VR128X, FR64X>;
866
867 let Predicates = [HasVLX] in {
868   defm : avx512_broadcast_pat<"VBROADCASTSSZ256", X86VBroadcast,
869                               v8f32x_info, VR128X, FR32X>;
870   defm : avx512_broadcast_pat<"VBROADCASTSSZ128", X86VBroadcast,
871                               v4f32x_info, VR128X, FR32X>;
872   defm : avx512_broadcast_pat<"VBROADCASTSDZ256", X86VBroadcast,
873                               v4f64x_info, VR128X, FR64X>;
874 }
875
876 def : Pat<(v16f32 (X86VBroadcast (loadf32 addr:$src))),
877           (VBROADCASTSSZm addr:$src)>;
878 def : Pat<(v8f64 (X86VBroadcast (loadf64 addr:$src))),
879           (VBROADCASTSDZm addr:$src)>;
880
881 def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
882           (VBROADCASTSSZm addr:$src)>;
883 def : Pat<(int_x86_avx512_vbroadcast_sd_512 addr:$src),
884           (VBROADCASTSDZm addr:$src)>;
885
886 multiclass avx512_int_broadcast_reg<bits<8> opc, X86VectorVTInfo _,
887                                     RegisterClass SrcRC> {
888   defm r : AVX512_maskable_in_asm<opc, MRMSrcReg, _, (outs _.RC:$dst),
889                            (ins SrcRC:$src),  "vpbroadcast"##_.Suffix,
890                            "$src", "$src", []>, T8PD, EVEX;
891 }
892
893 multiclass avx512_int_broadcast_reg_vl<bits<8> opc, AVX512VLVectorVTInfo _,
894                                        RegisterClass SrcRC, Predicate prd> {
895   let Predicates = [prd] in
896     defm Z : avx512_int_broadcast_reg<opc, _.info512, SrcRC>, EVEX_V512;
897   let Predicates = [prd, HasVLX] in {
898     defm Z256 : avx512_int_broadcast_reg<opc, _.info256, SrcRC>, EVEX_V256;
899     defm Z128 : avx512_int_broadcast_reg<opc, _.info128, SrcRC>, EVEX_V128;
900   }
901 }
902
903 defm VPBROADCASTBr : avx512_int_broadcast_reg_vl<0x7A, avx512vl_i8_info, GR32,
904                                                  HasBWI>;
905 defm VPBROADCASTWr : avx512_int_broadcast_reg_vl<0x7B, avx512vl_i16_info, GR32,
906                                                  HasBWI>;
907 defm VPBROADCASTDr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i32_info, GR32,
908                                                  HasAVX512>;
909 defm VPBROADCASTQr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i64_info, GR64,
910                                                  HasAVX512>, VEX_W;
911
912 def : Pat <(v16i32 (X86vzext VK16WM:$mask)),
913            (VPBROADCASTDrZrkz VK16WM:$mask, (i32 (MOV32ri 0x1)))>;
914
915 def : Pat <(v8i64 (X86vzext VK8WM:$mask)),
916            (VPBROADCASTQrZrkz VK8WM:$mask, (i64 (MOV64ri 0x1)))>;
917
918 def : Pat<(v16i32 (X86VBroadcast (i32 GR32:$src))),
919         (VPBROADCASTDrZr GR32:$src)>;
920 def : Pat<(v8i64 (X86VBroadcast (i64 GR64:$src))),
921         (VPBROADCASTQrZr GR64:$src)>;
922
923 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_i32_512 (i32 GR32:$src))),
924         (VPBROADCASTDrZr GR32:$src)>;
925 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_i64_512 (i64 GR64:$src))),
926         (VPBROADCASTQrZr GR64:$src)>;
927
928 def : Pat<(v16i32 (int_x86_avx512_mask_pbroadcast_d_gpr_512 (i32 GR32:$src),
929                    (v16i32 immAllZerosV), (i16 GR16:$mask))),
930           (VPBROADCASTDrZrkz (COPY_TO_REGCLASS GR16:$mask, VK16WM), GR32:$src)>;
931 def : Pat<(v8i64 (int_x86_avx512_mask_pbroadcast_q_gpr_512 (i64 GR64:$src),
932                    (bc_v8i64 (v16i32 immAllZerosV)), (i8 GR8:$mask))),
933           (VPBROADCASTQrZrkz (COPY_TO_REGCLASS GR8:$mask, VK8WM), GR64:$src)>;
934
935 multiclass avx512_int_broadcast_rm<bits<8> opc, string OpcodeStr,
936                           X86MemOperand x86memop, PatFrag ld_frag,
937                           RegisterClass DstRC, ValueType OpVT, ValueType SrcVT,
938                           RegisterClass KRC> {
939   def rr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins VR128X:$src),
940                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
941                   [(set DstRC:$dst,
942                     (OpVT (X86VBroadcast (SrcVT VR128X:$src))))]>, EVEX;
943   def rrk : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins KRC:$mask,
944                                                          VR128X:$src),
945                     !strconcat(OpcodeStr,
946                     "\t{$src, ${dst} {${mask}} |${dst} {${mask}}, $src}"),
947                     []>, EVEX, EVEX_K;
948   def rrkz : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins KRC:$mask,
949                                                          VR128X:$src),
950                     !strconcat(OpcodeStr,
951                     "\t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
952                     []>, EVEX, EVEX_KZ;
953   let mayLoad = 1 in {
954   def rm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
955                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
956                   [(set DstRC:$dst,
957                     (OpVT (X86VBroadcast (ld_frag addr:$src))))]>, EVEX;
958   def rmk : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins KRC:$mask,
959                                                          x86memop:$src),
960                   !strconcat(OpcodeStr,
961                       "\t{$src, ${dst} {${mask}}|${dst} {${mask}} , $src}"),
962                   []>, EVEX, EVEX_K;
963   def rmkz : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins KRC:$mask,
964                                                          x86memop:$src),
965                   !strconcat(OpcodeStr,
966                       "\t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
967                   [(set DstRC:$dst, (OpVT (vselect KRC:$mask,
968                              (X86VBroadcast (ld_frag addr:$src)),
969                              (OpVT (bitconvert (v16i32 immAllZerosV))))))]>, EVEX, EVEX_KZ;
970   }
971 }
972
973 defm VPBROADCASTDZ  : avx512_int_broadcast_rm<0x58, "vpbroadcastd", i32mem,
974                       loadi32, VR512, v16i32, v4i32, VK16WM>,
975                       EVEX_V512, EVEX_CD8<32, CD8VT1>;
976 defm VPBROADCASTQZ  : avx512_int_broadcast_rm<0x59, "vpbroadcastq", i64mem,
977                       loadi64, VR512, v8i64, v2i64, VK8WM>,  EVEX_V512, VEX_W,
978                       EVEX_CD8<64, CD8VT1>;
979
980 multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
981                           X86VectorVTInfo _Dst, X86VectorVTInfo _Src> {
982   let mayLoad = 1 in {
983   def rm : AVX5128I<opc, MRMSrcMem, (outs _Dst.RC:$dst), (ins _Src.MemOp:$src),
984                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
985                   [(set _Dst.RC:$dst,
986                     (_Dst.VT (X86SubVBroadcast
987                     (_Src.VT (bitconvert (_Src.LdFrag addr:$src))))))]>, EVEX;
988   def rmk : AVX5128I<opc, MRMSrcMem, (outs _Dst.RC:$dst), (ins _Dst.KRCWM:$mask,
989                                                          _Src.MemOp:$src),
990                   !strconcat(OpcodeStr,
991                       "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
992                   []>, EVEX, EVEX_K;
993   def rmkz : AVX5128I<opc, MRMSrcMem, (outs _Dst.RC:$dst), (ins _Dst.KRCWM:$mask,
994                                                          _Src.MemOp:$src),
995                   !strconcat(OpcodeStr,
996                     "\t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
997                   []>, EVEX, EVEX_KZ;
998   }
999 }
1000
1001 defm VBROADCASTI32X4 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1002                        v16i32_info, v4i32x_info>,
1003                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1004 defm VBROADCASTF32X4 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1005                        v16f32_info, v4f32x_info>,
1006                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1007 defm VBROADCASTI64X4 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
1008                        v8i64_info, v4i64x_info>, VEX_W,
1009                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1010 defm VBROADCASTF64X4 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf64x4",
1011                        v8f64_info, v4f64x_info>, VEX_W,
1012                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1013
1014 let Predicates = [HasVLX] in {
1015 defm VBROADCASTI32X4Z256 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1016                            v8i32x_info, v4i32x_info>,
1017                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1018 defm VBROADCASTF32X4Z256 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1019                            v8f32x_info, v4f32x_info>,
1020                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1021 }
1022 let Predicates = [HasVLX, HasDQI] in {
1023 defm VBROADCASTI64X2Z128 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1024                            v4i64x_info, v2i64x_info>, VEX_W,
1025                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1026 defm VBROADCASTF64X2Z128 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1027                            v4f64x_info, v2f64x_info>, VEX_W,
1028                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1029 }
1030 let Predicates = [HasDQI] in {
1031 defm VBROADCASTI64X2 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1032                        v8i64_info, v2i64x_info>, VEX_W,
1033                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1034 defm VBROADCASTI32X8 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti32x8",
1035                        v16i32_info, v8i32x_info>,
1036                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1037 defm VBROADCASTF64X2 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1038                        v8f64_info, v2f64x_info>, VEX_W,
1039                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1040 defm VBROADCASTF32X8 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf32x8",
1041                        v16f32_info, v8f32x_info>,
1042                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1043 }
1044
1045 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_512 (v4i32 VR128X:$src))),
1046           (VPBROADCASTDZrr VR128X:$src)>;
1047 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_512 (v2i64 VR128X:$src))),
1048           (VPBROADCASTQZrr VR128X:$src)>;
1049
1050 def : Pat<(v16f32 (X86VBroadcast (v16f32 VR512:$src))),
1051           (VBROADCASTSSZr (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm))>;
1052 def : Pat<(v16f32 (X86VBroadcast (v8f32 VR256X:$src))),
1053           (VBROADCASTSSZr (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm))>;
1054
1055 def : Pat<(v8f64 (X86VBroadcast (v8f64 VR512:$src))),
1056           (VBROADCASTSDZr (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm))>;
1057 def : Pat<(v8f64 (X86VBroadcast (v4f64 VR256X:$src))),
1058           (VBROADCASTSDZr (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm))>;
1059
1060 def : Pat<(v16i32 (X86VBroadcast (v16i32 VR512:$src))),
1061           (VPBROADCASTDZrr (EXTRACT_SUBREG (v16i32 VR512:$src), sub_xmm))>;
1062 def : Pat<(v16i32 (X86VBroadcast (v8i32 VR256X:$src))),
1063           (VPBROADCASTDZrr (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm))>;
1064
1065 def : Pat<(v8i64 (X86VBroadcast (v8i64 VR512:$src))),
1066           (VPBROADCASTQZrr (EXTRACT_SUBREG (v8i64 VR512:$src), sub_xmm))>;
1067 def : Pat<(v8i64 (X86VBroadcast (v4i64 VR256X:$src))),
1068           (VPBROADCASTQZrr (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm))>;
1069
1070 def : Pat<(v16f32 (int_x86_avx512_vbroadcast_ss_ps_512 (v4f32 VR128X:$src))),
1071           (VBROADCASTSSZr VR128X:$src)>;
1072 def : Pat<(v8f64 (int_x86_avx512_vbroadcast_sd_pd_512 (v2f64 VR128X:$src))),
1073           (VBROADCASTSDZr VR128X:$src)>;
1074
1075 // Provide fallback in case the load node that is used in the patterns above
1076 // is used by additional users, which prevents the pattern selection.
1077 def : Pat<(v16f32 (X86VBroadcast FR32X:$src)),
1078           (VBROADCASTSSZr (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
1079 def : Pat<(v8f64 (X86VBroadcast FR64X:$src)),
1080           (VBROADCASTSDZr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
1081
1082
1083 //===----------------------------------------------------------------------===//
1084 // AVX-512 BROADCAST MASK TO VECTOR REGISTER
1085 //---
1086
1087 multiclass avx512_mask_broadcast<bits<8> opc, string OpcodeStr,
1088                        RegisterClass KRC> {
1089 let Predicates = [HasCDI] in
1090 def Zrr : AVX512XS8I<opc, MRMSrcReg, (outs VR512:$dst), (ins KRC:$src),
1091                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1092                   []>, EVEX, EVEX_V512;
1093
1094 let Predicates = [HasCDI, HasVLX] in {
1095 def Z128rr : AVX512XS8I<opc, MRMSrcReg, (outs VR128:$dst), (ins KRC:$src),
1096                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1097                   []>, EVEX, EVEX_V128;
1098 def Z256rr : AVX512XS8I<opc, MRMSrcReg, (outs VR256:$dst), (ins KRC:$src),
1099                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1100                   []>, EVEX, EVEX_V256;
1101 }
1102 }
1103
1104 let Predicates = [HasCDI] in {
1105 defm VPBROADCASTMW2D : avx512_mask_broadcast<0x3A, "vpbroadcastmw2d",
1106                                              VK16>;
1107 defm VPBROADCASTMB2Q : avx512_mask_broadcast<0x2A, "vpbroadcastmb2q",
1108                                              VK8>, VEX_W;
1109 }
1110
1111 //===----------------------------------------------------------------------===//
1112 // -- VPERM2I - 3 source operands form --
1113 multiclass avx512_perm_3src<bits<8> opc, string OpcodeStr,
1114                             SDNode OpNode, X86VectorVTInfo _> {
1115 let Constraints = "$src1 = $dst" in {
1116   defm rr: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
1117           (ins _.RC:$src2, _.RC:$src3),
1118           OpcodeStr, "$src3, $src2", "$src2, $src3",
1119           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>, EVEX_4V,
1120          AVX5128IBase;
1121
1122   let mayLoad = 1 in
1123   defm rm: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1124             (ins _.RC:$src2, _.MemOp:$src3),
1125             OpcodeStr, "$src3, $src2", "$src2, $src3",
1126             (_.VT (OpNode _.RC:$src1, _.RC:$src2,
1127                    (_.VT (bitconvert (_.LdFrag addr:$src3)))))>,
1128             EVEX_4V, AVX5128IBase;
1129   }
1130 }
1131 multiclass avx512_perm_3src_mb<bits<8> opc, string OpcodeStr,
1132                                SDNode OpNode, X86VectorVTInfo _> {
1133   let mayLoad = 1, Constraints = "$src1 = $dst" in
1134   defm rmb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1135               (ins _.RC:$src2, _.ScalarMemOp:$src3),
1136               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
1137               !strconcat("$src2, ${src3}", _.BroadcastStr ),
1138               (_.VT (OpNode _.RC:$src1,
1139                _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3)))))>,
1140               AVX5128IBase, EVEX_4V, EVEX_B;
1141 }
1142
1143 multiclass avx512_perm_3src_sizes<bits<8> opc, string OpcodeStr,
1144                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo> {
1145   let Predicates = [HasAVX512] in
1146   defm NAME: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info512>,
1147             avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
1148   let Predicates = [HasVLX] in {
1149   defm NAME#128: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info128>,
1150                  avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info128>,
1151                  EVEX_V128;
1152   defm NAME#256: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info256>,
1153                  avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info256>,
1154                  EVEX_V256;
1155   }
1156 }
1157 multiclass avx512_perm_3src_sizes_w<bits<8> opc, string OpcodeStr,
1158                                    SDNode OpNode, AVX512VLVectorVTInfo VTInfo> {
1159   let Predicates = [HasBWI] in
1160   defm NAME: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info512>,
1161              avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info512>,
1162              EVEX_V512;
1163   let Predicates = [HasBWI, HasVLX] in {
1164   defm NAME#128: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info128>,
1165                  avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info128>,
1166                  EVEX_V128;
1167   defm NAME#256: avx512_perm_3src<opc, OpcodeStr, OpNode, VTInfo.info256>,
1168                  avx512_perm_3src_mb<opc, OpcodeStr, OpNode, VTInfo.info256>,
1169                  EVEX_V256;
1170   }
1171 }
1172 defm VPERMI2D  : avx512_perm_3src_sizes<0x76, "vpermi2d", X86VPermiv3,
1173                                   avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1174 defm VPERMI2Q  : avx512_perm_3src_sizes<0x76, "vpermi2q", X86VPermiv3,
1175                                   avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1176 defm VPERMI2PS : avx512_perm_3src_sizes<0x77, "vpermi2ps", X86VPermiv3,
1177                                   avx512vl_f32_info>, EVEX_CD8<32, CD8VF>;
1178 defm VPERMI2PD : avx512_perm_3src_sizes<0x77, "vpermi2pd", X86VPermiv3,
1179                                   avx512vl_f64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1180
1181 defm VPERMT2D  : avx512_perm_3src_sizes<0x7E, "vpermt2d", X86VPermv3,
1182                                   avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1183 defm VPERMT2Q  : avx512_perm_3src_sizes<0x7E, "vpermt2q", X86VPermv3,
1184                                   avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1185 defm VPERMT2PS : avx512_perm_3src_sizes<0x7F, "vpermt2ps", X86VPermv3,
1186                                   avx512vl_f32_info>, EVEX_CD8<32, CD8VF>;
1187 defm VPERMT2PD : avx512_perm_3src_sizes<0x7F, "vpermt2pd", X86VPermv3,
1188                                   avx512vl_f64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1189
1190 defm VPERMT2W  : avx512_perm_3src_sizes_w<0x7D, "vpermt2w", X86VPermv3,
1191                                   avx512vl_i16_info>, VEX_W, EVEX_CD8<16, CD8VF>;
1192 defm VPERMI2W  : avx512_perm_3src_sizes_w<0x75, "vpermi2w", X86VPermiv3,
1193                                   avx512vl_i16_info>, VEX_W, EVEX_CD8<16, CD8VF>;
1194
1195 //===----------------------------------------------------------------------===//
1196 // AVX-512 - BLEND using mask
1197 //
1198 multiclass avx512_blendmask<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1199   let ExeDomain = _.ExeDomain in {
1200   def rr : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1201              (ins _.RC:$src1, _.RC:$src2),
1202              !strconcat(OpcodeStr,
1203              "\t{$src2, $src1, ${dst} |${dst}, $src1, $src2}"),
1204              []>, EVEX_4V;
1205   def rrk : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1206              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1207              !strconcat(OpcodeStr,
1208              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1209              [(set _.RC:$dst, (X86select _.KRCWM:$mask, (_.VT _.RC:$src1),
1210                  (_.VT _.RC:$src2)))]>, EVEX_4V, EVEX_K;
1211   def rrkz : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1212              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1213              !strconcat(OpcodeStr,
1214              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1215              []>, EVEX_4V, EVEX_KZ;
1216   let mayLoad = 1 in {
1217   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1218              (ins _.RC:$src1, _.MemOp:$src2),
1219              !strconcat(OpcodeStr,
1220              "\t{$src2, $src1, ${dst} |${dst},  $src1, $src2}"),
1221              []>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
1222   def rmk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1223              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1224              !strconcat(OpcodeStr,
1225              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1226              [(set _.RC:$dst, (X86select _.KRCWM:$mask, (_.VT _.RC:$src1),
1227               (_.VT (bitconvert (_.LdFrag addr:$src2)))))]>,
1228               EVEX_4V, EVEX_K, EVEX_CD8<_.EltSize, CD8VF>;
1229   def rmkz : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1230              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1231              !strconcat(OpcodeStr,
1232              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1233              []>, EVEX_4V, EVEX_KZ, EVEX_CD8<_.EltSize, CD8VF>;
1234   }
1235   }
1236 }
1237 multiclass avx512_blendmask_rmb<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1238
1239   def rmbk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1240       (ins _.KRCWM:$mask, _.RC:$src1, _.ScalarMemOp:$src2),
1241        !strconcat(OpcodeStr,
1242             "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1243             "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1244       [(set _.RC:$dst,(X86select _.KRCWM:$mask, (_.VT _.RC:$src1),
1245                        (X86VBroadcast (_.ScalarLdFrag addr:$src2))))]>,
1246       EVEX_4V, EVEX_K, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1247
1248   def rmb : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1249       (ins _.RC:$src1, _.ScalarMemOp:$src2),
1250        !strconcat(OpcodeStr,
1251             "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1252             "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1253       []>,  EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1254
1255 }
1256
1257 multiclass blendmask_dq <bits<8> opc, string OpcodeStr,
1258                                  AVX512VLVectorVTInfo VTInfo> {
1259   defm Z : avx512_blendmask      <opc, OpcodeStr, VTInfo.info512>,
1260            avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1261
1262   let Predicates = [HasVLX] in {
1263     defm Z256 : avx512_blendmask<opc, OpcodeStr, VTInfo.info256>,
1264                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1265     defm Z128 : avx512_blendmask<opc, OpcodeStr, VTInfo.info128>,
1266                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1267   }
1268 }
1269
1270 multiclass blendmask_bw <bits<8> opc, string OpcodeStr,
1271                          AVX512VLVectorVTInfo VTInfo> {
1272   let Predicates = [HasBWI] in
1273     defm Z : avx512_blendmask    <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1274
1275   let Predicates = [HasBWI, HasVLX] in {
1276     defm Z256 : avx512_blendmask <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1277     defm Z128 : avx512_blendmask <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1278   }
1279 }
1280
1281
1282 defm VBLENDMPS : blendmask_dq <0x65, "vblendmps", avx512vl_f32_info>;
1283 defm VBLENDMPD : blendmask_dq <0x65, "vblendmpd", avx512vl_f64_info>, VEX_W;
1284 defm VPBLENDMD : blendmask_dq <0x64, "vpblendmd", avx512vl_i32_info>;
1285 defm VPBLENDMQ : blendmask_dq <0x64, "vpblendmq", avx512vl_i64_info>, VEX_W;
1286 defm VPBLENDMB : blendmask_bw <0x66, "vpblendmb", avx512vl_i8_info>;
1287 defm VPBLENDMW : blendmask_bw <0x66, "vpblendmw", avx512vl_i16_info>, VEX_W;
1288
1289
1290 let Predicates = [HasAVX512] in {
1291 def : Pat<(v8f32 (vselect (v8i1 VK8WM:$mask), (v8f32 VR256X:$src1),
1292                             (v8f32 VR256X:$src2))),
1293             (EXTRACT_SUBREG
1294               (v16f32 (VBLENDMPSZrrk (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
1295             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1296             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
1297
1298 def : Pat<(v8i32 (vselect (v8i1 VK8WM:$mask), (v8i32 VR256X:$src1),
1299                             (v8i32 VR256X:$src2))),
1300             (EXTRACT_SUBREG
1301                 (v16i32 (VPBLENDMDZrrk (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
1302             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1303             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
1304 }
1305 //===----------------------------------------------------------------------===//
1306 // Compare Instructions
1307 //===----------------------------------------------------------------------===//
1308
1309 // avx512_cmp_scalar - AVX512 CMPSS and CMPSD
1310
1311 multiclass avx512_cmp_scalar<X86VectorVTInfo _, SDNode OpNode, SDNode OpNodeRnd>{
1312
1313   defm  rr_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1314                       (outs _.KRC:$dst),
1315                       (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1316                       "vcmp${cc}"#_.Suffix,
1317                       "$src2, $src1", "$src1, $src2",
1318                       (OpNode (_.VT _.RC:$src1),
1319                               (_.VT _.RC:$src2),
1320                               imm:$cc)>, EVEX_4V;
1321   let mayLoad = 1 in
1322     defm  rm_Int  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1323                       (outs _.KRC:$dst),
1324                       (ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1325                       "vcmp${cc}"#_.Suffix,
1326                       "$src2, $src1", "$src1, $src2",
1327                       (OpNode (_.VT _.RC:$src1),
1328                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
1329                           imm:$cc)>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1330
1331   defm  rrb_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1332                      (outs _.KRC:$dst),
1333                      (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1334                      "vcmp${cc}"#_.Suffix,
1335                      "{sae}, $src2, $src1", "$src1, $src2,{sae}",
1336                      (OpNodeRnd (_.VT _.RC:$src1),
1337                                 (_.VT _.RC:$src2),
1338                                 imm:$cc,
1339                                 (i32 FROUND_NO_EXC))>, EVEX_4V, EVEX_B;
1340   // Accept explicit immediate argument form instead of comparison code.
1341   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1342     defm  rri_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1343                         (outs VK1:$dst),
1344                         (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1345                         "vcmp"#_.Suffix,
1346                         "$cc, $src2, $src1", "$src1, $src2, $cc">, EVEX_4V;
1347     defm  rmi_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1348                         (outs _.KRC:$dst),
1349                         (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1350                         "vcmp"#_.Suffix,
1351                         "$cc, $src2, $src1", "$src1, $src2, $cc">,
1352                         EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1353
1354     defm  rrb_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1355                        (outs _.KRC:$dst),
1356                        (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1357                        "vcmp"#_.Suffix,
1358                        "$cc,{sae}, $src2, $src1","$src1, $src2,{sae}, $cc">,
1359                        EVEX_4V, EVEX_B;
1360   }// let isAsmParserOnly = 1, hasSideEffects = 0
1361
1362   let isCodeGenOnly = 1 in {
1363     def rr : AVX512Ii8<0xC2, MRMSrcReg,
1364                 (outs _.KRC:$dst), (ins _.FRC:$src1, _.FRC:$src2, AVXCC:$cc),
1365                 !strconcat("vcmp${cc}", _.Suffix,
1366                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1367                 [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1368                                           _.FRC:$src2,
1369                                           imm:$cc))],
1370                 IIC_SSE_ALU_F32S_RR>, EVEX_4V;
1371     let mayLoad = 1 in
1372       def rm : AVX512Ii8<0xC2, MRMSrcMem,
1373                 (outs _.KRC:$dst),
1374                 (ins _.FRC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1375                 !strconcat("vcmp${cc}", _.Suffix,
1376                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1377                 [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1378                                           (_.ScalarLdFrag addr:$src2),
1379                                           imm:$cc))],
1380                 IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1381   }
1382 }
1383
1384 let Predicates = [HasAVX512] in {
1385   defm VCMPSSZ : avx512_cmp_scalar<f32x_info, X86cmpms, X86cmpmsRnd>,
1386                                    AVX512XSIi8Base;
1387   defm VCMPSDZ : avx512_cmp_scalar<f64x_info, X86cmpms, X86cmpmsRnd>,
1388                                    AVX512XDIi8Base, VEX_W;
1389 }
1390
1391 multiclass avx512_icmp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
1392               X86VectorVTInfo _> {
1393   def rr : AVX512BI<opc, MRMSrcReg,
1394              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2),
1395              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1396              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2)))],
1397              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1398   let mayLoad = 1 in
1399   def rm : AVX512BI<opc, MRMSrcMem,
1400              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2),
1401              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1402              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1403                                      (_.VT (bitconvert (_.LdFrag addr:$src2)))))],
1404              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1405   def rrk : AVX512BI<opc, MRMSrcReg,
1406               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1407               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1408                           "$dst {${mask}}, $src1, $src2}"),
1409               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1410                                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))))],
1411               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1412   let mayLoad = 1 in
1413   def rmk : AVX512BI<opc, MRMSrcMem,
1414               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1415               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1416                           "$dst {${mask}}, $src1, $src2}"),
1417               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1418                                    (OpNode (_.VT _.RC:$src1),
1419                                        (_.VT (bitconvert
1420                                               (_.LdFrag addr:$src2))))))],
1421               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1422 }
1423
1424 multiclass avx512_icmp_packed_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
1425               X86VectorVTInfo _> :
1426            avx512_icmp_packed<opc, OpcodeStr, OpNode, _> {
1427   let mayLoad = 1 in {
1428   def rmb : AVX512BI<opc, MRMSrcMem,
1429               (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2),
1430               !strconcat(OpcodeStr, "\t{${src2}", _.BroadcastStr, ", $src1, $dst",
1431                                     "|$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1432               [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1433                               (X86VBroadcast (_.ScalarLdFrag addr:$src2))))],
1434               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1435   def rmbk : AVX512BI<opc, MRMSrcMem,
1436                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1437                                        _.ScalarMemOp:$src2),
1438                !strconcat(OpcodeStr,
1439                           "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1440                           "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1441                [(set _.KRC:$dst, (and _.KRCWM:$mask,
1442                                       (OpNode (_.VT _.RC:$src1),
1443                                         (X86VBroadcast
1444                                           (_.ScalarLdFrag addr:$src2)))))],
1445                IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1446   }
1447 }
1448
1449 multiclass avx512_icmp_packed_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
1450                                  AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1451   let Predicates = [prd] in
1452   defm Z : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info512>,
1453            EVEX_V512;
1454
1455   let Predicates = [prd, HasVLX] in {
1456     defm Z256 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info256>,
1457                 EVEX_V256;
1458     defm Z128 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info128>,
1459                 EVEX_V128;
1460   }
1461 }
1462
1463 multiclass avx512_icmp_packed_rmb_vl<bits<8> opc, string OpcodeStr,
1464                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo,
1465                                   Predicate prd> {
1466   let Predicates = [prd] in
1467   defm Z : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
1468            EVEX_V512;
1469
1470   let Predicates = [prd, HasVLX] in {
1471     defm Z256 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
1472                 EVEX_V256;
1473     defm Z128 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
1474                 EVEX_V128;
1475   }
1476 }
1477
1478 defm VPCMPEQB : avx512_icmp_packed_vl<0x74, "vpcmpeqb", X86pcmpeqm,
1479                       avx512vl_i8_info, HasBWI>,
1480                 EVEX_CD8<8, CD8VF>;
1481
1482 defm VPCMPEQW : avx512_icmp_packed_vl<0x75, "vpcmpeqw", X86pcmpeqm,
1483                       avx512vl_i16_info, HasBWI>,
1484                 EVEX_CD8<16, CD8VF>;
1485
1486 defm VPCMPEQD : avx512_icmp_packed_rmb_vl<0x76, "vpcmpeqd", X86pcmpeqm,
1487                       avx512vl_i32_info, HasAVX512>,
1488                 EVEX_CD8<32, CD8VF>;
1489
1490 defm VPCMPEQQ : avx512_icmp_packed_rmb_vl<0x29, "vpcmpeqq", X86pcmpeqm,
1491                       avx512vl_i64_info, HasAVX512>,
1492                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1493
1494 defm VPCMPGTB : avx512_icmp_packed_vl<0x64, "vpcmpgtb", X86pcmpgtm,
1495                       avx512vl_i8_info, HasBWI>,
1496                 EVEX_CD8<8, CD8VF>;
1497
1498 defm VPCMPGTW : avx512_icmp_packed_vl<0x65, "vpcmpgtw", X86pcmpgtm,
1499                       avx512vl_i16_info, HasBWI>,
1500                 EVEX_CD8<16, CD8VF>;
1501
1502 defm VPCMPGTD : avx512_icmp_packed_rmb_vl<0x66, "vpcmpgtd", X86pcmpgtm,
1503                       avx512vl_i32_info, HasAVX512>,
1504                 EVEX_CD8<32, CD8VF>;
1505
1506 defm VPCMPGTQ : avx512_icmp_packed_rmb_vl<0x37, "vpcmpgtq", X86pcmpgtm,
1507                       avx512vl_i64_info, HasAVX512>,
1508                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1509
1510 def : Pat<(v8i1 (X86pcmpgtm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1511             (COPY_TO_REGCLASS (VPCMPGTDZrr
1512             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1513             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1514
1515 def : Pat<(v8i1 (X86pcmpeqm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1516             (COPY_TO_REGCLASS (VPCMPEQDZrr
1517             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1518             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1519
1520 multiclass avx512_icmp_cc<bits<8> opc, string Suffix, SDNode OpNode,
1521                           X86VectorVTInfo _> {
1522   def rri : AVX512AIi8<opc, MRMSrcReg,
1523              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, AVX512ICC:$cc),
1524              !strconcat("vpcmp${cc}", Suffix,
1525                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1526              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1527                                        imm:$cc))],
1528              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1529   let mayLoad = 1 in
1530   def rmi : AVX512AIi8<opc, MRMSrcMem,
1531              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, AVX512ICC:$cc),
1532              !strconcat("vpcmp${cc}", Suffix,
1533                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1534              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1535                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
1536                               imm:$cc))],
1537              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1538   def rrik : AVX512AIi8<opc, MRMSrcReg,
1539               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1540                                       AVX512ICC:$cc),
1541               !strconcat("vpcmp${cc}", Suffix,
1542                          "\t{$src2, $src1, $dst {${mask}}|",
1543                          "$dst {${mask}}, $src1, $src2}"),
1544               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1545                                   (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1546                                           imm:$cc)))],
1547               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1548   let mayLoad = 1 in
1549   def rmik : AVX512AIi8<opc, MRMSrcMem,
1550               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1551                                     AVX512ICC:$cc),
1552               !strconcat("vpcmp${cc}", Suffix,
1553                          "\t{$src2, $src1, $dst {${mask}}|",
1554                          "$dst {${mask}}, $src1, $src2}"),
1555               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1556                                    (OpNode (_.VT _.RC:$src1),
1557                                       (_.VT (bitconvert (_.LdFrag addr:$src2))),
1558                                       imm:$cc)))],
1559               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1560
1561   // Accept explicit immediate argument form instead of comparison code.
1562   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1563     def rri_alt : AVX512AIi8<opc, MRMSrcReg,
1564                (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1565                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1566                           "$dst, $src1, $src2, $cc}"),
1567                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1568     let mayLoad = 1 in
1569     def rmi_alt : AVX512AIi8<opc, MRMSrcMem,
1570                (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1571                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1572                           "$dst, $src1, $src2, $cc}"),
1573                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1574     def rrik_alt : AVX512AIi8<opc, MRMSrcReg,
1575                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1576                                        u8imm:$cc),
1577                !strconcat("vpcmp", Suffix,
1578                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1579                           "$dst {${mask}}, $src1, $src2, $cc}"),
1580                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1581     let mayLoad = 1 in
1582     def rmik_alt : AVX512AIi8<opc, MRMSrcMem,
1583                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1584                                        u8imm:$cc),
1585                !strconcat("vpcmp", Suffix,
1586                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1587                           "$dst {${mask}}, $src1, $src2, $cc}"),
1588                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1589   }
1590 }
1591
1592 multiclass avx512_icmp_cc_rmb<bits<8> opc, string Suffix, SDNode OpNode,
1593                               X86VectorVTInfo _> :
1594            avx512_icmp_cc<opc, Suffix, OpNode, _> {
1595   def rmib : AVX512AIi8<opc, MRMSrcMem,
1596              (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1597                                      AVX512ICC:$cc),
1598              !strconcat("vpcmp${cc}", Suffix,
1599                         "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1600                         "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1601              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1602                                (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1603                                imm:$cc))],
1604              IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1605   def rmibk : AVX512AIi8<opc, MRMSrcMem,
1606               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1607                                        _.ScalarMemOp:$src2, AVX512ICC:$cc),
1608               !strconcat("vpcmp${cc}", Suffix,
1609                        "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1610                        "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1611               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1612                                   (OpNode (_.VT _.RC:$src1),
1613                                     (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1614                                     imm:$cc)))],
1615               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1616
1617   // Accept explicit immediate argument form instead of comparison code.
1618   let isAsmParserOnly = 1, hasSideEffects = 0, mayLoad = 1 in {
1619     def rmib_alt : AVX512AIi8<opc, MRMSrcMem,
1620                (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1621                                        u8imm:$cc),
1622                !strconcat("vpcmp", Suffix,
1623                    "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst|",
1624                    "$dst, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1625                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1626     def rmibk_alt : AVX512AIi8<opc, MRMSrcMem,
1627                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1628                                        _.ScalarMemOp:$src2, u8imm:$cc),
1629                !strconcat("vpcmp", Suffix,
1630                   "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1631                   "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1632                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1633   }
1634 }
1635
1636 multiclass avx512_icmp_cc_vl<bits<8> opc, string Suffix, SDNode OpNode,
1637                              AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1638   let Predicates = [prd] in
1639   defm Z : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info512>, EVEX_V512;
1640
1641   let Predicates = [prd, HasVLX] in {
1642     defm Z256 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info256>, EVEX_V256;
1643     defm Z128 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info128>, EVEX_V128;
1644   }
1645 }
1646
1647 multiclass avx512_icmp_cc_rmb_vl<bits<8> opc, string Suffix, SDNode OpNode,
1648                                 AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1649   let Predicates = [prd] in
1650   defm Z : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info512>,
1651            EVEX_V512;
1652
1653   let Predicates = [prd, HasVLX] in {
1654     defm Z256 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info256>,
1655                 EVEX_V256;
1656     defm Z128 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info128>,
1657                 EVEX_V128;
1658   }
1659 }
1660
1661 defm VPCMPB : avx512_icmp_cc_vl<0x3F, "b", X86cmpm, avx512vl_i8_info,
1662                                 HasBWI>, EVEX_CD8<8, CD8VF>;
1663 defm VPCMPUB : avx512_icmp_cc_vl<0x3E, "ub", X86cmpmu, avx512vl_i8_info,
1664                                  HasBWI>, EVEX_CD8<8, CD8VF>;
1665
1666 defm VPCMPW : avx512_icmp_cc_vl<0x3F, "w", X86cmpm, avx512vl_i16_info,
1667                                 HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1668 defm VPCMPUW : avx512_icmp_cc_vl<0x3E, "uw", X86cmpmu, avx512vl_i16_info,
1669                                  HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1670
1671 defm VPCMPD : avx512_icmp_cc_rmb_vl<0x1F, "d", X86cmpm, avx512vl_i32_info,
1672                                     HasAVX512>, EVEX_CD8<32, CD8VF>;
1673 defm VPCMPUD : avx512_icmp_cc_rmb_vl<0x1E, "ud", X86cmpmu, avx512vl_i32_info,
1674                                      HasAVX512>, EVEX_CD8<32, CD8VF>;
1675
1676 defm VPCMPQ : avx512_icmp_cc_rmb_vl<0x1F, "q", X86cmpm, avx512vl_i64_info,
1677                                     HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1678 defm VPCMPUQ : avx512_icmp_cc_rmb_vl<0x1E, "uq", X86cmpmu, avx512vl_i64_info,
1679                                      HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1680
1681 multiclass avx512_vcmp_common<X86VectorVTInfo _> {
1682
1683   defm  rri  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1684                    (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2,AVXCC:$cc),
1685                    "vcmp${cc}"#_.Suffix,
1686                    "$src2, $src1", "$src1, $src2",
1687                    (X86cmpm (_.VT _.RC:$src1),
1688                          (_.VT _.RC:$src2),
1689                            imm:$cc)>;
1690
1691   let mayLoad = 1 in {
1692     defm  rmi  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1693                   (outs _.KRC:$dst),(ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1694                   "vcmp${cc}"#_.Suffix,
1695                   "$src2, $src1", "$src1, $src2",
1696                   (X86cmpm (_.VT _.RC:$src1),
1697                           (_.VT (bitconvert (_.LdFrag addr:$src2))),
1698                           imm:$cc)>;
1699
1700     defm  rmbi : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1701                   (outs _.KRC:$dst),
1702                   (ins _.RC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1703                   "vcmp${cc}"#_.Suffix,
1704                   "${src2}"##_.BroadcastStr##", $src1",
1705                   "$src1, ${src2}"##_.BroadcastStr,
1706                   (X86cmpm (_.VT _.RC:$src1),
1707                           (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
1708                           imm:$cc)>,EVEX_B;
1709   }
1710   // Accept explicit immediate argument form instead of comparison code.
1711   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1712     defm  rri_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1713                          (outs _.KRC:$dst),
1714                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1715                          "vcmp"#_.Suffix,
1716                          "$cc, $src2, $src1", "$src1, $src2, $cc">;
1717
1718     let mayLoad = 1 in {
1719       defm rmi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1720                              (outs _.KRC:$dst),
1721                              (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1722                              "vcmp"#_.Suffix,
1723                              "$cc, $src2, $src1", "$src1, $src2, $cc">;
1724
1725       defm  rmbi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1726                          (outs _.KRC:$dst),
1727                          (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$cc),
1728                          "vcmp"#_.Suffix,
1729                          "$cc, ${src2}"##_.BroadcastStr##", $src1",
1730                          "$src1, ${src2}"##_.BroadcastStr##", $cc">,EVEX_B;
1731     }
1732  }
1733 }
1734
1735 multiclass avx512_vcmp_sae<X86VectorVTInfo _> {
1736   // comparison code form (VCMP[EQ/LT/LE/...]
1737   defm  rrib  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1738                      (outs _.KRC:$dst),(ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1739                      "vcmp${cc}"#_.Suffix,
1740                      "{sae}, $src2, $src1", "$src1, $src2,{sae}",
1741                      (X86cmpmRnd (_.VT _.RC:$src1),
1742                                     (_.VT _.RC:$src2),
1743                                     imm:$cc,
1744                                 (i32 FROUND_NO_EXC))>, EVEX_B;
1745
1746   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1747     defm  rrib_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1748                          (outs _.KRC:$dst),
1749                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1750                          "vcmp"#_.Suffix,
1751                          "$cc,{sae}, $src2, $src1",
1752                          "$src1, $src2,{sae}, $cc">, EVEX_B;
1753    }
1754 }
1755
1756 multiclass avx512_vcmp<AVX512VLVectorVTInfo _> {
1757   let Predicates = [HasAVX512] in {
1758     defm Z    : avx512_vcmp_common<_.info512>,
1759                 avx512_vcmp_sae<_.info512>, EVEX_V512;
1760
1761   }
1762   let Predicates = [HasAVX512,HasVLX] in {
1763    defm Z128 : avx512_vcmp_common<_.info128>, EVEX_V128;
1764    defm Z256 : avx512_vcmp_common<_.info256>, EVEX_V256;
1765   }
1766 }
1767
1768 defm VCMPPD : avx512_vcmp<avx512vl_f64_info>,
1769                           AVX512PDIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
1770 defm VCMPPS : avx512_vcmp<avx512vl_f32_info>,
1771                           AVX512PSIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
1772
1773 def : Pat<(v8i1 (X86cmpm (v8f32 VR256X:$src1), (v8f32 VR256X:$src2), imm:$cc)),
1774           (COPY_TO_REGCLASS (VCMPPSZrri
1775             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1776             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1777             imm:$cc), VK8)>;
1778 def : Pat<(v8i1 (X86cmpm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1779           (COPY_TO_REGCLASS (VPCMPDZrri
1780             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1781             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1782             imm:$cc), VK8)>;
1783 def : Pat<(v8i1 (X86cmpmu (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1784           (COPY_TO_REGCLASS (VPCMPUDZrri
1785             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1786             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1787             imm:$cc), VK8)>;
1788
1789 // ----------------------------------------------------------------
1790 // FPClass
1791 //handle fpclass instruction mask = fpclass(reg_vec, reg_vec, imm)
1792 //                                  fpclass(reg_vec, mem_vec, imm)
1793 //                                  fpclass(reg_vec, broadcast(eltVt), imm)
1794 multiclass avx512_vector_fpclass<bits<8> opc, string OpcodeStr, SDNode OpNode,
1795                                  X86VectorVTInfo _, string mem, string broadcast>{
1796   def rr : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
1797                       (ins _.RC:$src1, i32u8imm:$src2),
1798                       OpcodeStr##_.Suffix#"\t{$src2, $src1, $dst | $dst, $src1, $src2}",
1799                       [(set _.KRC:$dst,(OpNode (_.VT _.RC:$src1),
1800                                        (i32 imm:$src2)))], NoItinerary>;
1801   def rrk : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
1802                       (ins _.KRCWM:$mask, _.RC:$src1, i32u8imm:$src2),
1803                       OpcodeStr##_.Suffix#
1804                       "\t{$src2, $src1, $dst {${mask}}| $dst {${mask}}, $src1, $src2}",
1805                       [(set _.KRC:$dst,(or _.KRCWM:$mask, 
1806                                        (OpNode (_.VT _.RC:$src1),
1807                                        (i32 imm:$src2))))], NoItinerary>, EVEX_K;
1808   let mayLoad = 1 in {
1809     def rm : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
1810                       (ins _.MemOp:$src1, i32u8imm:$src2),
1811                       OpcodeStr##_.Suffix##mem#
1812                       "\t{$src2, $src1, $dst | $dst, $src1, $src2}",
1813                       [(set _.KRC:$dst,(OpNode 
1814                                        (_.VT (bitconvert (_.LdFrag addr:$src1))),
1815                                        (i32 imm:$src2)))], NoItinerary>;
1816     def rmk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
1817                       (ins _.KRCWM:$mask, _.MemOp:$src1, i32u8imm:$src2),
1818                       OpcodeStr##_.Suffix##mem#
1819                       "\t{$src2, $src1, $dst {${mask}} | $dst {${mask}}, $src1, $src2}",
1820                       [(set _.KRC:$dst, (or _.KRCWM:$mask, (OpNode 
1821                                     (_.VT (bitconvert (_.LdFrag addr:$src1))),
1822                                     (i32 imm:$src2))))], NoItinerary>, EVEX_K;
1823     def rmb : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
1824                       (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
1825                       OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
1826                                         _.BroadcastStr##", $dst | $dst, ${src1}"
1827                                                     ##_.BroadcastStr##", $src2}",
1828                       [(set _.KRC:$dst,(OpNode 
1829                                        (_.VT (X86VBroadcast 
1830                                              (_.ScalarLdFrag addr:$src1))),
1831                                        (i32 imm:$src2)))], NoItinerary>,EVEX_B;
1832     def rmbk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
1833                       (ins _.KRCWM:$mask, _.ScalarMemOp:$src1, i32u8imm:$src2),
1834                       OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
1835                             _.BroadcastStr##", $dst {${mask}} | $dst {${mask}}, ${src1}"##
1836                                                      _.BroadcastStr##", $src2}",
1837                       [(set _.KRC:$dst,(or _.KRCWM:$mask, (OpNode 
1838                                        (_.VT (X86VBroadcast 
1839                                              (_.ScalarLdFrag addr:$src1))),
1840                                        (i32 imm:$src2))))], NoItinerary>,
1841                                                             EVEX_B, EVEX_K;
1842   }
1843 }
1844
1845
1846 multiclass avx512_vector_fpclass_all<string OpcodeStr,
1847             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd, 
1848                                                               string broadcast>{
1849   let Predicates = [prd] in {
1850     defm Z    : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info512, "{z}", 
1851                                       broadcast>, EVEX_V512;
1852   }
1853   let Predicates = [prd, HasVLX] in {
1854     defm Z128 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info128, "{x}",
1855                                       broadcast>, EVEX_V128;
1856     defm Z256 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info256, "{y}",
1857                                       broadcast>, EVEX_V256;
1858   }
1859 }
1860
1861 multiclass avx512_fp_fpclass_all<string OpcodeStr, bits<8> opcVec,
1862                                  SDNode OpNode, Predicate prd>{
1863   defm PS : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f32_info, opcVec, 
1864                                       OpNode, prd, "{l}">, EVEX_CD8<32, CD8VF>;
1865   defm PD : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f64_info, opcVec, 
1866                                       OpNode, prd, "{q}">,EVEX_CD8<64, CD8VF> , VEX_W;
1867 }
1868
1869 defm VFPCLASS : avx512_fp_fpclass_all<"vfpclass", 0x66, X86Vfpclass, HasDQI>,
1870                                       AVX512AIi8Base,EVEX;
1871
1872 //-----------------------------------------------------------------
1873 // Mask register copy, including
1874 // - copy between mask registers
1875 // - load/store mask registers
1876 // - copy from GPR to mask register and vice versa
1877 //
1878 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
1879                          string OpcodeStr, RegisterClass KRC,
1880                          ValueType vvt, X86MemOperand x86memop> {
1881   let hasSideEffects = 0 in {
1882     def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
1883                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
1884     let mayLoad = 1 in
1885     def km : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
1886                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1887                [(set KRC:$dst, (vvt (load addr:$src)))]>;
1888     let mayStore = 1 in
1889     def mk : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
1890                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1891                [(store KRC:$src, addr:$dst)]>;
1892   }
1893 }
1894
1895 multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,
1896                              string OpcodeStr,
1897                              RegisterClass KRC, RegisterClass GRC> {
1898   let hasSideEffects = 0 in {
1899     def kr : I<opc_kr, MRMSrcReg, (outs KRC:$dst), (ins GRC:$src),
1900                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
1901     def rk : I<opc_rk, MRMSrcReg, (outs GRC:$dst), (ins KRC:$src),
1902                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
1903   }
1904 }
1905
1906 let Predicates = [HasDQI] in
1907   defm KMOVB : avx512_mask_mov<0x90, 0x90, 0x91, "kmovb", VK8, v8i1, i8mem>,
1908                avx512_mask_mov_gpr<0x92, 0x93, "kmovb", VK8, GR32>,
1909                VEX, PD;
1910
1911 let Predicates = [HasAVX512] in
1912   defm KMOVW : avx512_mask_mov<0x90, 0x90, 0x91, "kmovw", VK16, v16i1, i16mem>,
1913                avx512_mask_mov_gpr<0x92, 0x93, "kmovw", VK16, GR32>,
1914                VEX, PS;
1915
1916 let Predicates = [HasBWI] in {
1917   defm KMOVD : avx512_mask_mov<0x90, 0x90, 0x91, "kmovd", VK32, v32i1,i32mem>,
1918                VEX, PD, VEX_W;
1919   defm KMOVD : avx512_mask_mov_gpr<0x92, 0x93, "kmovd", VK32, GR32>,
1920                VEX, XD;
1921 }
1922
1923 let Predicates = [HasBWI] in {
1924   defm KMOVQ : avx512_mask_mov<0x90, 0x90, 0x91, "kmovq", VK64, v64i1, i64mem>,
1925                VEX, PS, VEX_W;
1926   defm KMOVQ : avx512_mask_mov_gpr<0x92, 0x93, "kmovq", VK64, GR64>,
1927                VEX, XD, VEX_W;
1928 }
1929
1930 // GR from/to mask register
1931 let Predicates = [HasDQI] in {
1932   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
1933             (KMOVBkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit))>;
1934   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
1935             (EXTRACT_SUBREG (KMOVBrk VK8:$src), sub_8bit)>;
1936 }
1937 let Predicates = [HasAVX512] in {
1938   def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
1939             (KMOVWkr (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit))>;
1940   def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
1941             (EXTRACT_SUBREG (KMOVWrk VK16:$src), sub_16bit)>;
1942 }
1943 let Predicates = [HasBWI] in {
1944   def : Pat<(v32i1 (bitconvert (i32 GR32:$src))), (KMOVDkr GR32:$src)>;
1945   def : Pat<(i32 (bitconvert (v32i1 VK32:$src))), (KMOVDrk VK32:$src)>;
1946 }
1947 let Predicates = [HasBWI] in {
1948   def : Pat<(v64i1 (bitconvert (i64 GR64:$src))), (KMOVQkr GR64:$src)>;
1949   def : Pat<(i64 (bitconvert (v64i1 VK64:$src))), (KMOVQrk VK64:$src)>;
1950 }
1951
1952 // Load/store kreg
1953 let Predicates = [HasDQI] in {
1954   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1955             (KMOVBmk addr:$dst, VK8:$src)>;
1956   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
1957             (KMOVBkm addr:$src)>;
1958
1959   def : Pat<(store VK4:$src, addr:$dst),
1960             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK4:$src, VK8))>;
1961   def : Pat<(store VK2:$src, addr:$dst),
1962             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK2:$src, VK8))>;
1963 }
1964 let Predicates = [HasAVX512, NoDQI] in {
1965   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1966             (KMOVWmk addr:$dst, (COPY_TO_REGCLASS VK8:$src, VK16))>;
1967   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
1968             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK8)>;
1969 }
1970 let Predicates = [HasAVX512] in {
1971   def : Pat<(store (i16 (bitconvert (v16i1 VK16:$src))), addr:$dst),
1972             (KMOVWmk addr:$dst, VK16:$src)>;
1973   def : Pat<(i1 (load addr:$src)),
1974             (COPY_TO_REGCLASS (AND16ri (i16 (SUBREG_TO_REG (i32 0),
1975                                               (MOV8rm addr:$src), sub_8bit)),
1976                                 (i16 1)), VK1)>;
1977   def : Pat<(v16i1 (bitconvert (i16 (load addr:$src)))),
1978             (KMOVWkm addr:$src)>;
1979 }
1980 let Predicates = [HasBWI] in {
1981   def : Pat<(store (i32 (bitconvert (v32i1 VK32:$src))), addr:$dst),
1982             (KMOVDmk addr:$dst, VK32:$src)>;
1983   def : Pat<(v32i1 (bitconvert (i32 (load addr:$src)))),
1984             (KMOVDkm addr:$src)>;
1985 }
1986 let Predicates = [HasBWI] in {
1987   def : Pat<(store (i64 (bitconvert (v64i1 VK64:$src))), addr:$dst),
1988             (KMOVQmk addr:$dst, VK64:$src)>;
1989   def : Pat<(v64i1 (bitconvert (i64 (load addr:$src)))),
1990             (KMOVQkm addr:$src)>;
1991 }
1992
1993 let Predicates = [HasAVX512] in {
1994   def : Pat<(i1 (trunc (i64 GR64:$src))),
1995             (COPY_TO_REGCLASS (KMOVWkr (AND32ri (EXTRACT_SUBREG $src, sub_32bit),
1996                                         (i32 1))), VK1)>;
1997
1998   def : Pat<(i1 (trunc (i32 GR32:$src))),
1999             (COPY_TO_REGCLASS (KMOVWkr (AND32ri $src, (i32 1))), VK1)>;
2000
2001   def : Pat<(i1 (trunc (i8 GR8:$src))),
2002        (COPY_TO_REGCLASS
2003         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit), (i32 1))),
2004        VK1)>;
2005   def : Pat<(i1 (trunc (i16 GR16:$src))),
2006        (COPY_TO_REGCLASS
2007         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), $src, sub_16bit), (i32 1))),
2008        VK1)>;
2009
2010   def : Pat<(i32 (zext VK1:$src)),
2011             (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1))>;
2012   def : Pat<(i32 (anyext VK1:$src)),
2013             (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16))>;
2014
2015   def : Pat<(i8 (zext VK1:$src)),
2016             (EXTRACT_SUBREG
2017              (AND32ri (KMOVWrk
2018                        (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)), sub_8bit)>;
2019   def : Pat<(i8 (anyext VK1:$src)),
2020               (EXTRACT_SUBREG
2021                 (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), sub_8bit)>;
2022
2023   def : Pat<(i64 (zext VK1:$src)),
2024             (AND64ri8 (SUBREG_TO_REG (i64 0),
2025              (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), sub_32bit), (i64 1))>;
2026   def : Pat<(i16 (zext VK1:$src)),
2027             (EXTRACT_SUBREG
2028              (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)),
2029               sub_16bit)>;
2030   def : Pat<(v16i1 (scalar_to_vector VK1:$src)),
2031             (COPY_TO_REGCLASS VK1:$src, VK16)>;
2032   def : Pat<(v8i1 (scalar_to_vector VK1:$src)),
2033             (COPY_TO_REGCLASS VK1:$src, VK8)>;
2034 }
2035 let Predicates = [HasBWI] in {
2036   def : Pat<(v32i1 (scalar_to_vector VK1:$src)),
2037             (COPY_TO_REGCLASS VK1:$src, VK32)>;
2038   def : Pat<(v64i1 (scalar_to_vector VK1:$src)),
2039             (COPY_TO_REGCLASS VK1:$src, VK64)>;
2040 }
2041
2042
2043 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
2044 let Predicates = [HasAVX512, NoDQI] in {
2045   // GR from/to 8-bit mask without native support
2046   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
2047             (COPY_TO_REGCLASS
2048              (KMOVWkr (MOVZX32rr8 GR8 :$src)), VK8)>;
2049   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
2050             (EXTRACT_SUBREG
2051               (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
2052               sub_8bit)>;
2053 }
2054
2055 let Predicates = [HasAVX512] in {
2056   def : Pat<(i1 (X86Vextract VK16:$src, (iPTR 0))),
2057             (COPY_TO_REGCLASS VK16:$src, VK1)>;
2058   def : Pat<(i1 (X86Vextract VK8:$src, (iPTR 0))),
2059             (COPY_TO_REGCLASS VK8:$src, VK1)>;
2060 }
2061 let Predicates = [HasBWI] in {
2062   def : Pat<(i1 (X86Vextract VK32:$src, (iPTR 0))),
2063             (COPY_TO_REGCLASS VK32:$src, VK1)>;
2064   def : Pat<(i1 (X86Vextract VK64:$src, (iPTR 0))),
2065             (COPY_TO_REGCLASS VK64:$src, VK1)>;
2066 }
2067
2068 // Mask unary operation
2069 // - KNOT
2070 multiclass avx512_mask_unop<bits<8> opc, string OpcodeStr,
2071                             RegisterClass KRC, SDPatternOperator OpNode,
2072                             Predicate prd> {
2073   let Predicates = [prd] in
2074     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
2075                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2076                [(set KRC:$dst, (OpNode KRC:$src))]>;
2077 }
2078
2079 multiclass avx512_mask_unop_all<bits<8> opc, string OpcodeStr,
2080                                 SDPatternOperator OpNode> {
2081   defm B : avx512_mask_unop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2082                             HasDQI>, VEX, PD;
2083   defm W : avx512_mask_unop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2084                             HasAVX512>, VEX, PS;
2085   defm D : avx512_mask_unop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2086                             HasBWI>, VEX, PD, VEX_W;
2087   defm Q : avx512_mask_unop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2088                             HasBWI>, VEX, PS, VEX_W;
2089 }
2090
2091 defm KNOT : avx512_mask_unop_all<0x44, "knot", not>;
2092
2093 multiclass avx512_mask_unop_int<string IntName, string InstName> {
2094   let Predicates = [HasAVX512] in
2095     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
2096                 (i16 GR16:$src)),
2097               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
2098               (v16i1 (COPY_TO_REGCLASS GR16:$src, VK16))), GR16)>;
2099 }
2100 defm : avx512_mask_unop_int<"knot", "KNOT">;
2101
2102 let Predicates = [HasDQI] in
2103 def : Pat<(xor VK8:$src1, (v8i1 immAllOnesV)), (KNOTBrr VK8:$src1)>;
2104 let Predicates = [HasAVX512] in
2105 def : Pat<(xor VK16:$src1, (v16i1 immAllOnesV)), (KNOTWrr VK16:$src1)>;
2106 let Predicates = [HasBWI] in
2107 def : Pat<(xor VK32:$src1, (v32i1 immAllOnesV)), (KNOTDrr VK32:$src1)>;
2108 let Predicates = [HasBWI] in
2109 def : Pat<(xor VK64:$src1, (v64i1 immAllOnesV)), (KNOTQrr VK64:$src1)>;
2110
2111 // KNL does not support KMOVB, 8-bit mask is promoted to 16-bit
2112 let Predicates = [HasAVX512, NoDQI] in {
2113 def : Pat<(xor VK8:$src1,  (v8i1 immAllOnesV)),
2114           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$src1, VK16)), VK8)>;
2115 def : Pat<(not VK8:$src),
2116           (COPY_TO_REGCLASS
2117             (KNOTWrr (COPY_TO_REGCLASS VK8:$src, VK16)), VK8)>;
2118 }
2119 def : Pat<(xor VK4:$src1,  (v4i1 immAllOnesV)),
2120           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK4:$src1, VK16)), VK4)>;
2121 def : Pat<(xor VK2:$src1,  (v2i1 immAllOnesV)),
2122           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK2:$src1, VK16)), VK2)>;
2123
2124 // Mask binary operation
2125 // - KAND, KANDN, KOR, KXNOR, KXOR
2126 multiclass avx512_mask_binop<bits<8> opc, string OpcodeStr,
2127                            RegisterClass KRC, SDPatternOperator OpNode,
2128                            Predicate prd, bit IsCommutable> {
2129   let Predicates = [prd], isCommutable = IsCommutable in
2130     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
2131                !strconcat(OpcodeStr,
2132                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2133                [(set KRC:$dst, (OpNode KRC:$src1, KRC:$src2))]>;
2134 }
2135
2136 multiclass avx512_mask_binop_all<bits<8> opc, string OpcodeStr,
2137                                SDPatternOperator OpNode, bit IsCommutable,
2138                                Predicate prdW = HasAVX512> {
2139   defm B : avx512_mask_binop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2140                              HasDQI, IsCommutable>, VEX_4V, VEX_L, PD;
2141   defm W : avx512_mask_binop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2142                              prdW, IsCommutable>, VEX_4V, VEX_L, PS;
2143   defm D : avx512_mask_binop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2144                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PD;
2145   defm Q : avx512_mask_binop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2146                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PS;
2147 }
2148
2149 def andn : PatFrag<(ops node:$i0, node:$i1), (and (not node:$i0), node:$i1)>;
2150 def xnor : PatFrag<(ops node:$i0, node:$i1), (not (xor node:$i0, node:$i1))>;
2151
2152 defm KAND  : avx512_mask_binop_all<0x41, "kand",  and,  1>;
2153 defm KOR   : avx512_mask_binop_all<0x45, "kor",   or,   1>;
2154 defm KXNOR : avx512_mask_binop_all<0x46, "kxnor", xnor, 1>;
2155 defm KXOR  : avx512_mask_binop_all<0x47, "kxor",  xor,  1>;
2156 defm KANDN : avx512_mask_binop_all<0x42, "kandn", andn, 0>;
2157 defm KADD  : avx512_mask_binop_all<0x4A, "kadd",  add,  1, HasDQI>;
2158
2159 multiclass avx512_mask_binop_int<string IntName, string InstName> {
2160   let Predicates = [HasAVX512] in
2161     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
2162                 (i16 GR16:$src1), (i16 GR16:$src2)),
2163               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
2164               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
2165               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
2166 }
2167
2168 defm : avx512_mask_binop_int<"kand",  "KAND">;
2169 defm : avx512_mask_binop_int<"kandn", "KANDN">;
2170 defm : avx512_mask_binop_int<"kor",   "KOR">;
2171 defm : avx512_mask_binop_int<"kxnor", "KXNOR">;
2172 defm : avx512_mask_binop_int<"kxor",  "KXOR">;
2173
2174 multiclass avx512_binop_pat<SDPatternOperator OpNode, Instruction Inst> {
2175   // With AVX512F, 8-bit mask is promoted to 16-bit mask,
2176   // for the DQI set, this type is legal and KxxxB instruction is used
2177   let Predicates = [NoDQI] in
2178   def : Pat<(OpNode VK8:$src1, VK8:$src2),
2179             (COPY_TO_REGCLASS
2180               (Inst (COPY_TO_REGCLASS VK8:$src1, VK16),
2181                     (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
2182
2183   // All types smaller than 8 bits require conversion anyway
2184   def : Pat<(OpNode VK1:$src1, VK1:$src2),
2185         (COPY_TO_REGCLASS (Inst
2186                            (COPY_TO_REGCLASS VK1:$src1, VK16),
2187                            (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
2188   def : Pat<(OpNode VK2:$src1, VK2:$src2),
2189         (COPY_TO_REGCLASS (Inst
2190                            (COPY_TO_REGCLASS VK2:$src1, VK16),
2191                            (COPY_TO_REGCLASS VK2:$src2, VK16)), VK1)>;
2192   def : Pat<(OpNode VK4:$src1, VK4:$src2),
2193         (COPY_TO_REGCLASS (Inst
2194                            (COPY_TO_REGCLASS VK4:$src1, VK16),
2195                            (COPY_TO_REGCLASS VK4:$src2, VK16)), VK1)>;
2196 }
2197
2198 defm : avx512_binop_pat<and,  KANDWrr>;
2199 defm : avx512_binop_pat<andn, KANDNWrr>;
2200 defm : avx512_binop_pat<or,   KORWrr>;
2201 defm : avx512_binop_pat<xnor, KXNORWrr>;
2202 defm : avx512_binop_pat<xor,  KXORWrr>;
2203
2204 def : Pat<(xor (xor VK16:$src1, VK16:$src2), (v16i1 immAllOnesV)),
2205           (KXNORWrr VK16:$src1, VK16:$src2)>;
2206 def : Pat<(xor (xor VK8:$src1, VK8:$src2), (v8i1 immAllOnesV)),
2207           (KXNORBrr VK8:$src1, VK8:$src2)>, Requires<[HasDQI]>;
2208 def : Pat<(xor (xor VK32:$src1, VK32:$src2), (v32i1 immAllOnesV)),
2209           (KXNORDrr VK32:$src1, VK32:$src2)>, Requires<[HasBWI]>;
2210 def : Pat<(xor (xor VK64:$src1, VK64:$src2), (v64i1 immAllOnesV)),
2211           (KXNORQrr VK64:$src1, VK64:$src2)>, Requires<[HasBWI]>;
2212
2213 let Predicates = [NoDQI] in
2214 def : Pat<(xor (xor VK8:$src1, VK8:$src2), (v8i1 immAllOnesV)),
2215           (COPY_TO_REGCLASS (KXNORWrr (COPY_TO_REGCLASS VK8:$src1, VK16),
2216                              (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
2217
2218 def : Pat<(xor (xor VK4:$src1, VK4:$src2), (v4i1 immAllOnesV)),
2219           (COPY_TO_REGCLASS (KXNORWrr (COPY_TO_REGCLASS VK4:$src1, VK16),
2220                              (COPY_TO_REGCLASS VK4:$src2, VK16)), VK4)>;
2221
2222 def : Pat<(xor (xor VK2:$src1, VK2:$src2), (v2i1 immAllOnesV)),
2223           (COPY_TO_REGCLASS (KXNORWrr (COPY_TO_REGCLASS VK2:$src1, VK16),
2224                              (COPY_TO_REGCLASS VK2:$src2, VK16)), VK2)>;
2225
2226 def : Pat<(xor (xor VK1:$src1, VK1:$src2), (i1 1)),
2227           (COPY_TO_REGCLASS (KXNORWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
2228                              (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
2229
2230 // Mask unpacking
2231 multiclass avx512_mask_unpck<string Suffix,RegisterClass KRC, ValueType VT,
2232                              RegisterClass KRCSrc, Predicate prd> {
2233   let Predicates = [prd] in {
2234     def rr : I<0x4b, MRMSrcReg, (outs KRC:$dst),
2235                (ins KRC:$src1, KRC:$src2),
2236                "kunpck"#Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
2237                VEX_4V, VEX_L;
2238
2239     def : Pat<(VT (concat_vectors KRCSrc:$src1, KRCSrc:$src2)),
2240               (!cast<Instruction>(NAME##rr)
2241                         (COPY_TO_REGCLASS KRCSrc:$src2, KRC),
2242                         (COPY_TO_REGCLASS KRCSrc:$src1, KRC))>;
2243   }
2244 }
2245
2246 defm KUNPCKBW : avx512_mask_unpck<"bw", VK16, v16i1, VK8, HasAVX512>, PD;
2247 defm KUNPCKWD : avx512_mask_unpck<"wd", VK32, v32i1, VK16, HasBWI>, PS;
2248 defm KUNPCKDQ : avx512_mask_unpck<"dq", VK64, v64i1, VK32, HasBWI>, PS, VEX_W;
2249
2250 multiclass avx512_mask_unpck_int<string IntName, string InstName> {
2251   let Predicates = [HasAVX512] in
2252     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_bw")
2253                 (i16 GR16:$src1), (i16 GR16:$src2)),
2254               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"BWrr")
2255               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
2256               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
2257 }
2258 defm : avx512_mask_unpck_int<"kunpck",  "KUNPCK">;
2259
2260 // Mask bit testing
2261 multiclass avx512_mask_testop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2262                               SDNode OpNode, Predicate prd> {
2263   let Predicates = [prd], Defs = [EFLAGS] in
2264     def rr : I<opc, MRMSrcReg, (outs), (ins KRC:$src1, KRC:$src2),
2265                !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2266                [(set EFLAGS, (OpNode KRC:$src1, KRC:$src2))]>;
2267 }
2268
2269 multiclass avx512_mask_testop_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
2270                                 Predicate prdW = HasAVX512> {
2271   defm B : avx512_mask_testop<opc, OpcodeStr#"b", VK8, OpNode, HasDQI>,
2272                                                                 VEX, PD;
2273   defm W : avx512_mask_testop<opc, OpcodeStr#"w", VK16, OpNode, prdW>,
2274                                                                 VEX, PS;
2275   defm Q : avx512_mask_testop<opc, OpcodeStr#"q", VK64, OpNode, HasBWI>,
2276                                                                 VEX, PS, VEX_W;
2277   defm D : avx512_mask_testop<opc, OpcodeStr#"d", VK32, OpNode, HasBWI>,
2278                                                                 VEX, PD, VEX_W;
2279 }
2280
2281 defm KORTEST : avx512_mask_testop_w<0x98, "kortest", X86kortest>;
2282 defm KTEST   : avx512_mask_testop_w<0x99, "ktest", X86ktest, HasDQI>;
2283
2284 // Mask shift
2285 multiclass avx512_mask_shiftop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2286                              SDNode OpNode> {
2287   let Predicates = [HasAVX512] in
2288     def ri : Ii8<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src, u8imm:$imm),
2289                  !strconcat(OpcodeStr,
2290                             "\t{$imm, $src, $dst|$dst, $src, $imm}"),
2291                             [(set KRC:$dst, (OpNode KRC:$src, (i8 imm:$imm)))]>;
2292 }
2293
2294 multiclass avx512_mask_shiftop_w<bits<8> opc1, bits<8> opc2, string OpcodeStr,
2295                                SDNode OpNode> {
2296   defm W : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
2297                                VEX, TAPD, VEX_W;
2298   let Predicates = [HasDQI] in
2299   defm B : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "b"), VK8, OpNode>,
2300                                VEX, TAPD;
2301   let Predicates = [HasBWI] in {
2302   defm Q : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "q"), VK64, OpNode>,
2303                                VEX, TAPD, VEX_W;
2304   let Predicates = [HasDQI] in
2305   defm D : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "d"), VK32, OpNode>,
2306                                VEX, TAPD;
2307   }
2308 }
2309
2310 defm KSHIFTL : avx512_mask_shiftop_w<0x32, 0x33, "kshiftl", X86vshli>;
2311 defm KSHIFTR : avx512_mask_shiftop_w<0x30, 0x31, "kshiftr", X86vsrli>;
2312
2313 // Mask setting all 0s or 1s
2314 multiclass avx512_mask_setop<RegisterClass KRC, ValueType VT, PatFrag Val> {
2315   let Predicates = [HasAVX512] in
2316     let isReMaterializable = 1, isAsCheapAsAMove = 1, isPseudo = 1 in
2317       def #NAME# : I<0, Pseudo, (outs KRC:$dst), (ins), "",
2318                      [(set KRC:$dst, (VT Val))]>;
2319 }
2320
2321 multiclass avx512_mask_setop_w<PatFrag Val> {
2322   defm B : avx512_mask_setop<VK8,   v8i1, Val>;
2323   defm W : avx512_mask_setop<VK16, v16i1, Val>;
2324   defm D : avx512_mask_setop<VK32,  v32i1, Val>;
2325   defm Q : avx512_mask_setop<VK64, v64i1, Val>;
2326 }
2327
2328 defm KSET0 : avx512_mask_setop_w<immAllZerosV>;
2329 defm KSET1 : avx512_mask_setop_w<immAllOnesV>;
2330
2331 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
2332 let Predicates = [HasAVX512] in {
2333   def : Pat<(v8i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK8)>;
2334   def : Pat<(v8i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK8)>;
2335   def : Pat<(v4i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK4)>;
2336   def : Pat<(v2i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK2)>;
2337   def : Pat<(i1 0), (COPY_TO_REGCLASS (KSET0W), VK1)>;
2338   def : Pat<(i1 1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2339   def : Pat<(i1 -1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2340 }
2341 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 0))),
2342           (v8i1 (COPY_TO_REGCLASS VK16:$src, VK8))>;
2343
2344 def : Pat<(v16i1 (insert_subvector undef, (v8i1 VK8:$src), (iPTR 0))),
2345           (v16i1 (COPY_TO_REGCLASS VK8:$src, VK16))>;
2346
2347 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 8))),
2348           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri VK16:$src, (i8 8)), VK8))>;
2349
2350 def : Pat<(v32i1 (extract_subvector (v64i1 VK64:$src), (iPTR 0))),
2351           (v32i1 (COPY_TO_REGCLASS VK64:$src, VK32))>;
2352
2353 def : Pat<(v32i1 (extract_subvector (v64i1 VK64:$src), (iPTR 32))),
2354           (v32i1 (COPY_TO_REGCLASS (KSHIFTRQri VK64:$src, (i8 32)), VK32))>;
2355
2356 let Predicates = [HasVLX] in {
2357   def : Pat<(v8i1 (insert_subvector undef, (v4i1 VK4:$src), (iPTR 0))),
2358             (v8i1 (COPY_TO_REGCLASS VK4:$src, VK8))>;
2359   def : Pat<(v8i1 (insert_subvector undef, (v2i1 VK2:$src), (iPTR 0))),
2360             (v8i1 (COPY_TO_REGCLASS VK2:$src, VK8))>;
2361   def : Pat<(v4i1 (insert_subvector undef, (v2i1 VK2:$src), (iPTR 0))),
2362             (v4i1 (COPY_TO_REGCLASS VK2:$src, VK4))>;
2363   def : Pat<(v4i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
2364             (v4i1 (COPY_TO_REGCLASS VK8:$src, VK4))>;
2365   def : Pat<(v2i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
2366             (v2i1 (COPY_TO_REGCLASS VK8:$src, VK2))>;
2367 }
2368
2369 def : Pat<(v8i1 (X86vshli VK8:$src, (i8 imm:$imm))),
2370           (v8i1 (COPY_TO_REGCLASS
2371                  (KSHIFTLWri (COPY_TO_REGCLASS VK8:$src, VK16),
2372                   (I8Imm $imm)), VK8))>, Requires<[HasAVX512, NoDQI]>;
2373
2374 def : Pat<(v8i1 (X86vsrli VK8:$src, (i8 imm:$imm))),
2375           (v8i1 (COPY_TO_REGCLASS
2376                  (KSHIFTRWri (COPY_TO_REGCLASS VK8:$src, VK16),
2377                   (I8Imm $imm)), VK8))>, Requires<[HasAVX512, NoDQI]>;
2378
2379 def : Pat<(v4i1 (X86vshli VK4:$src, (i8 imm:$imm))),
2380           (v4i1 (COPY_TO_REGCLASS
2381                  (KSHIFTLWri (COPY_TO_REGCLASS VK4:$src, VK16),
2382                   (I8Imm $imm)), VK4))>, Requires<[HasAVX512]>;
2383
2384 def : Pat<(v4i1 (X86vsrli VK4:$src, (i8 imm:$imm))),
2385           (v4i1 (COPY_TO_REGCLASS
2386                  (KSHIFTRWri (COPY_TO_REGCLASS VK4:$src, VK16),
2387                   (I8Imm $imm)), VK4))>, Requires<[HasAVX512]>;
2388
2389 //===----------------------------------------------------------------------===//
2390 // AVX-512 - Aligned and unaligned load and store
2391 //
2392
2393
2394 multiclass avx512_load<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2395                          PatFrag ld_frag, PatFrag mload,
2396                          bit IsReMaterializable = 1> {
2397   let hasSideEffects = 0 in {
2398   def rr : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst), (ins _.RC:$src),
2399                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
2400                     _.ExeDomain>, EVEX;
2401   def rrkz : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2402                       (ins _.KRCWM:$mask,  _.RC:$src),
2403                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
2404                        "${dst} {${mask}} {z}, $src}"), [], _.ExeDomain>,
2405                        EVEX, EVEX_KZ;
2406
2407   let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable,
2408       SchedRW = [WriteLoad] in
2409   def rm : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst), (ins _.MemOp:$src),
2410                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2411                     [(set _.RC:$dst, (_.VT (bitconvert (ld_frag addr:$src))))],
2412                     _.ExeDomain>, EVEX;
2413
2414   let Constraints = "$src0 = $dst" in {
2415   def rrk : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2416                     (ins _.RC:$src0, _.KRCWM:$mask, _.RC:$src1),
2417                     !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2418                     "${dst} {${mask}}, $src1}"),
2419                     [(set _.RC:$dst, (_.VT (vselect _.KRCWM:$mask,
2420                                         (_.VT _.RC:$src1),
2421                                         (_.VT _.RC:$src0))))], _.ExeDomain>,
2422                      EVEX, EVEX_K;
2423   let mayLoad = 1, SchedRW = [WriteLoad] in
2424     def rmk : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2425                      (ins _.RC:$src0, _.KRCWM:$mask, _.MemOp:$src1),
2426                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2427                       "${dst} {${mask}}, $src1}"),
2428                      [(set _.RC:$dst, (_.VT
2429                          (vselect _.KRCWM:$mask,
2430                           (_.VT (bitconvert (ld_frag addr:$src1))),
2431                            (_.VT _.RC:$src0))))], _.ExeDomain>, EVEX, EVEX_K;
2432   }
2433   let mayLoad = 1, SchedRW = [WriteLoad] in
2434   def rmkz : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2435                   (ins _.KRCWM:$mask, _.MemOp:$src),
2436                   OpcodeStr #"\t{$src, ${dst} {${mask}} {z}|"#
2437                                 "${dst} {${mask}} {z}, $src}",
2438                   [(set _.RC:$dst, (_.VT (vselect _.KRCWM:$mask,
2439                     (_.VT (bitconvert (ld_frag addr:$src))), _.ImmAllZerosV)))],
2440                   _.ExeDomain>, EVEX, EVEX_KZ;
2441   }
2442   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, undef)),
2443             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2444
2445   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, _.ImmAllZerosV)),
2446             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2447
2448   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src0))),
2449             (!cast<Instruction>(NAME#_.ZSuffix##rmk) _.RC:$src0,
2450              _.KRCWM:$mask, addr:$ptr)>;
2451 }
2452
2453 multiclass avx512_alignedload_vl<bits<8> opc, string OpcodeStr,
2454                                   AVX512VLVectorVTInfo _,
2455                                   Predicate prd,
2456                                   bit IsReMaterializable = 1> {
2457   let Predicates = [prd] in
2458   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.AlignedLdFrag,
2459                        masked_load_aligned512, IsReMaterializable>, EVEX_V512;
2460
2461   let Predicates = [prd, HasVLX] in {
2462   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.AlignedLdFrag,
2463                           masked_load_aligned256, IsReMaterializable>, EVEX_V256;
2464   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.AlignedLdFrag,
2465                           masked_load_aligned128, IsReMaterializable>, EVEX_V128;
2466   }
2467 }
2468
2469 multiclass avx512_load_vl<bits<8> opc, string OpcodeStr,
2470                                   AVX512VLVectorVTInfo _,
2471                                   Predicate prd,
2472                                   bit IsReMaterializable = 1> {
2473   let Predicates = [prd] in
2474   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.LdFrag,
2475                        masked_load_unaligned, IsReMaterializable>, EVEX_V512;
2476
2477   let Predicates = [prd, HasVLX] in {
2478   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.LdFrag,
2479                          masked_load_unaligned, IsReMaterializable>, EVEX_V256;
2480   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.LdFrag,
2481                          masked_load_unaligned, IsReMaterializable>, EVEX_V128;
2482   }
2483 }
2484
2485 multiclass avx512_store<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2486                         PatFrag st_frag, PatFrag mstore> {
2487   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
2488   def rr_alt : AVX512PI<opc, MRMDestReg, (outs _.RC:$dst), (ins _.RC:$src),
2489                         OpcodeStr # "\t{$src, $dst|$dst, $src}", [],
2490                         _.ExeDomain>, EVEX;
2491   let Constraints = "$src1 = $dst" in
2492   def rrk_alt : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2493                          (ins _.RC:$src1, _.KRCWM:$mask, _.RC:$src2),
2494                          OpcodeStr #
2495                          "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}",
2496                          [], _.ExeDomain>,  EVEX, EVEX_K;
2497   def rrkz_alt : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2498                           (ins _.KRCWM:$mask, _.RC:$src),
2499                           OpcodeStr #
2500                           "\t{$src, ${dst} {${mask}} {z}|" #
2501                           "${dst} {${mask}} {z}, $src}",
2502                           [], _.ExeDomain>, EVEX, EVEX_KZ;
2503   }
2504   let mayStore = 1 in {
2505   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins _.MemOp:$dst, _.RC:$src),
2506                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2507                     [(st_frag (_.VT _.RC:$src), addr:$dst)], _.ExeDomain>, EVEX;
2508   def mrk : AVX512PI<opc, MRMDestMem, (outs),
2509                      (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
2510               OpcodeStr # "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}",
2511                [], _.ExeDomain>, EVEX, EVEX_K;
2512   }
2513
2514   def: Pat<(mstore addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src)),
2515            (!cast<Instruction>(NAME#_.ZSuffix##mrk) addr:$ptr,
2516                                                     _.KRCWM:$mask, _.RC:$src)>;
2517 }
2518
2519
2520 multiclass avx512_store_vl< bits<8> opc, string OpcodeStr,
2521                             AVX512VLVectorVTInfo _, Predicate prd> {
2522   let Predicates = [prd] in
2523   defm Z : avx512_store<opc, OpcodeStr, _.info512, store,
2524                         masked_store_unaligned>, EVEX_V512;
2525
2526   let Predicates = [prd, HasVLX] in {
2527     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, store,
2528                              masked_store_unaligned>, EVEX_V256;
2529     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, store,
2530                              masked_store_unaligned>, EVEX_V128;
2531   }
2532 }
2533
2534 multiclass avx512_alignedstore_vl<bits<8> opc, string OpcodeStr,
2535                                   AVX512VLVectorVTInfo _,  Predicate prd> {
2536   let Predicates = [prd] in
2537   defm Z : avx512_store<opc, OpcodeStr, _.info512, alignedstore512,
2538                         masked_store_aligned512>, EVEX_V512;
2539
2540   let Predicates = [prd, HasVLX] in {
2541     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, alignedstore256,
2542                              masked_store_aligned256>, EVEX_V256;
2543     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, alignedstore,
2544                              masked_store_aligned128>, EVEX_V128;
2545   }
2546 }
2547
2548 defm VMOVAPS : avx512_alignedload_vl<0x28, "vmovaps", avx512vl_f32_info,
2549                                      HasAVX512>,
2550                avx512_alignedstore_vl<0x29, "vmovaps", avx512vl_f32_info,
2551                                       HasAVX512>,  PS, EVEX_CD8<32, CD8VF>;
2552
2553 defm VMOVAPD : avx512_alignedload_vl<0x28, "vmovapd", avx512vl_f64_info,
2554                                      HasAVX512>,
2555                avx512_alignedstore_vl<0x29, "vmovapd", avx512vl_f64_info,
2556                                      HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2557
2558 defm VMOVUPS : avx512_load_vl<0x10, "vmovups", avx512vl_f32_info, HasAVX512>,
2559                avx512_store_vl<0x11, "vmovups", avx512vl_f32_info, HasAVX512>,
2560                               PS, EVEX_CD8<32, CD8VF>;
2561
2562 defm VMOVUPD : avx512_load_vl<0x10, "vmovupd", avx512vl_f64_info, HasAVX512, 0>,
2563                avx512_store_vl<0x11, "vmovupd", avx512vl_f64_info, HasAVX512>,
2564                PD, VEX_W, EVEX_CD8<64, CD8VF>;
2565
2566 def: Pat<(v8f64 (int_x86_avx512_mask_loadu_pd_512 addr:$ptr,
2567                 (bc_v8f64 (v16i32 immAllZerosV)), GR8:$mask)),
2568        (VMOVUPDZrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
2569
2570 def: Pat<(v16f32 (int_x86_avx512_mask_loadu_ps_512 addr:$ptr,
2571                  (bc_v16f32 (v16i32 immAllZerosV)), GR16:$mask)),
2572        (VMOVUPSZrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
2573
2574 def: Pat<(v8f64 (int_x86_avx512_mask_load_pd_512 addr:$ptr,
2575                 (bc_v8f64 (v16i32 immAllZerosV)), GR8:$mask)),
2576        (VMOVAPDZrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
2577
2578 def: Pat<(v16f32 (int_x86_avx512_mask_load_ps_512 addr:$ptr,
2579                  (bc_v16f32 (v16i32 immAllZerosV)), GR16:$mask)),
2580        (VMOVAPSZrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
2581
2582 def: Pat<(v8f64 (int_x86_avx512_mask_load_pd_512 addr:$ptr,
2583                 (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
2584        (VMOVAPDZrm addr:$ptr)>;
2585
2586 def: Pat<(v16f32 (int_x86_avx512_mask_load_ps_512 addr:$ptr,
2587                  (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
2588        (VMOVAPSZrm addr:$ptr)>;
2589
2590 def: Pat<(int_x86_avx512_mask_storeu_ps_512 addr:$ptr, (v16f32 VR512:$src),
2591           GR16:$mask),
2592          (VMOVUPSZmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
2593             VR512:$src)>;
2594 def: Pat<(int_x86_avx512_mask_storeu_pd_512 addr:$ptr, (v8f64 VR512:$src),
2595           GR8:$mask),
2596          (VMOVUPDZmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
2597             VR512:$src)>;
2598
2599 def: Pat<(int_x86_avx512_mask_store_ps_512 addr:$ptr, (v16f32 VR512:$src),
2600           GR16:$mask),
2601          (VMOVAPSZmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
2602             VR512:$src)>;
2603 def: Pat<(int_x86_avx512_mask_store_pd_512 addr:$ptr, (v8f64 VR512:$src),
2604           GR8:$mask),
2605          (VMOVAPDZmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
2606             VR512:$src)>;
2607
2608 let Predicates = [HasAVX512, NoVLX] in {
2609 def: Pat<(X86mstore addr:$ptr, VK8WM:$mask, (v8f32 VR256:$src)),
2610          (VMOVUPSZmrk addr:$ptr,
2611          (v16i1 (COPY_TO_REGCLASS VK8WM:$mask, VK16WM)),
2612          (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256:$src, sub_ymm))>;
2613
2614 def: Pat<(v8f32 (masked_load addr:$ptr, VK8WM:$mask, undef)),
2615          (v8f32 (EXTRACT_SUBREG (v16f32 (VMOVUPSZrmkz
2616           (v16i1 (COPY_TO_REGCLASS VK8WM:$mask, VK16WM)), addr:$ptr)), sub_ymm))>;
2617
2618 def: Pat<(v8f32 (masked_load addr:$ptr, VK8WM:$mask, (v8f32 VR256:$src0))),
2619          (v8f32 (EXTRACT_SUBREG (v16f32 (VMOVUPSZrmk
2620          (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256:$src0, sub_ymm),
2621           (v16i1 (COPY_TO_REGCLASS VK8WM:$mask, VK16WM)), addr:$ptr)), sub_ymm))>;
2622 }
2623
2624 defm VMOVDQA32 : avx512_alignedload_vl<0x6F, "vmovdqa32", avx512vl_i32_info,
2625                                        HasAVX512>,
2626                  avx512_alignedstore_vl<0x7F, "vmovdqa32", avx512vl_i32_info,
2627                                        HasAVX512>, PD, EVEX_CD8<32, CD8VF>;
2628
2629 defm VMOVDQA64 : avx512_alignedload_vl<0x6F, "vmovdqa64", avx512vl_i64_info,
2630                                        HasAVX512>,
2631                  avx512_alignedstore_vl<0x7F, "vmovdqa64", avx512vl_i64_info,
2632                                     HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2633
2634 defm VMOVDQU8 : avx512_load_vl<0x6F, "vmovdqu8", avx512vl_i8_info, HasBWI>,
2635                  avx512_store_vl<0x7F, "vmovdqu8", avx512vl_i8_info,
2636                                  HasBWI>, XD, EVEX_CD8<8, CD8VF>;
2637
2638 defm VMOVDQU16 : avx512_load_vl<0x6F, "vmovdqu16", avx512vl_i16_info, HasBWI>,
2639                  avx512_store_vl<0x7F, "vmovdqu16", avx512vl_i16_info,
2640                                  HasBWI>, XD, VEX_W, EVEX_CD8<16, CD8VF>;
2641
2642 defm VMOVDQU32 : avx512_load_vl<0x6F, "vmovdqu32", avx512vl_i32_info, HasAVX512>,
2643                  avx512_store_vl<0x7F, "vmovdqu32", avx512vl_i32_info,
2644                                  HasAVX512>, XS, EVEX_CD8<32, CD8VF>;
2645
2646 defm VMOVDQU64 : avx512_load_vl<0x6F, "vmovdqu64", avx512vl_i64_info, HasAVX512>,
2647                  avx512_store_vl<0x7F, "vmovdqu64", avx512vl_i64_info,
2648                                  HasAVX512>, XS, VEX_W, EVEX_CD8<64, CD8VF>;
2649
2650 def: Pat<(v16i32 (int_x86_avx512_mask_loadu_d_512 addr:$ptr,
2651                  (v16i32 immAllZerosV), GR16:$mask)),
2652        (VMOVDQU32Zrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
2653
2654 def: Pat<(v8i64 (int_x86_avx512_mask_loadu_q_512 addr:$ptr,
2655                 (bc_v8i64 (v16i32 immAllZerosV)), GR8:$mask)),
2656        (VMOVDQU64Zrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
2657
2658 def: Pat<(int_x86_avx512_mask_storeu_d_512 addr:$ptr, (v16i32 VR512:$src),
2659             GR16:$mask),
2660          (VMOVDQU32Zmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
2661             VR512:$src)>;
2662 def: Pat<(int_x86_avx512_mask_storeu_q_512 addr:$ptr, (v8i64 VR512:$src),
2663             GR8:$mask),
2664          (VMOVDQU64Zmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
2665             VR512:$src)>;
2666
2667 let AddedComplexity = 20 in {
2668 def : Pat<(v8i64 (vselect VK8WM:$mask, (v8i64 VR512:$src),
2669                           (bc_v8i64 (v16i32 immAllZerosV)))),
2670                   (VMOVDQU64Zrrkz VK8WM:$mask, VR512:$src)>;
2671
2672 def : Pat<(v8i64 (vselect VK8WM:$mask, (bc_v8i64 (v16i32 immAllZerosV)),
2673                           (v8i64 VR512:$src))),
2674    (VMOVDQU64Zrrkz (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$mask, VK16)),
2675                                               VK8), VR512:$src)>;
2676
2677 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 VR512:$src),
2678                            (v16i32 immAllZerosV))),
2679                   (VMOVDQU32Zrrkz VK16WM:$mask, VR512:$src)>;
2680
2681 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 immAllZerosV),
2682                            (v16i32 VR512:$src))),
2683                   (VMOVDQU32Zrrkz (KNOTWrr VK16WM:$mask), VR512:$src)>;
2684 }
2685 // NoVLX patterns
2686 let Predicates = [HasAVX512, NoVLX] in {
2687 def: Pat<(X86mstore addr:$ptr, VK8WM:$mask, (v8i32 VR256:$src)),
2688          (VMOVDQU32Zmrk addr:$ptr,
2689          (v16i1 (COPY_TO_REGCLASS VK8WM:$mask, VK16WM)),
2690          (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256:$src, sub_ymm))>;
2691
2692 def: Pat<(v8i32 (masked_load addr:$ptr, VK8WM:$mask, undef)),
2693          (v8i32 (EXTRACT_SUBREG (v16i32 (VMOVDQU32Zrmkz
2694           (v16i1 (COPY_TO_REGCLASS VK8WM:$mask, VK16WM)), addr:$ptr)), sub_ymm))>;
2695 }
2696
2697 // Move Int Doubleword to Packed Double Int
2698 //
2699 def VMOVDI2PDIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR32:$src),
2700                       "vmovd\t{$src, $dst|$dst, $src}",
2701                       [(set VR128X:$dst,
2702                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
2703                         EVEX, VEX_LIG;
2704 def VMOVDI2PDIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst), (ins i32mem:$src),
2705                       "vmovd\t{$src, $dst|$dst, $src}",
2706                       [(set VR128X:$dst,
2707                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
2708                         IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2709 def VMOV64toPQIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR64:$src),
2710                       "vmovq\t{$src, $dst|$dst, $src}",
2711                         [(set VR128X:$dst,
2712                           (v2i64 (scalar_to_vector GR64:$src)))],
2713                           IIC_SSE_MOVDQ>, EVEX, VEX_W, VEX_LIG;
2714 let isCodeGenOnly = 1 in {
2715 def VMOV64toSDZrr : AVX512BI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
2716                        "vmovq\t{$src, $dst|$dst, $src}",
2717                        [(set FR64:$dst, (bitconvert GR64:$src))],
2718                        IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2719 def VMOVSDto64Zrr : AVX512BI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
2720                          "vmovq\t{$src, $dst|$dst, $src}",
2721                          [(set GR64:$dst, (bitconvert FR64:$src))],
2722                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2723 }
2724 def VMOVSDto64Zmr : AVX512BI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
2725                          "vmovq\t{$src, $dst|$dst, $src}",
2726                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
2727                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteStore]>,
2728                          EVEX_CD8<64, CD8VT1>;
2729
2730 // Move Int Doubleword to Single Scalar
2731 //
2732 let isCodeGenOnly = 1 in {
2733 def VMOVDI2SSZrr  : AVX512BI<0x6E, MRMSrcReg, (outs FR32X:$dst), (ins GR32:$src),
2734                       "vmovd\t{$src, $dst|$dst, $src}",
2735                       [(set FR32X:$dst, (bitconvert GR32:$src))],
2736                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG;
2737
2738 def VMOVDI2SSZrm  : AVX512BI<0x6E, MRMSrcMem, (outs FR32X:$dst), (ins i32mem:$src),
2739                       "vmovd\t{$src, $dst|$dst, $src}",
2740                       [(set FR32X:$dst, (bitconvert (loadi32 addr:$src)))],
2741                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2742 }
2743
2744 // Move doubleword from xmm register to r/m32
2745 //
2746 def VMOVPDI2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128X:$src),
2747                        "vmovd\t{$src, $dst|$dst, $src}",
2748                        [(set GR32:$dst, (vector_extract (v4i32 VR128X:$src),
2749                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
2750                        EVEX, VEX_LIG;
2751 def VMOVPDI2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2752                        (ins i32mem:$dst, VR128X:$src),
2753                        "vmovd\t{$src, $dst|$dst, $src}",
2754                        [(store (i32 (vector_extract (v4i32 VR128X:$src),
2755                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
2756                        EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2757
2758 // Move quadword from xmm1 register to r/m64
2759 //
2760 def VMOVPQIto64Zrr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128X:$src),
2761                       "vmovq\t{$src, $dst|$dst, $src}",
2762                       [(set GR64:$dst, (extractelt (v2i64 VR128X:$src),
2763                                                    (iPTR 0)))],
2764                       IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_LIG, VEX_W,
2765                       Requires<[HasAVX512, In64BitMode]>;
2766
2767 def VMOVPQIto64Zmr : I<0xD6, MRMDestMem, (outs),
2768                        (ins i64mem:$dst, VR128X:$src),
2769                        "vmovq\t{$src, $dst|$dst, $src}",
2770                        [(store (extractelt (v2i64 VR128X:$src), (iPTR 0)),
2771                                addr:$dst)], IIC_SSE_MOVDQ>,
2772                        EVEX, PD, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>,
2773                        Sched<[WriteStore]>, Requires<[HasAVX512, In64BitMode]>;
2774
2775 // Move Scalar Single to Double Int
2776 //
2777 let isCodeGenOnly = 1 in {
2778 def VMOVSS2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst),
2779                       (ins FR32X:$src),
2780                       "vmovd\t{$src, $dst|$dst, $src}",
2781                       [(set GR32:$dst, (bitconvert FR32X:$src))],
2782                       IIC_SSE_MOVD_ToGP>, EVEX, VEX_LIG;
2783 def VMOVSS2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2784                       (ins i32mem:$dst, FR32X:$src),
2785                       "vmovd\t{$src, $dst|$dst, $src}",
2786                       [(store (i32 (bitconvert FR32X:$src)), addr:$dst)],
2787                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2788 }
2789
2790 // Move Quadword Int to Packed Quadword Int
2791 //
2792 def VMOVQI2PQIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst),
2793                       (ins i64mem:$src),
2794                       "vmovq\t{$src, $dst|$dst, $src}",
2795                       [(set VR128X:$dst,
2796                         (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
2797                       EVEX, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
2798
2799 //===----------------------------------------------------------------------===//
2800 // AVX-512  MOVSS, MOVSD
2801 //===----------------------------------------------------------------------===//
2802
2803 multiclass avx512_move_scalar <string asm, RegisterClass RC,
2804                               SDNode OpNode, ValueType vt,
2805                               X86MemOperand x86memop, PatFrag mem_pat> {
2806   let hasSideEffects = 0 in {
2807   def rr : SI<0x10, MRMSrcReg, (outs VR128X:$dst), (ins VR128X:$src1, RC:$src2),
2808               !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2809               [(set VR128X:$dst, (vt (OpNode VR128X:$src1,
2810                                       (scalar_to_vector RC:$src2))))],
2811               IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG;
2812   let Constraints = "$src1 = $dst" in
2813   def rrk : SI<0x10, MRMSrcReg, (outs VR128X:$dst),
2814               (ins VR128X:$src1, VK1WM:$mask, RC:$src2, RC:$src3),
2815               !strconcat(asm,
2816                 "\t{$src3, $src2, $dst {${mask}}|$dst {${mask}}, $src2, $src3}"),
2817               [], IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG, EVEX_K;
2818   def rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
2819               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2820               [(set RC:$dst, (mem_pat addr:$src))], IIC_SSE_MOV_S_RM>,
2821               EVEX, VEX_LIG;
2822   let mayStore = 1 in {
2823   def mr: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
2824              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2825              [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
2826              EVEX, VEX_LIG;
2827   def mrk: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, VK1WM:$mask, RC:$src),
2828              !strconcat(asm, "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
2829              [], IIC_SSE_MOV_S_MR>,
2830              EVEX, VEX_LIG, EVEX_K;
2831   } // mayStore
2832   } //hasSideEffects = 0
2833 }
2834
2835 let ExeDomain = SSEPackedSingle in
2836 defm VMOVSSZ : avx512_move_scalar<"movss", FR32X, X86Movss, v4f32, f32mem,
2837                                  loadf32>, XS, EVEX_CD8<32, CD8VT1>;
2838
2839 let ExeDomain = SSEPackedDouble in
2840 defm VMOVSDZ : avx512_move_scalar<"movsd", FR64X, X86Movsd, v2f64, f64mem,
2841                                  loadf64>, XD, VEX_W, EVEX_CD8<64, CD8VT1>;
2842
2843 def : Pat<(f32 (X86select VK1WM:$mask, (f32 FR32X:$src1), (f32 FR32X:$src2))),
2844           (COPY_TO_REGCLASS (VMOVSSZrrk (COPY_TO_REGCLASS FR32X:$src2, VR128X),
2845            VK1WM:$mask, (f32 (IMPLICIT_DEF)), FR32X:$src1), FR32X)>;
2846
2847 def : Pat<(f64 (X86select VK1WM:$mask, (f64 FR64X:$src1), (f64 FR64X:$src2))),
2848           (COPY_TO_REGCLASS (VMOVSDZrrk (COPY_TO_REGCLASS FR64X:$src2, VR128X),
2849            VK1WM:$mask, (f64 (IMPLICIT_DEF)), FR64X:$src1), FR64X)>;
2850
2851 def : Pat<(int_x86_avx512_mask_store_ss addr:$dst, VR128X:$src, GR8:$mask),
2852           (VMOVSSZmrk addr:$dst, (i1 (COPY_TO_REGCLASS GR8:$mask, VK1WM)),
2853            (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2854
2855 // For the disassembler
2856 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
2857   def VMOVSSZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2858                         (ins VR128X:$src1, FR32X:$src2),
2859                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2860                         IIC_SSE_MOV_S_RR>,
2861                         XS, EVEX_4V, VEX_LIG;
2862   def VMOVSDZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2863                         (ins VR128X:$src1, FR64X:$src2),
2864                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2865                         IIC_SSE_MOV_S_RR>,
2866                         XD, EVEX_4V, VEX_LIG, VEX_W;
2867 }
2868
2869 let Predicates = [HasAVX512] in {
2870   let AddedComplexity = 15 in {
2871   // Move scalar to XMM zero-extended, zeroing a VR128X then do a
2872   // MOVS{S,D} to the lower bits.
2873   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32X:$src)))),
2874             (VMOVSSZrr (v4f32 (V_SET0)), FR32X:$src)>;
2875   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128X:$src))),
2876             (VMOVSSZrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2877   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128X:$src))),
2878             (VMOVSSZrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2879   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64X:$src)))),
2880             (VMOVSDZrr (v2f64 (V_SET0)), FR64X:$src)>;
2881
2882   // Move low f32 and clear high bits.
2883   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256X:$src))),
2884             (SUBREG_TO_REG (i32 0),
2885              (VMOVSSZrr (v4f32 (V_SET0)),
2886               (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm)), sub_xmm)>;
2887   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256X:$src))),
2888             (SUBREG_TO_REG (i32 0),
2889              (VMOVSSZrr (v4i32 (V_SET0)),
2890                        (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm)), sub_xmm)>;
2891   }
2892
2893   let AddedComplexity = 20 in {
2894   // MOVSSrm zeros the high parts of the register; represent this
2895   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2896   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
2897             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2898   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
2899             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2900   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
2901             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2902
2903   // MOVSDrm zeros the high parts of the register; represent this
2904   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2905   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
2906             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2907   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
2908             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2909   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
2910             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2911   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
2912             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2913   def : Pat<(v2f64 (X86vzload addr:$src)),
2914             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2915
2916   // Represent the same patterns above but in the form they appear for
2917   // 256-bit types
2918   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
2919                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
2920             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
2921   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2922                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
2923             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
2924   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2925                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
2926             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
2927   }
2928   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2929                    (v4f32 (scalar_to_vector FR32X:$src)), (iPTR 0)))),
2930             (SUBREG_TO_REG (i32 0), (v4f32 (VMOVSSZrr (v4f32 (V_SET0)),
2931                                             FR32X:$src)), sub_xmm)>;
2932   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2933                    (v2f64 (scalar_to_vector FR64X:$src)), (iPTR 0)))),
2934             (SUBREG_TO_REG (i64 0), (v2f64 (VMOVSDZrr (v2f64 (V_SET0)),
2935                                      FR64X:$src)), sub_xmm)>;
2936   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
2937                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
2938             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
2939
2940   // Move low f64 and clear high bits.
2941   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256X:$src))),
2942             (SUBREG_TO_REG (i32 0),
2943              (VMOVSDZrr (v2f64 (V_SET0)),
2944                        (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm)), sub_xmm)>;
2945
2946   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256X:$src))),
2947             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (V_SET0)),
2948                        (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm)), sub_xmm)>;
2949
2950   // Extract and store.
2951   def : Pat<(store (f32 (vector_extract (v4f32 VR128X:$src), (iPTR 0))),
2952                    addr:$dst),
2953             (VMOVSSZmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128X:$src), FR32X))>;
2954   def : Pat<(store (f64 (vector_extract (v2f64 VR128X:$src), (iPTR 0))),
2955                    addr:$dst),
2956             (VMOVSDZmr addr:$dst, (COPY_TO_REGCLASS (v2f64 VR128X:$src), FR64X))>;
2957
2958   // Shuffle with VMOVSS
2959   def : Pat<(v4i32 (X86Movss VR128X:$src1, VR128X:$src2)),
2960             (VMOVSSZrr (v4i32 VR128X:$src1),
2961                       (COPY_TO_REGCLASS (v4i32 VR128X:$src2), FR32X))>;
2962   def : Pat<(v4f32 (X86Movss VR128X:$src1, VR128X:$src2)),
2963             (VMOVSSZrr (v4f32 VR128X:$src1),
2964                       (COPY_TO_REGCLASS (v4f32 VR128X:$src2), FR32X))>;
2965
2966   // 256-bit variants
2967   def : Pat<(v8i32 (X86Movss VR256X:$src1, VR256X:$src2)),
2968             (SUBREG_TO_REG (i32 0),
2969               (VMOVSSZrr (EXTRACT_SUBREG (v8i32 VR256X:$src1), sub_xmm),
2970                         (EXTRACT_SUBREG (v8i32 VR256X:$src2), sub_xmm)),
2971               sub_xmm)>;
2972   def : Pat<(v8f32 (X86Movss VR256X:$src1, VR256X:$src2)),
2973             (SUBREG_TO_REG (i32 0),
2974               (VMOVSSZrr (EXTRACT_SUBREG (v8f32 VR256X:$src1), sub_xmm),
2975                         (EXTRACT_SUBREG (v8f32 VR256X:$src2), sub_xmm)),
2976               sub_xmm)>;
2977
2978   // Shuffle with VMOVSD
2979   def : Pat<(v2i64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2980             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2981   def : Pat<(v2f64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2982             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2983   def : Pat<(v4f32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2984             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2985   def : Pat<(v4i32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2986             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2987
2988   // 256-bit variants
2989   def : Pat<(v4i64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2990             (SUBREG_TO_REG (i32 0),
2991               (VMOVSDZrr (EXTRACT_SUBREG (v4i64 VR256X:$src1), sub_xmm),
2992                         (EXTRACT_SUBREG (v4i64 VR256X:$src2), sub_xmm)),
2993               sub_xmm)>;
2994   def : Pat<(v4f64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2995             (SUBREG_TO_REG (i32 0),
2996               (VMOVSDZrr (EXTRACT_SUBREG (v4f64 VR256X:$src1), sub_xmm),
2997                         (EXTRACT_SUBREG (v4f64 VR256X:$src2), sub_xmm)),
2998               sub_xmm)>;
2999
3000   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3001             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3002   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3003             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3004   def : Pat<(v4f32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3005             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3006   def : Pat<(v4i32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3007             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3008 }
3009
3010 let AddedComplexity = 15 in
3011 def VMOVZPQILo2PQIZrr : AVX512XSI<0x7E, MRMSrcReg, (outs VR128X:$dst),
3012                                 (ins VR128X:$src),
3013                                 "vmovq\t{$src, $dst|$dst, $src}",
3014                                 [(set VR128X:$dst, (v2i64 (X86vzmovl
3015                                                    (v2i64 VR128X:$src))))],
3016                                 IIC_SSE_MOVQ_RR>, EVEX, VEX_W;
3017
3018 let AddedComplexity = 20 in
3019 def VMOVZPQILo2PQIZrm : AVX512XSI<0x7E, MRMSrcMem, (outs VR128X:$dst),
3020                                  (ins i128mem:$src),
3021                                  "vmovq\t{$src, $dst|$dst, $src}",
3022                                  [(set VR128X:$dst, (v2i64 (X86vzmovl
3023                                                      (loadv2i64 addr:$src))))],
3024                                  IIC_SSE_MOVDQ>, EVEX, VEX_W,
3025                                  EVEX_CD8<8, CD8VT8>;
3026
3027 let Predicates = [HasAVX512] in {
3028   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
3029   let AddedComplexity = 20 in {
3030     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
3031               (VMOVDI2PDIZrm addr:$src)>;
3032     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
3033               (VMOV64toPQIZrr GR64:$src)>;
3034     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
3035               (VMOVDI2PDIZrr GR32:$src)>;
3036
3037     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
3038               (VMOVDI2PDIZrm addr:$src)>;
3039     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
3040               (VMOVDI2PDIZrm addr:$src)>;
3041     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
3042             (VMOVZPQILo2PQIZrm addr:$src)>;
3043     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128X:$src))),
3044             (VMOVZPQILo2PQIZrr VR128X:$src)>;
3045     def : Pat<(v2i64 (X86vzload addr:$src)),
3046             (VMOVZPQILo2PQIZrm addr:$src)>;
3047   }
3048
3049   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
3050   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
3051                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
3052             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
3053   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
3054                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
3055             (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
3056 }
3057
3058 def : Pat<(v16i32 (X86Vinsert (v16i32 immAllZerosV), GR32:$src2, (iPTR 0))),
3059         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
3060
3061 def : Pat<(v8i64 (X86Vinsert (bc_v8i64 (v16i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
3062         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
3063
3064 def : Pat<(v16i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
3065         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
3066
3067 def : Pat<(v8i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
3068         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
3069
3070 //===----------------------------------------------------------------------===//
3071 // AVX-512 - Non-temporals
3072 //===----------------------------------------------------------------------===//
3073 let SchedRW = [WriteLoad] in {
3074   def VMOVNTDQAZrm : AVX512PI<0x2A, MRMSrcMem, (outs VR512:$dst),
3075                         (ins i512mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}",
3076                         [(set VR512:$dst, (int_x86_avx512_movntdqa addr:$src))],
3077                         SSEPackedInt>, EVEX, T8PD, EVEX_V512,
3078                         EVEX_CD8<64, CD8VF>;
3079
3080   let Predicates = [HasAVX512, HasVLX] in {
3081     def VMOVNTDQAZ256rm : AVX512PI<0x2A, MRMSrcMem, (outs VR256X:$dst),
3082                              (ins i256mem:$src),
3083                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
3084                              SSEPackedInt>, EVEX, T8PD, EVEX_V256,
3085                              EVEX_CD8<64, CD8VF>;
3086
3087     def VMOVNTDQAZ128rm : AVX512PI<0x2A, MRMSrcMem, (outs VR128X:$dst),
3088                              (ins i128mem:$src),
3089                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
3090                              SSEPackedInt>, EVEX, T8PD, EVEX_V128,
3091                              EVEX_CD8<64, CD8VF>;
3092   }
3093 }
3094
3095 multiclass avx512_movnt<bits<8> opc, string OpcodeStr, PatFrag st_frag,
3096                         ValueType OpVT, RegisterClass RC, X86MemOperand memop,
3097                         Domain d, InstrItinClass itin = IIC_SSE_MOVNT> {
3098   let SchedRW = [WriteStore], mayStore = 1,
3099       AddedComplexity = 400 in
3100   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins memop:$dst, RC:$src),
3101                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3102                     [(st_frag (OpVT RC:$src), addr:$dst)], d, itin>, EVEX;
3103 }
3104
3105 multiclass avx512_movnt_vl<bits<8> opc, string OpcodeStr, PatFrag st_frag,
3106                            string elty, string elsz, string vsz512,
3107                            string vsz256, string vsz128, Domain d,
3108                            Predicate prd, InstrItinClass itin = IIC_SSE_MOVNT> {
3109   let Predicates = [prd] in
3110   defm Z : avx512_movnt<opc, OpcodeStr, st_frag,
3111                         !cast<ValueType>("v"##vsz512##elty##elsz), VR512,
3112                         !cast<X86MemOperand>(elty##"512mem"), d, itin>,
3113                         EVEX_V512;
3114
3115   let Predicates = [prd, HasVLX] in {
3116     defm Z256 : avx512_movnt<opc, OpcodeStr, st_frag,
3117                              !cast<ValueType>("v"##vsz256##elty##elsz), VR256X,
3118                              !cast<X86MemOperand>(elty##"256mem"), d, itin>,
3119                              EVEX_V256;
3120
3121     defm Z128 : avx512_movnt<opc, OpcodeStr, st_frag,
3122                              !cast<ValueType>("v"##vsz128##elty##elsz), VR128X,
3123                              !cast<X86MemOperand>(elty##"128mem"), d, itin>,
3124                              EVEX_V128;
3125   }
3126 }
3127
3128 defm VMOVNTDQ : avx512_movnt_vl<0xE7, "vmovntdq", alignednontemporalstore,
3129                                 "i", "64", "8", "4", "2", SSEPackedInt,
3130                                 HasAVX512>, PD, EVEX_CD8<64, CD8VF>;
3131
3132 defm VMOVNTPD : avx512_movnt_vl<0x2B, "vmovntpd", alignednontemporalstore,
3133                                 "f", "64", "8", "4", "2", SSEPackedDouble,
3134                                 HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
3135
3136 defm VMOVNTPS : avx512_movnt_vl<0x2B, "vmovntps", alignednontemporalstore,
3137                                 "f", "32", "16", "8", "4", SSEPackedSingle,
3138                                 HasAVX512>, PS, EVEX_CD8<32, CD8VF>;
3139
3140 //===----------------------------------------------------------------------===//
3141 // AVX-512 - Integer arithmetic
3142 //
3143 multiclass avx512_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3144                            X86VectorVTInfo _, OpndItins itins,
3145                            bit IsCommutable = 0> {
3146   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3147                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3148                     "$src2, $src1", "$src1, $src2",
3149                     (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
3150                     itins.rr, IsCommutable>,
3151             AVX512BIBase, EVEX_4V;
3152
3153   let mayLoad = 1 in
3154     defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3155                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3156                     "$src2, $src1", "$src1, $src2",
3157                     (_.VT (OpNode _.RC:$src1,
3158                                   (bitconvert (_.LdFrag addr:$src2)))),
3159                     itins.rm>,
3160               AVX512BIBase, EVEX_4V;
3161 }
3162
3163 multiclass avx512_binop_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3164                             X86VectorVTInfo _, OpndItins itins,
3165                             bit IsCommutable = 0> :
3166            avx512_binop_rm<opc, OpcodeStr, OpNode, _, itins, IsCommutable> {
3167   let mayLoad = 1 in
3168     defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3169                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
3170                     "${src2}"##_.BroadcastStr##", $src1",
3171                     "$src1, ${src2}"##_.BroadcastStr,
3172                     (_.VT (OpNode _.RC:$src1,
3173                                   (X86VBroadcast
3174                                       (_.ScalarLdFrag addr:$src2)))),
3175                     itins.rm>,
3176                AVX512BIBase, EVEX_4V, EVEX_B;
3177 }
3178
3179 multiclass avx512_binop_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3180                               AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3181                               Predicate prd, bit IsCommutable = 0> {
3182   let Predicates = [prd] in
3183     defm Z : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3184                              IsCommutable>, EVEX_V512;
3185
3186   let Predicates = [prd, HasVLX] in {
3187     defm Z256 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3188                              IsCommutable>, EVEX_V256;
3189     defm Z128 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3190                              IsCommutable>, EVEX_V128;
3191   }
3192 }
3193
3194 multiclass avx512_binop_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3195                                AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3196                                Predicate prd, bit IsCommutable = 0> {
3197   let Predicates = [prd] in
3198     defm Z : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3199                              IsCommutable>, EVEX_V512;
3200
3201   let Predicates = [prd, HasVLX] in {
3202     defm Z256 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3203                              IsCommutable>, EVEX_V256;
3204     defm Z128 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3205                              IsCommutable>, EVEX_V128;
3206   }
3207 }
3208
3209 multiclass avx512_binop_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
3210                                 OpndItins itins, Predicate prd,
3211                                 bit IsCommutable = 0> {
3212   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
3213                                itins, prd, IsCommutable>,
3214                                VEX_W, EVEX_CD8<64, CD8VF>;
3215 }
3216
3217 multiclass avx512_binop_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
3218                                 OpndItins itins, Predicate prd,
3219                                 bit IsCommutable = 0> {
3220   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
3221                                itins, prd, IsCommutable>, EVEX_CD8<32, CD8VF>;
3222 }
3223
3224 multiclass avx512_binop_rm_vl_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
3225                                 OpndItins itins, Predicate prd,
3226                                 bit IsCommutable = 0> {
3227   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i16_info,
3228                               itins, prd, IsCommutable>, EVEX_CD8<16, CD8VF>;
3229 }
3230
3231 multiclass avx512_binop_rm_vl_b<bits<8> opc, string OpcodeStr, SDNode OpNode,
3232                                 OpndItins itins, Predicate prd,
3233                                 bit IsCommutable = 0> {
3234   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i8_info,
3235                               itins, prd, IsCommutable>, EVEX_CD8<8, CD8VF>;
3236 }
3237
3238 multiclass avx512_binop_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
3239                                  SDNode OpNode, OpndItins itins, Predicate prd,
3240                                  bit IsCommutable = 0> {
3241   defm Q : avx512_binop_rm_vl_q<opc_q, OpcodeStr#"q", OpNode, itins, prd,
3242                                    IsCommutable>;
3243
3244   defm D : avx512_binop_rm_vl_d<opc_d, OpcodeStr#"d", OpNode, itins, prd,
3245                                    IsCommutable>;
3246 }
3247
3248 multiclass avx512_binop_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
3249                                  SDNode OpNode, OpndItins itins, Predicate prd,
3250                                  bit IsCommutable = 0> {
3251   defm W : avx512_binop_rm_vl_w<opc_w, OpcodeStr#"w", OpNode, itins, prd,
3252                                    IsCommutable>;
3253
3254   defm B : avx512_binop_rm_vl_b<opc_b, OpcodeStr#"b", OpNode, itins, prd,
3255                                    IsCommutable>;
3256 }
3257
3258 multiclass avx512_binop_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
3259                                   bits<8> opc_d, bits<8> opc_q,
3260                                   string OpcodeStr, SDNode OpNode,
3261                                   OpndItins itins, bit IsCommutable = 0> {
3262   defm NAME : avx512_binop_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
3263                                     itins, HasAVX512, IsCommutable>,
3264               avx512_binop_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
3265                                     itins, HasBWI, IsCommutable>;
3266 }
3267
3268 multiclass avx512_binop_rm2<bits<8> opc, string OpcodeStr, OpndItins itins,
3269                             SDNode OpNode,X86VectorVTInfo _Src,
3270                             X86VectorVTInfo _Dst, bit IsCommutable = 0> {
3271   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
3272                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
3273                             "$src2, $src1","$src1, $src2",
3274                             (_Dst.VT (OpNode
3275                                          (_Src.VT _Src.RC:$src1),
3276                                          (_Src.VT _Src.RC:$src2))),
3277                             itins.rr, IsCommutable>,
3278                             AVX512BIBase, EVEX_4V;
3279   let mayLoad = 1 in {
3280       defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3281                             (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
3282                             "$src2, $src1", "$src1, $src2",
3283                             (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
3284                                           (bitconvert (_Src.LdFrag addr:$src2)))),
3285                             itins.rm>,
3286                             AVX512BIBase, EVEX_4V;
3287
3288       defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3289                         (ins _Src.RC:$src1, _Dst.ScalarMemOp:$src2),
3290                         OpcodeStr,
3291                         "${src2}"##_Dst.BroadcastStr##", $src1",
3292                          "$src1, ${src2}"##_Dst.BroadcastStr,
3293                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
3294                                      (_Dst.VT (X86VBroadcast
3295                                               (_Dst.ScalarLdFrag addr:$src2)))))),
3296                         itins.rm>,
3297                         AVX512BIBase, EVEX_4V, EVEX_B;
3298   }
3299 }
3300
3301 defm VPADD : avx512_binop_rm_vl_all<0xFC, 0xFD, 0xFE, 0xD4, "vpadd", add,
3302                                     SSE_INTALU_ITINS_P, 1>;
3303 defm VPSUB : avx512_binop_rm_vl_all<0xF8, 0xF9, 0xFA, 0xFB, "vpsub", sub,
3304                                     SSE_INTALU_ITINS_P, 0>;
3305 defm VPADDS : avx512_binop_rm_vl_bw<0xEC, 0xED, "vpadds", X86adds,
3306                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3307 defm VPSUBS : avx512_binop_rm_vl_bw<0xE8, 0xE9, "vpsubs", X86subs,
3308                                     SSE_INTALU_ITINS_P, HasBWI, 0>;
3309 defm VPADDUS : avx512_binop_rm_vl_bw<0xDC, 0xDD, "vpaddus", X86addus,
3310                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3311 defm VPSUBUS : avx512_binop_rm_vl_bw<0xD8, 0xD9, "vpsubus", X86subus,
3312                                      SSE_INTALU_ITINS_P, HasBWI, 0>;
3313 defm VPMULLD : avx512_binop_rm_vl_d<0x40, "vpmulld", mul,
3314                                     SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3315 defm VPMULLW : avx512_binop_rm_vl_w<0xD5, "vpmullw", mul,
3316                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3317 defm VPMULLQ : avx512_binop_rm_vl_q<0x40, "vpmullq", mul,
3318                                     SSE_INTALU_ITINS_P, HasDQI, 1>, T8PD;
3319 defm VPMULHW : avx512_binop_rm_vl_w<0xE5, "vpmulhw", mulhs, SSE_INTALU_ITINS_P,
3320                                     HasBWI, 1>;
3321 defm VPMULHUW : avx512_binop_rm_vl_w<0xE4, "vpmulhuw", mulhu, SSE_INTMUL_ITINS_P,
3322                                      HasBWI, 1>;
3323 defm VPMULHRSW : avx512_binop_rm_vl_w<0x0B, "vpmulhrsw", X86mulhrs, SSE_INTMUL_ITINS_P,
3324                                       HasBWI, 1>, T8PD;
3325 defm VPAVG : avx512_binop_rm_vl_bw<0xE0, 0xE3, "vpavg", X86avg,
3326                                    SSE_INTALU_ITINS_P, HasBWI, 1>;
3327
3328 multiclass avx512_binop_all<bits<8> opc, string OpcodeStr, OpndItins itins,
3329                             SDNode OpNode, bit IsCommutable = 0> {
3330
3331   defm NAME#Z : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3332                                  v16i32_info, v8i64_info, IsCommutable>,
3333                                 EVEX_V512, EVEX_CD8<64, CD8VF>, VEX_W;
3334   let Predicates = [HasVLX] in {
3335     defm NAME#Z256 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3336                                       v8i32x_info, v4i64x_info, IsCommutable>,
3337                                      EVEX_V256, EVEX_CD8<64, CD8VF>, VEX_W;
3338     defm NAME#Z128 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3339                                       v4i32x_info, v2i64x_info, IsCommutable>,
3340                                      EVEX_V128, EVEX_CD8<64, CD8VF>, VEX_W;
3341   }
3342 }
3343
3344 defm VPMULDQ : avx512_binop_all<0x28, "vpmuldq", SSE_INTALU_ITINS_P,
3345                    X86pmuldq, 1>,T8PD;
3346 defm VPMULUDQ : avx512_binop_all<0xF4, "vpmuludq", SSE_INTMUL_ITINS_P,
3347                    X86pmuludq, 1>;
3348
3349 multiclass avx512_packs_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3350                             X86VectorVTInfo _Src, X86VectorVTInfo _Dst> {
3351   let mayLoad = 1 in {
3352       defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3353                         (ins _Src.RC:$src1, _Src.ScalarMemOp:$src2),
3354                         OpcodeStr,
3355                         "${src2}"##_Src.BroadcastStr##", $src1",
3356                          "$src1, ${src2}"##_Src.BroadcastStr,
3357                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
3358                                      (_Src.VT (X86VBroadcast
3359                                               (_Src.ScalarLdFrag addr:$src2))))))>,
3360                         EVEX_4V, EVEX_B, EVEX_CD8<_Src.EltSize, CD8VF>;
3361   }
3362 }
3363
3364 multiclass avx512_packs_rm<bits<8> opc, string OpcodeStr,
3365                             SDNode OpNode,X86VectorVTInfo _Src,
3366                             X86VectorVTInfo _Dst> {
3367   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
3368                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
3369                             "$src2, $src1","$src1, $src2",
3370                             (_Dst.VT (OpNode
3371                                          (_Src.VT _Src.RC:$src1),
3372                                          (_Src.VT _Src.RC:$src2)))>,
3373                             EVEX_CD8<_Src.EltSize, CD8VF>, EVEX_4V;
3374   let mayLoad = 1 in {
3375     defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3376                           (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
3377                           "$src2, $src1", "$src1, $src2",
3378                           (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
3379                                         (bitconvert (_Src.LdFrag addr:$src2))))>,
3380                            EVEX_4V, EVEX_CD8<_Src.EltSize, CD8VF>;
3381   }
3382 }
3383
3384 multiclass avx512_packs_all_i32_i16<bits<8> opc, string OpcodeStr,
3385                                     SDNode OpNode> {
3386   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i32_info,
3387                                  v32i16_info>,
3388                 avx512_packs_rmb<opc, OpcodeStr, OpNode, v16i32_info,
3389                                  v32i16_info>, EVEX_V512;
3390   let Predicates = [HasVLX] in {
3391     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i32x_info,
3392                                      v16i16x_info>,
3393                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v8i32x_info,
3394                                      v16i16x_info>, EVEX_V256;
3395     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v4i32x_info,
3396                                      v8i16x_info>,
3397                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v4i32x_info,
3398                                      v8i16x_info>, EVEX_V128;
3399   }
3400 }
3401 multiclass avx512_packs_all_i16_i8<bits<8> opc, string OpcodeStr,
3402                             SDNode OpNode> {
3403   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v32i16_info,
3404                                 v64i8_info>, EVEX_V512;
3405   let Predicates = [HasVLX] in {
3406     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i16x_info,
3407                                     v32i8x_info>, EVEX_V256;
3408     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i16x_info,
3409                                     v16i8x_info>, EVEX_V128;
3410   }
3411 }
3412
3413 multiclass avx512_vpmadd<bits<8> opc, string OpcodeStr,
3414                             SDNode OpNode, AVX512VLVectorVTInfo _Src,
3415                             AVX512VLVectorVTInfo _Dst> {
3416   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info512,
3417                                 _Dst.info512>, EVEX_V512;
3418   let Predicates = [HasVLX] in {
3419     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info256,
3420                                      _Dst.info256>, EVEX_V256;
3421     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info128,
3422                                      _Dst.info128>, EVEX_V128;
3423   }
3424 }
3425
3426 let Predicates = [HasBWI] in {
3427   defm VPACKSSDW : avx512_packs_all_i32_i16<0x6B, "vpackssdw", X86Packss>, PD;
3428   defm VPACKUSDW : avx512_packs_all_i32_i16<0x2b, "vpackusdw", X86Packus>, T8PD;
3429   defm VPACKSSWB : avx512_packs_all_i16_i8 <0x63, "vpacksswb", X86Packss>, AVX512BIBase, VEX_W;
3430   defm VPACKUSWB : avx512_packs_all_i16_i8 <0x67, "vpackuswb", X86Packus>, AVX512BIBase, VEX_W;
3431
3432   defm VPMADDUBSW : avx512_vpmadd<0x04, "vpmaddubsw", X86vpmaddubsw,
3433                        avx512vl_i8_info, avx512vl_i16_info>, AVX512BIBase, T8PD;
3434   defm VPMADDWD   : avx512_vpmadd<0xF5, "vpmaddwd", X86vpmaddwd,
3435                        avx512vl_i16_info, avx512vl_i32_info>, AVX512BIBase;
3436 }
3437
3438 defm VPMAXSB : avx512_binop_rm_vl_b<0x3C, "vpmaxsb", smax,
3439                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
3440 defm VPMAXSW : avx512_binop_rm_vl_w<0xEE, "vpmaxsw", smax,
3441                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3442 defm VPMAXS : avx512_binop_rm_vl_dq<0x3D, 0x3D, "vpmaxs", smax,
3443                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3444
3445 defm VPMAXUB : avx512_binop_rm_vl_b<0xDE, "vpmaxub", umax,
3446                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3447 defm VPMAXUW : avx512_binop_rm_vl_w<0x3E, "vpmaxuw", umax,
3448                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
3449 defm VPMAXU : avx512_binop_rm_vl_dq<0x3F, 0x3F, "vpmaxu", umax,
3450                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3451
3452 defm VPMINSB : avx512_binop_rm_vl_b<0x38, "vpminsb", smin,
3453                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
3454 defm VPMINSW : avx512_binop_rm_vl_w<0xEA, "vpminsw", smin,
3455                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3456 defm VPMINS : avx512_binop_rm_vl_dq<0x39, 0x39, "vpmins", smin,
3457                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3458
3459 defm VPMINUB : avx512_binop_rm_vl_b<0xDA, "vpminub", umin,
3460                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3461 defm VPMINUW : avx512_binop_rm_vl_w<0x3A, "vpminuw", umin,
3462                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
3463 defm VPMINU : avx512_binop_rm_vl_dq<0x3B, 0x3B, "vpminu", umin,
3464                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3465 //===----------------------------------------------------------------------===//
3466 // AVX-512  Logical Instructions
3467 //===----------------------------------------------------------------------===//
3468
3469 defm VPAND : avx512_binop_rm_vl_dq<0xDB, 0xDB, "vpand", and,
3470                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
3471 defm VPOR : avx512_binop_rm_vl_dq<0xEB, 0xEB, "vpor", or,
3472                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
3473 defm VPXOR : avx512_binop_rm_vl_dq<0xEF, 0xEF, "vpxor", xor,
3474                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
3475 defm VPANDN : avx512_binop_rm_vl_dq<0xDF, 0xDF, "vpandn", X86andnp,
3476                                   SSE_INTALU_ITINS_P, HasAVX512, 0>;
3477
3478 //===----------------------------------------------------------------------===//
3479 // AVX-512  FP arithmetic
3480 //===----------------------------------------------------------------------===//
3481 multiclass avx512_fp_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
3482                          SDNode OpNode, SDNode VecNode, OpndItins itins,
3483                          bit IsCommutable> {
3484
3485   defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
3486                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3487                            "$src2, $src1", "$src1, $src2",
3488                            (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
3489                            (i32 FROUND_CURRENT)),
3490                            itins.rr, IsCommutable>;
3491
3492   defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
3493                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3494                          "$src2, $src1", "$src1, $src2",
3495                          (VecNode (_.VT _.RC:$src1),
3496                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
3497                            (i32 FROUND_CURRENT)),
3498                          itins.rm, IsCommutable>;
3499   let isCodeGenOnly = 1, isCommutable = IsCommutable,
3500       Predicates = [HasAVX512] in {
3501   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
3502                          (ins _.FRC:$src1, _.FRC:$src2),
3503                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3504                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
3505                           itins.rr>;
3506   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
3507                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
3508                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3509                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
3510                          (_.ScalarLdFrag addr:$src2)))], itins.rr>;
3511   }
3512 }
3513
3514 multiclass avx512_fp_scalar_round<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
3515                          SDNode VecNode, OpndItins itins, bit IsCommutable = 0> {
3516
3517   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
3518                           (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
3519                           "$rc, $src2, $src1", "$src1, $src2, $rc",
3520                           (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
3521                           (i32 imm:$rc)), itins.rr, IsCommutable>,
3522                           EVEX_B, EVEX_RC;
3523 }
3524 multiclass avx512_fp_scalar_sae<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
3525                          SDNode VecNode, OpndItins itins, bit IsCommutable> {
3526
3527   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
3528                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3529                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
3530                             (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
3531                             (i32 FROUND_NO_EXC))>, EVEX_B;
3532 }
3533
3534 multiclass avx512_binop_s_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
3535                                   SDNode VecNode,
3536                                   SizeItins itins, bit IsCommutable> {
3537   defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
3538                               itins.s, IsCommutable>,
3539              avx512_fp_scalar_round<opc, OpcodeStr#"ss", f32x_info, VecNode,
3540                               itins.s, IsCommutable>,
3541                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
3542   defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
3543                               itins.d,                  IsCommutable>,
3544              avx512_fp_scalar_round<opc, OpcodeStr#"sd", f64x_info, VecNode,
3545                               itins.d, IsCommutable>,
3546                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3547 }
3548
3549 multiclass avx512_binop_s_sae<bits<8> opc, string OpcodeStr, SDNode OpNode,
3550                                   SDNode VecNode,
3551                                   SizeItins itins, bit IsCommutable> {
3552   defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
3553                               itins.s, IsCommutable>,
3554              avx512_fp_scalar_sae<opc, OpcodeStr#"ss", f32x_info, VecNode,
3555                               itins.s, IsCommutable>,
3556                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
3557   defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
3558                               itins.d,                  IsCommutable>,
3559              avx512_fp_scalar_sae<opc, OpcodeStr#"sd", f64x_info, VecNode,
3560                               itins.d, IsCommutable>,
3561                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
3562 }
3563 defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnd, SSE_ALU_ITINS_S, 1>;
3564 defm VMUL : avx512_binop_s_round<0x59, "vmul", fmul, X86fmulRnd, SSE_ALU_ITINS_S, 1>;
3565 defm VSUB : avx512_binop_s_round<0x5C, "vsub", fsub, X86fsubRnd, SSE_ALU_ITINS_S, 0>;
3566 defm VDIV : avx512_binop_s_round<0x5E, "vdiv", fdiv, X86fdivRnd, SSE_ALU_ITINS_S, 0>;
3567 defm VMIN : avx512_binop_s_sae  <0x5D, "vmin", X86fmin, X86fminRnd, SSE_ALU_ITINS_S, 1>;
3568 defm VMAX : avx512_binop_s_sae  <0x5F, "vmax", X86fmax, X86fmaxRnd, SSE_ALU_ITINS_S, 1>;
3569
3570 multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
3571                             X86VectorVTInfo _, bit IsCommutable> {
3572   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3573                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
3574                   "$src2, $src1", "$src1, $src2",
3575                   (_.VT (OpNode _.RC:$src1, _.RC:$src2))>, EVEX_4V;
3576   let mayLoad = 1 in {
3577     defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3578                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
3579                     "$src2, $src1", "$src1, $src2",
3580                     (OpNode _.RC:$src1, (_.LdFrag addr:$src2))>, EVEX_4V;
3581     defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3582                      (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
3583                      "${src2}"##_.BroadcastStr##", $src1",
3584                      "$src1, ${src2}"##_.BroadcastStr,
3585                      (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
3586                                                 (_.ScalarLdFrag addr:$src2))))>,
3587                      EVEX_4V, EVEX_B;
3588   }//let mayLoad = 1
3589 }
3590
3591 multiclass avx512_fp_round_packed<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd,
3592                             X86VectorVTInfo _> {
3593   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3594                   (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr##_.Suffix,
3595                   "$rc, $src2, $src1", "$src1, $src2, $rc",
3596                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 imm:$rc)))>,
3597                   EVEX_4V, EVEX_B, EVEX_RC;
3598 }
3599
3600
3601 multiclass avx512_fp_sae_packed<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd,
3602                             X86VectorVTInfo _> {
3603   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3604                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
3605                   "{sae}, $src2, $src1", "$src1, $src2, {sae}",
3606                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 FROUND_NO_EXC)))>,
3607                   EVEX_4V, EVEX_B;
3608 }
3609
3610 multiclass avx512_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3611                              bit IsCommutable = 0> {
3612   defm PSZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v16f32_info,
3613                               IsCommutable>, EVEX_V512, PS,
3614                               EVEX_CD8<32, CD8VF>;
3615   defm PDZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f64_info,
3616                               IsCommutable>, EVEX_V512, PD, VEX_W,
3617                               EVEX_CD8<64, CD8VF>;
3618
3619     // Define only if AVX512VL feature is present.
3620   let Predicates = [HasVLX] in {
3621     defm PSZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f32x_info,
3622                                    IsCommutable>, EVEX_V128, PS,
3623                                    EVEX_CD8<32, CD8VF>;
3624     defm PSZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f32x_info,
3625                                    IsCommutable>, EVEX_V256, PS,
3626                                    EVEX_CD8<32, CD8VF>;
3627     defm PDZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v2f64x_info,
3628                                    IsCommutable>, EVEX_V128, PD, VEX_W,
3629                                    EVEX_CD8<64, CD8VF>;
3630     defm PDZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f64x_info,
3631                                    IsCommutable>, EVEX_V256, PD, VEX_W,
3632                                    EVEX_CD8<64, CD8VF>;
3633   }
3634 }
3635
3636 multiclass avx512_fp_binop_p_round<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
3637   defm PSZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
3638                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
3639   defm PDZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
3640                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
3641 }
3642
3643 multiclass avx512_fp_binop_p_sae<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
3644   defm PSZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
3645                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
3646   defm PDZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
3647                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
3648 }
3649
3650 defm VADD : avx512_fp_binop_p<0x58, "vadd", fadd, 1>,
3651             avx512_fp_binop_p_round<0x58, "vadd", X86faddRnd>;
3652 defm VMUL : avx512_fp_binop_p<0x59, "vmul", fmul, 1>,
3653             avx512_fp_binop_p_round<0x59, "vmul", X86fmulRnd>;
3654 defm VSUB : avx512_fp_binop_p<0x5C, "vsub", fsub>,
3655             avx512_fp_binop_p_round<0x5C, "vsub", X86fsubRnd>;
3656 defm VDIV : avx512_fp_binop_p<0x5E, "vdiv", fdiv>,
3657             avx512_fp_binop_p_round<0x5E, "vdiv", X86fdivRnd>;
3658 defm VMIN : avx512_fp_binop_p<0x5D, "vmin", X86fmin, 1>,
3659             avx512_fp_binop_p_sae<0x5D, "vmin", X86fminRnd>;
3660 defm VMAX : avx512_fp_binop_p<0x5F, "vmax", X86fmax, 1>,
3661             avx512_fp_binop_p_sae<0x5F, "vmax", X86fmaxRnd>;
3662 let Predicates = [HasDQI] in {
3663   defm VAND  : avx512_fp_binop_p<0x54, "vand", X86fand, 1>;
3664   defm VANDN : avx512_fp_binop_p<0x55, "vandn", X86fandn, 0>;
3665   defm VOR   : avx512_fp_binop_p<0x56, "vor", X86for, 1>;
3666   defm VXOR  : avx512_fp_binop_p<0x57, "vxor", X86fxor, 1>;
3667 }
3668
3669 multiclass avx512_fp_scalef_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3670                             X86VectorVTInfo _> {
3671   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3672                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
3673                   "$src2, $src1", "$src1, $src2",
3674                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>, EVEX_4V;
3675   let mayLoad = 1 in {
3676     defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3677                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
3678                     "$src2, $src1", "$src1, $src2",
3679                     (OpNode _.RC:$src1, (_.LdFrag addr:$src2), (i32 FROUND_CURRENT))>, EVEX_4V;
3680     defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3681                      (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
3682                      "${src2}"##_.BroadcastStr##", $src1",
3683                      "$src1, ${src2}"##_.BroadcastStr,
3684                      (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
3685                                                 (_.ScalarLdFrag addr:$src2))), (i32 FROUND_CURRENT))>,
3686                      EVEX_4V, EVEX_B;
3687   }//let mayLoad = 1
3688 }
3689
3690 multiclass avx512_fp_scalef_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
3691                             X86VectorVTInfo _> {
3692   defm rr: AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
3693                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
3694                   "$src2, $src1", "$src1, $src2",
3695                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>;
3696   let mayLoad = 1 in {
3697     defm rm: AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
3698                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
3699                     "$src2, $src1", "$src1, $src2",
3700                     (OpNode _.RC:$src1, (_.LdFrag addr:$src2), (i32 FROUND_CURRENT))>;
3701   }//let mayLoad = 1
3702 }
3703
3704 multiclass avx512_fp_scalef_all<bits<8> opc, bits<8> opcScaler, string OpcodeStr, SDNode OpNode> {
3705   defm PSZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v16f32_info>,
3706              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v16f32_info>,
3707                               EVEX_V512, EVEX_CD8<32, CD8VF>;
3708   defm PDZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f64_info>,
3709              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v8f64_info>,
3710                               EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
3711   defm SSZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNode, f32x_info>,
3712                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"ss", f32x_info, OpNode, SSE_ALU_ITINS_S.s>,
3713                               EVEX_4V,EVEX_CD8<32, CD8VT1>;
3714   defm SDZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNode, f64x_info>,
3715                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"sd", f64x_info, OpNode, SSE_ALU_ITINS_S.d>,
3716                               EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
3717
3718   // Define only if AVX512VL feature is present.
3719   let Predicates = [HasVLX] in {
3720     defm PSZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f32x_info>,
3721                                    EVEX_V128, EVEX_CD8<32, CD8VF>;
3722     defm PSZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f32x_info>,
3723                                    EVEX_V256, EVEX_CD8<32, CD8VF>;
3724     defm PDZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v2f64x_info>,
3725                                    EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
3726     defm PDZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f64x_info>,
3727                                    EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
3728   }
3729 }
3730 defm VSCALEF : avx512_fp_scalef_all<0x2C, 0x2D, "vscalef", X86scalef>, T8PD;
3731
3732 //===----------------------------------------------------------------------===//
3733 // AVX-512  VPTESTM instructions
3734 //===----------------------------------------------------------------------===//
3735
3736 multiclass avx512_vptest<bits<8> opc, string OpcodeStr, SDNode OpNode,
3737                             X86VectorVTInfo _> {
3738   defm rr : AVX512_maskable_cmp<opc, MRMSrcReg, _, (outs _.KRC:$dst),
3739                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3740                       "$src2, $src1", "$src1, $src2",
3741                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>,
3742                     EVEX_4V;
3743   let mayLoad = 1 in
3744   defm rm : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
3745                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3746                        "$src2, $src1", "$src1, $src2",
3747                    (OpNode (_.VT _.RC:$src1),
3748                     (_.VT (bitconvert (_.LdFrag addr:$src2))))>,
3749                     EVEX_4V,
3750                    EVEX_CD8<_.EltSize, CD8VF>;
3751 }
3752
3753 multiclass avx512_vptest_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3754                             X86VectorVTInfo _> {
3755   let mayLoad = 1 in
3756   defm rmb : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
3757                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
3758                     "${src2}"##_.BroadcastStr##", $src1",
3759                     "$src1, ${src2}"##_.BroadcastStr,
3760                     (OpNode (_.VT _.RC:$src1), (_.VT (X86VBroadcast
3761                                                 (_.ScalarLdFrag addr:$src2))))>,
3762                     EVEX_B, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
3763 }
3764 multiclass avx512_vptest_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
3765                                   AVX512VLVectorVTInfo _> {
3766   let Predicates  = [HasAVX512] in
3767   defm Z : avx512_vptest<opc, OpcodeStr, OpNode, _.info512>,
3768            avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
3769
3770   let Predicates = [HasAVX512, HasVLX] in {
3771   defm Z256 : avx512_vptest<opc, OpcodeStr, OpNode, _.info256>,
3772               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
3773   defm Z128 : avx512_vptest<opc, OpcodeStr, OpNode, _.info128>,
3774               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
3775   }
3776 }
3777
3778 multiclass avx512_vptest_dq<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3779   defm D : avx512_vptest_dq_sizes<opc, OpcodeStr#"d", OpNode,
3780                                  avx512vl_i32_info>;
3781   defm Q : avx512_vptest_dq_sizes<opc, OpcodeStr#"q", OpNode,
3782                                  avx512vl_i64_info>, VEX_W;
3783 }
3784
3785 multiclass avx512_vptest_wb<bits<8> opc, string OpcodeStr,
3786                                  SDNode OpNode> {
3787   let Predicates = [HasBWI] in {
3788   defm WZ:    avx512_vptest<opc, OpcodeStr#"w", OpNode, v32i16_info>,
3789               EVEX_V512, VEX_W;
3790   defm BZ:    avx512_vptest<opc, OpcodeStr#"b", OpNode, v64i8_info>,
3791               EVEX_V512;
3792   }
3793   let Predicates = [HasVLX, HasBWI] in {
3794
3795   defm WZ256: avx512_vptest<opc, OpcodeStr#"w", OpNode, v16i16x_info>,
3796               EVEX_V256, VEX_W;
3797   defm WZ128: avx512_vptest<opc, OpcodeStr#"w", OpNode, v8i16x_info>,
3798               EVEX_V128, VEX_W;
3799   defm BZ256: avx512_vptest<opc, OpcodeStr#"b", OpNode, v32i8x_info>,
3800               EVEX_V256;
3801   defm BZ128: avx512_vptest<opc, OpcodeStr#"b", OpNode, v16i8x_info>,
3802               EVEX_V128;
3803   }
3804 }
3805
3806 multiclass avx512_vptest_all_forms<bits<8> opc_wb, bits<8> opc_dq, string OpcodeStr,
3807                                    SDNode OpNode> :
3808   avx512_vptest_wb <opc_wb, OpcodeStr, OpNode>,
3809   avx512_vptest_dq<opc_dq, OpcodeStr, OpNode>;
3810
3811 defm VPTESTM   : avx512_vptest_all_forms<0x26, 0x27, "vptestm", X86testm>, T8PD;
3812 defm VPTESTNM  : avx512_vptest_all_forms<0x26, 0x27, "vptestnm", X86testnm>, T8XS;
3813
3814 def : Pat <(i16 (int_x86_avx512_mask_ptestm_d_512 (v16i32 VR512:$src1),
3815                  (v16i32 VR512:$src2), (i16 -1))),
3816                  (COPY_TO_REGCLASS (VPTESTMDZrr VR512:$src1, VR512:$src2), GR16)>;
3817
3818 def : Pat <(i8 (int_x86_avx512_mask_ptestm_q_512 (v8i64 VR512:$src1),
3819                  (v8i64 VR512:$src2), (i8 -1))),
3820                  (COPY_TO_REGCLASS (VPTESTMQZrr VR512:$src1, VR512:$src2), GR8)>;
3821
3822 //===----------------------------------------------------------------------===//
3823 // AVX-512  Shift instructions
3824 //===----------------------------------------------------------------------===//
3825 multiclass avx512_shift_rmi<bits<8> opc, Format ImmFormR, Format ImmFormM,
3826                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
3827   defm ri : AVX512_maskable<opc, ImmFormR, _, (outs _.RC:$dst),
3828                    (ins _.RC:$src1, u8imm:$src2), OpcodeStr,
3829                       "$src2, $src1", "$src1, $src2",
3830                    (_.VT (OpNode _.RC:$src1, (i8 imm:$src2))),
3831                    SSE_INTSHIFT_ITINS_P.rr>;
3832   let mayLoad = 1 in
3833   defm mi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
3834                    (ins _.MemOp:$src1, u8imm:$src2), OpcodeStr,
3835                        "$src2, $src1", "$src1, $src2",
3836                    (_.VT (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
3837                           (i8 imm:$src2))),
3838                    SSE_INTSHIFT_ITINS_P.rm>;
3839 }
3840
3841 multiclass avx512_shift_rmbi<bits<8> opc, Format ImmFormM,
3842                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
3843   let mayLoad = 1 in
3844   defm mbi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
3845                    (ins _.ScalarMemOp:$src1, u8imm:$src2), OpcodeStr,
3846       "$src2, ${src1}"##_.BroadcastStr, "${src1}"##_.BroadcastStr##", $src2",
3847      (_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src1)), (i8 imm:$src2))),
3848      SSE_INTSHIFT_ITINS_P.rm>, EVEX_B;
3849 }
3850
3851 multiclass avx512_shift_rrm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3852                          ValueType SrcVT, PatFrag bc_frag, X86VectorVTInfo _> {
3853    // src2 is always 128-bit
3854   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3855                    (ins _.RC:$src1, VR128X:$src2), OpcodeStr,
3856                       "$src2, $src1", "$src1, $src2",
3857                    (_.VT (OpNode _.RC:$src1, (SrcVT VR128X:$src2))),
3858                    SSE_INTSHIFT_ITINS_P.rr>, AVX512BIBase, EVEX_4V;
3859   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3860                    (ins _.RC:$src1, i128mem:$src2), OpcodeStr,
3861                        "$src2, $src1", "$src1, $src2",
3862                    (_.VT (OpNode _.RC:$src1, (bc_frag (loadv2i64 addr:$src2)))),
3863                    SSE_INTSHIFT_ITINS_P.rm>, AVX512BIBase,
3864                    EVEX_4V;
3865 }
3866
3867 multiclass avx512_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
3868                                   ValueType SrcVT, PatFrag bc_frag,
3869                                   AVX512VLVectorVTInfo VTInfo, Predicate prd> {
3870   let Predicates = [prd] in
3871   defm Z    : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
3872                             VTInfo.info512>, EVEX_V512,
3873                             EVEX_CD8<VTInfo.info512.EltSize, CD8VQ> ;
3874   let Predicates = [prd, HasVLX] in {
3875   defm Z256 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
3876                             VTInfo.info256>, EVEX_V256,
3877                             EVEX_CD8<VTInfo.info256.EltSize, CD8VH>;
3878   defm Z128 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
3879                             VTInfo.info128>, EVEX_V128,
3880                             EVEX_CD8<VTInfo.info128.EltSize, CD8VF>;
3881   }
3882 }
3883
3884 multiclass avx512_shift_types<bits<8> opcd, bits<8> opcq, bits<8> opcw,
3885                               string OpcodeStr, SDNode OpNode> {
3886   defm D : avx512_shift_sizes<opcd, OpcodeStr#"d", OpNode, v4i32, bc_v4i32,
3887                                  avx512vl_i32_info, HasAVX512>;
3888   defm Q : avx512_shift_sizes<opcq, OpcodeStr#"q", OpNode, v2i64, bc_v2i64,
3889                                  avx512vl_i64_info, HasAVX512>, VEX_W;
3890   defm W : avx512_shift_sizes<opcw, OpcodeStr#"w", OpNode, v8i16, bc_v8i16,
3891                                  avx512vl_i16_info, HasBWI>;
3892 }
3893
3894 multiclass avx512_shift_rmi_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
3895                                  string OpcodeStr, SDNode OpNode,
3896                                  AVX512VLVectorVTInfo VTInfo> {
3897   let Predicates = [HasAVX512] in
3898   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3899                               VTInfo.info512>,
3900              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
3901                               VTInfo.info512>, EVEX_V512;
3902   let Predicates = [HasAVX512, HasVLX] in {
3903   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3904                               VTInfo.info256>,
3905              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
3906                               VTInfo.info256>, EVEX_V256;
3907   defm Z128: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3908                               VTInfo.info128>,
3909              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
3910                               VTInfo.info128>, EVEX_V128;
3911   }
3912 }
3913
3914 multiclass avx512_shift_rmi_w<bits<8> opcw,
3915                                  Format ImmFormR, Format ImmFormM,
3916                                  string OpcodeStr, SDNode OpNode> {
3917   let Predicates = [HasBWI] in
3918   defm WZ:    avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3919                                v32i16_info>, EVEX_V512;
3920   let Predicates = [HasVLX, HasBWI] in {
3921   defm WZ256: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3922                                v16i16x_info>, EVEX_V256;
3923   defm WZ128: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
3924                                v8i16x_info>, EVEX_V128;
3925   }
3926 }
3927
3928 multiclass avx512_shift_rmi_dq<bits<8> opcd, bits<8> opcq,
3929                                  Format ImmFormR, Format ImmFormM,
3930                                  string OpcodeStr, SDNode OpNode> {
3931   defm D: avx512_shift_rmi_sizes<opcd, ImmFormR, ImmFormM, OpcodeStr#"d", OpNode,
3932                                  avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
3933   defm Q: avx512_shift_rmi_sizes<opcq, ImmFormR, ImmFormM, OpcodeStr#"q", OpNode,
3934                                  avx512vl_i64_info>, EVEX_CD8<64, CD8VF>, VEX_W;
3935 }
3936
3937 defm VPSRL : avx512_shift_rmi_dq<0x72, 0x73, MRM2r, MRM2m, "vpsrl", X86vsrli>,
3938              avx512_shift_rmi_w<0x71, MRM2r, MRM2m, "vpsrlw", X86vsrli>, AVX512BIi8Base, EVEX_4V;
3939
3940 defm VPSLL : avx512_shift_rmi_dq<0x72, 0x73, MRM6r, MRM6m, "vpsll", X86vshli>,
3941              avx512_shift_rmi_w<0x71, MRM6r, MRM6m, "vpsllw", X86vshli>, AVX512BIi8Base, EVEX_4V;
3942
3943 defm VPSRA : avx512_shift_rmi_dq<0x72, 0x72, MRM4r, MRM4m, "vpsra", X86vsrai>,
3944              avx512_shift_rmi_w<0x71, MRM4r, MRM4m, "vpsraw", X86vsrai>, AVX512BIi8Base, EVEX_4V;
3945
3946 defm VPROR : avx512_shift_rmi_dq<0x72, 0x72, MRM0r, MRM0m, "vpror", rotr>, AVX512BIi8Base, EVEX_4V;
3947 defm VPROL : avx512_shift_rmi_dq<0x72, 0x72, MRM1r, MRM1m, "vprol", rotl>, AVX512BIi8Base, EVEX_4V;
3948
3949 defm VPSLL : avx512_shift_types<0xF2, 0xF3, 0xF1, "vpsll", X86vshl>;
3950 defm VPSRA : avx512_shift_types<0xE2, 0xE2, 0xE1, "vpsra", X86vsra>;
3951 defm VPSRL : avx512_shift_types<0xD2, 0xD3, 0xD1, "vpsrl", X86vsrl>;
3952
3953 //===-------------------------------------------------------------------===//
3954 // Variable Bit Shifts
3955 //===-------------------------------------------------------------------===//
3956 multiclass avx512_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
3957                             X86VectorVTInfo _> {
3958   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3959                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3960                       "$src2, $src1", "$src1, $src2",
3961                    (_.VT (OpNode _.RC:$src1, (_.VT _.RC:$src2))),
3962                    SSE_INTSHIFT_ITINS_P.rr>, AVX5128IBase, EVEX_4V;
3963   let mayLoad = 1 in
3964   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3965                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3966                        "$src2, $src1", "$src1, $src2",
3967                    (_.VT (OpNode _.RC:$src1,
3968                    (_.VT (bitconvert (_.LdFrag addr:$src2))))),
3969                    SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_4V,
3970                    EVEX_CD8<_.EltSize, CD8VF>;
3971 }
3972
3973 multiclass avx512_var_shift_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3974                             X86VectorVTInfo _> {
3975   let mayLoad = 1 in
3976   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3977                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
3978                     "${src2}"##_.BroadcastStr##", $src1",
3979                     "$src1, ${src2}"##_.BroadcastStr,
3980                     (_.VT (OpNode _.RC:$src1, (_.VT (X86VBroadcast
3981                                                 (_.ScalarLdFrag addr:$src2))))),
3982                     SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_B,
3983                     EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
3984 }
3985 multiclass avx512_var_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
3986                                   AVX512VLVectorVTInfo _> {
3987   let Predicates  = [HasAVX512] in
3988   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
3989            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
3990
3991   let Predicates = [HasAVX512, HasVLX] in {
3992   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
3993               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
3994   defm Z128 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info128>,
3995               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
3996   }
3997 }
3998
3999 multiclass avx512_var_shift_types<bits<8> opc, string OpcodeStr,
4000                                  SDNode OpNode> {
4001   defm D : avx512_var_shift_sizes<opc, OpcodeStr#"d", OpNode,
4002                                  avx512vl_i32_info>;
4003   defm Q : avx512_var_shift_sizes<opc, OpcodeStr#"q", OpNode,
4004                                  avx512vl_i64_info>, VEX_W;
4005 }
4006
4007 multiclass avx512_var_shift_w<bits<8> opc, string OpcodeStr,
4008                                  SDNode OpNode> {
4009   let Predicates = [HasBWI] in
4010   defm WZ:    avx512_var_shift<opc, OpcodeStr, OpNode, v32i16_info>,
4011               EVEX_V512, VEX_W;
4012   let Predicates = [HasVLX, HasBWI] in {
4013
4014   defm WZ256: avx512_var_shift<opc, OpcodeStr, OpNode, v16i16x_info>,
4015               EVEX_V256, VEX_W;
4016   defm WZ128: avx512_var_shift<opc, OpcodeStr, OpNode, v8i16x_info>,
4017               EVEX_V128, VEX_W;
4018   }
4019 }
4020
4021 defm VPSLLV : avx512_var_shift_types<0x47, "vpsllv", shl>,
4022               avx512_var_shift_w<0x12, "vpsllvw", shl>;
4023 defm VPSRAV : avx512_var_shift_types<0x46, "vpsrav", sra>,
4024               avx512_var_shift_w<0x11, "vpsravw", sra>;
4025 defm VPSRLV : avx512_var_shift_types<0x45, "vpsrlv", srl>,
4026               avx512_var_shift_w<0x10, "vpsrlvw", srl>;
4027 defm VPRORV : avx512_var_shift_types<0x14, "vprorv", rotr>;
4028 defm VPROLV : avx512_var_shift_types<0x15, "vprolv", rotl>;
4029
4030 //===-------------------------------------------------------------------===//
4031 // 1-src variable permutation VPERMW/D/Q
4032 //===-------------------------------------------------------------------===//
4033 multiclass avx512_vperm_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4034                                   AVX512VLVectorVTInfo _> {
4035   let Predicates  = [HasAVX512] in
4036   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
4037            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
4038
4039   let Predicates = [HasAVX512, HasVLX] in
4040   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
4041               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
4042 }
4043
4044 multiclass avx512_vpermi_dq_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
4045                                  string OpcodeStr, SDNode OpNode,
4046                                  AVX512VLVectorVTInfo VTInfo> {
4047   let Predicates = [HasAVX512] in
4048   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4049                               VTInfo.info512>,
4050              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4051                               VTInfo.info512>, EVEX_V512;
4052   let Predicates = [HasAVX512, HasVLX] in
4053   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4054                               VTInfo.info256>,
4055              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4056                               VTInfo.info256>, EVEX_V256;
4057 }
4058
4059
4060 defm VPERM  : avx512_var_shift_w<0x8D, "vpermw", X86VPermv>;
4061
4062 defm VPERMD : avx512_vperm_dq_sizes<0x36, "vpermd", X86VPermv,
4063                                     avx512vl_i32_info>;
4064 defm VPERMQ : avx512_vperm_dq_sizes<0x36, "vpermq", X86VPermv,
4065                                     avx512vl_i64_info>, VEX_W;
4066 defm VPERMPS : avx512_vperm_dq_sizes<0x16, "vpermps", X86VPermv,
4067                                     avx512vl_f32_info>;
4068 defm VPERMPD : avx512_vperm_dq_sizes<0x16, "vpermpd", X86VPermv,
4069                                     avx512vl_f64_info>, VEX_W;
4070
4071 defm VPERMQ : avx512_vpermi_dq_sizes<0x00, MRMSrcReg, MRMSrcMem, "vpermq",
4072                              X86VPermi, avx512vl_i64_info>,
4073                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
4074 defm VPERMPD : avx512_vpermi_dq_sizes<0x01, MRMSrcReg, MRMSrcMem, "vpermpd",
4075                              X86VPermi, avx512vl_f64_info>,
4076                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
4077 //===----------------------------------------------------------------------===//
4078 // AVX-512 - VPERMIL 
4079 //===----------------------------------------------------------------------===//
4080
4081 multiclass avx512_permil_vec<bits<8> OpcVar, string OpcodeStr,  SDNode OpNode,
4082                              X86VectorVTInfo _, X86VectorVTInfo Ctrl> {
4083   defm rr: AVX512_maskable<OpcVar, MRMSrcReg, _, (outs _.RC:$dst),
4084                   (ins _.RC:$src1, Ctrl.RC:$src2), OpcodeStr,
4085                   "$src2, $src1", "$src1, $src2",
4086                   (_.VT (OpNode _.RC:$src1,
4087                                (Ctrl.VT Ctrl.RC:$src2)))>,
4088                   T8PD, EVEX_4V;
4089   let mayLoad = 1 in {
4090     defm rm: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
4091                     (ins _.RC:$src1, Ctrl.MemOp:$src2), OpcodeStr,
4092                     "$src2, $src1", "$src1, $src2",
4093                     (_.VT (OpNode
4094                              _.RC:$src1,
4095                              (Ctrl.VT (bitconvert(Ctrl.LdFrag addr:$src2)))))>,
4096                     T8PD, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
4097     defm rmb: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
4098                      (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4099                      "${src2}"##_.BroadcastStr##", $src1",
4100                      "$src1, ${src2}"##_.BroadcastStr,
4101                      (_.VT (OpNode
4102                               _.RC:$src1,
4103                               (Ctrl.VT (X86VBroadcast
4104                                          (Ctrl.ScalarLdFrag addr:$src2)))))>,
4105                      T8PD, EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
4106   }//let mayLoad = 1
4107 }
4108
4109 multiclass avx512_permil_vec_common<string OpcodeStr, bits<8> OpcVar,
4110                              AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
4111   let Predicates = [HasAVX512] in {
4112     defm Z    : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info512,
4113                                   Ctrl.info512>, EVEX_V512;
4114   }
4115   let Predicates = [HasAVX512, HasVLX] in {
4116     defm Z128 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info128,
4117                                   Ctrl.info128>, EVEX_V128;
4118     defm Z256 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info256,
4119                                   Ctrl.info256>, EVEX_V256;
4120   }
4121 }
4122
4123 multiclass avx512_permil<string OpcodeStr, bits<8> OpcImm, bits<8> OpcVar,
4124                          AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
4125
4126   defm NAME: avx512_permil_vec_common<OpcodeStr, OpcVar, _, Ctrl>;
4127   defm NAME: avx512_shift_rmi_sizes<OpcImm, MRMSrcReg, MRMSrcMem, OpcodeStr,
4128                                     X86VPermilpi, _>,
4129                     EVEX, AVX512AIi8Base, EVEX_CD8<_.info128.EltSize, CD8VF>;
4130
4131   let isCodeGenOnly = 1 in {
4132     // lowering implementation with the alternative types
4133     defm NAME#_I: avx512_permil_vec_common<OpcodeStr, OpcVar, Ctrl, Ctrl>;
4134     defm NAME#_I: avx512_shift_rmi_sizes<OpcImm, MRMSrcReg, MRMSrcMem,
4135                                          OpcodeStr, X86VPermilpi, Ctrl>,
4136                     EVEX, AVX512AIi8Base, EVEX_CD8<_.info128.EltSize, CD8VF>;
4137   }
4138 }
4139
4140 defm VPERMILPS : avx512_permil<"vpermilps", 0x04, 0x0C, avx512vl_f32_info,
4141                                avx512vl_i32_info>;
4142 defm VPERMILPD : avx512_permil<"vpermilpd", 0x05, 0x0D, avx512vl_f64_info,
4143                                avx512vl_i64_info>, VEX_W;
4144 //===----------------------------------------------------------------------===//
4145 // AVX-512 - VPSHUFD, VPSHUFLW, VPSHUFHW
4146 //===----------------------------------------------------------------------===//
4147
4148 defm VPSHUFD : avx512_shift_rmi_sizes<0x70, MRMSrcReg, MRMSrcMem, "vpshufd",
4149                              X86PShufd, avx512vl_i32_info>,
4150                              EVEX, AVX512BIi8Base, EVEX_CD8<32, CD8VF>;
4151 defm VPSHUFH : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshufhw",
4152                                   X86PShufhw>, EVEX, AVX512XSIi8Base, VEX_W;
4153 defm VPSHUFL : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshuflw",
4154                                   X86PShuflw>, EVEX, AVX512XDIi8Base, VEX_W;
4155
4156 multiclass avx512_pshufb_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode> {
4157   let Predicates = [HasBWI] in
4158   defm Z:    avx512_var_shift<opc, OpcodeStr, OpNode, v64i8_info>, EVEX_V512;
4159
4160   let Predicates = [HasVLX, HasBWI] in {
4161   defm Z256: avx512_var_shift<opc, OpcodeStr, OpNode, v32i8x_info>, EVEX_V256;
4162   defm Z128: avx512_var_shift<opc, OpcodeStr, OpNode, v16i8x_info>, EVEX_V128;
4163   }
4164 }
4165
4166 defm VPSHUFB: avx512_pshufb_sizes<0x00, "vpshufb", X86pshufb>;
4167
4168 //===----------------------------------------------------------------------===//
4169 // AVX-512 - MOVDDUP
4170 //===----------------------------------------------------------------------===//
4171
4172 multiclass avx512_movddup<string OpcodeStr, RegisterClass RC, ValueType VT,
4173                         X86MemOperand x86memop, PatFrag memop_frag> {
4174 def rr  : AVX512PDI<0x12, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4175                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4176                     [(set RC:$dst, (VT (X86Movddup RC:$src)))]>, EVEX;
4177 def rm  : AVX512PDI<0x12, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4178                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4179                     [(set RC:$dst,
4180                       (VT (X86Movddup (memop_frag addr:$src))))]>, EVEX;
4181 }
4182
4183 defm VMOVDDUPZ : avx512_movddup<"vmovddup", VR512, v8f64, f512mem, loadv8f64>,
4184                  VEX_W, EVEX_V512, EVEX_CD8<64, CD8VF>;
4185 def : Pat<(X86Movddup (v8f64 (scalar_to_vector (loadf64 addr:$src)))),
4186           (VMOVDDUPZrm addr:$src)>;
4187
4188 //===---------------------------------------------------------------------===//
4189 // Replicate Single FP - MOVSHDUP and MOVSLDUP
4190 //===---------------------------------------------------------------------===//
4191 multiclass avx512_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4192                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4193                               X86MemOperand x86memop> {
4194   def rr : AVX512XSI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4195                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4196                       [(set RC:$dst, (vt (OpNode RC:$src)))]>, EVEX;
4197   let mayLoad = 1 in
4198   def rm : AVX512XSI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4199                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4200                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>, EVEX;
4201 }
4202
4203 defm VMOVSHDUPZ  : avx512_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4204                        v16f32, VR512, loadv16f32, f512mem>, EVEX_V512,
4205                        EVEX_CD8<32, CD8VF>;
4206 defm VMOVSLDUPZ  : avx512_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4207                        v16f32, VR512, loadv16f32, f512mem>, EVEX_V512,
4208                        EVEX_CD8<32, CD8VF>;
4209
4210 def : Pat<(v16i32 (X86Movshdup VR512:$src)), (VMOVSHDUPZrr VR512:$src)>;
4211 def : Pat<(v16i32 (X86Movshdup (loadv16i32 addr:$src))),
4212            (VMOVSHDUPZrm addr:$src)>;
4213 def : Pat<(v16i32 (X86Movsldup VR512:$src)), (VMOVSLDUPZrr VR512:$src)>;
4214 def : Pat<(v16i32 (X86Movsldup (loadv16i32 addr:$src))),
4215            (VMOVSLDUPZrm addr:$src)>;
4216
4217 //===----------------------------------------------------------------------===//
4218 // Move Low to High and High to Low packed FP Instructions
4219 //===----------------------------------------------------------------------===//
4220 def VMOVLHPSZrr : AVX512PSI<0x16, MRMSrcReg, (outs VR128X:$dst),
4221           (ins VR128X:$src1, VR128X:$src2),
4222           "vmovlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4223           [(set VR128X:$dst, (v4f32 (X86Movlhps VR128X:$src1, VR128X:$src2)))],
4224            IIC_SSE_MOV_LH>, EVEX_4V;
4225 def VMOVHLPSZrr : AVX512PSI<0x12, MRMSrcReg, (outs VR128X:$dst),
4226           (ins VR128X:$src1, VR128X:$src2),
4227           "vmovhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4228           [(set VR128X:$dst, (v4f32 (X86Movhlps VR128X:$src1, VR128X:$src2)))],
4229           IIC_SSE_MOV_LH>, EVEX_4V;
4230
4231 let Predicates = [HasAVX512] in {
4232   // MOVLHPS patterns
4233   def : Pat<(v4i32 (X86Movlhps VR128X:$src1, VR128X:$src2)),
4234             (VMOVLHPSZrr VR128X:$src1, VR128X:$src2)>;
4235   def : Pat<(v2i64 (X86Movlhps VR128X:$src1, VR128X:$src2)),
4236             (VMOVLHPSZrr (v2i64 VR128X:$src1), VR128X:$src2)>;
4237
4238   // MOVHLPS patterns
4239   def : Pat<(v4i32 (X86Movhlps VR128X:$src1, VR128X:$src2)),
4240             (VMOVHLPSZrr VR128X:$src1, VR128X:$src2)>;
4241 }
4242
4243 //===----------------------------------------------------------------------===//
4244 // FMA - Fused Multiply Operations
4245 //
4246
4247 let Constraints = "$src1 = $dst" in {
4248 multiclass avx512_fma3p_213_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4249                                                             X86VectorVTInfo _> {
4250   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4251           (ins _.RC:$src2, _.RC:$src3),
4252           OpcodeStr, "$src3, $src2", "$src2, $src3",
4253           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>,
4254          AVX512FMA3Base;
4255
4256   let mayLoad = 1 in {
4257     defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4258             (ins _.RC:$src2, _.MemOp:$src3),
4259             OpcodeStr, "$src3, $src2", "$src2, $src3",
4260             (_.VT (OpNode _.RC:$src1, _.RC:$src2, (_.LdFrag addr:$src3)))>,
4261             AVX512FMA3Base;
4262
4263     defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4264               (ins _.RC:$src2, _.ScalarMemOp:$src3),
4265               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
4266               !strconcat("$src2, ${src3}", _.BroadcastStr ),
4267               (OpNode _.RC:$src1,
4268                _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))>,
4269               AVX512FMA3Base, EVEX_B;
4270   }
4271 }
4272
4273 multiclass avx512_fma3_213_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
4274                                                             X86VectorVTInfo _> {
4275   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4276           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
4277           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
4278           (_.VT ( OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3, (i32 imm:$rc)))>,
4279           AVX512FMA3Base, EVEX_B, EVEX_RC;
4280 }
4281 } // Constraints = "$src1 = $dst"
4282
4283 multiclass avx512_fma3p_213_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
4284                                      SDNode OpNodeRnd, AVX512VLVectorVTInfo _> {
4285   let Predicates = [HasAVX512] in {
4286     defm Z      : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info512>,
4287                   avx512_fma3_213_round<opc, OpcodeStr, OpNodeRnd, _.info512>,
4288                       EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
4289   }
4290   let Predicates = [HasVLX, HasAVX512] in {
4291     defm Z256 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info256>,
4292                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
4293     defm Z128 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info128>,
4294                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
4295   }
4296 }
4297
4298 multiclass avx512_fma3p_213_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
4299                                                             SDNode OpNodeRnd > {
4300     defm PS : avx512_fma3p_213_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
4301                                       avx512vl_f32_info>;
4302     defm PD : avx512_fma3p_213_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
4303                                       avx512vl_f64_info>, VEX_W;
4304 }
4305
4306 defm VFMADD213    : avx512_fma3p_213_f<0xA8, "vfmadd213", X86Fmadd, X86FmaddRnd>;
4307 defm VFMSUB213    : avx512_fma3p_213_f<0xAA, "vfmsub213", X86Fmsub, X86FmsubRnd>;
4308 defm VFMADDSUB213 : avx512_fma3p_213_f<0xA6, "vfmaddsub213", X86Fmaddsub, X86FmaddsubRnd>;
4309 defm VFMSUBADD213 : avx512_fma3p_213_f<0xA7, "vfmsubadd213", X86Fmsubadd, X86FmsubaddRnd>;
4310 defm VFNMADD213   : avx512_fma3p_213_f<0xAC, "vfnmadd213", X86Fnmadd, X86FnmaddRnd>;
4311 defm VFNMSUB213   : avx512_fma3p_213_f<0xAE, "vfnmsub213", X86Fnmsub, X86FnmsubRnd>;
4312
4313
4314 let Constraints = "$src1 = $dst" in {
4315 multiclass avx512_fma3p_231_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4316                                                             X86VectorVTInfo _> {
4317   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4318           (ins _.RC:$src2, _.RC:$src3),
4319           OpcodeStr, "$src3, $src2", "$src2, $src3",
4320           (_.VT (OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1))>,
4321          AVX512FMA3Base;
4322
4323   let mayLoad = 1 in {
4324     defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4325             (ins _.RC:$src2, _.MemOp:$src3),
4326             OpcodeStr, "$src3, $src2", "$src2, $src3",
4327             (_.VT (OpNode _.RC:$src2, (_.LdFrag addr:$src3), _.RC:$src1))>,
4328            AVX512FMA3Base;
4329
4330     defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4331            (ins _.RC:$src2, _.ScalarMemOp:$src3),
4332            OpcodeStr, "${src3}"##_.BroadcastStr##", $src2",
4333            "$src2, ${src3}"##_.BroadcastStr,
4334            (_.VT (OpNode _.RC:$src2,
4335                         (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
4336                         _.RC:$src1))>, AVX512FMA3Base, EVEX_B;
4337   }
4338 }
4339
4340 multiclass avx512_fma3_231_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
4341                                                             X86VectorVTInfo _> {
4342   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4343           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
4344           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
4345           (_.VT ( OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 imm:$rc)))>,
4346           AVX512FMA3Base, EVEX_B, EVEX_RC;
4347 }
4348 } // Constraints = "$src1 = $dst"
4349
4350 multiclass avx512_fma3p_231_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
4351                                      SDNode OpNodeRnd, AVX512VLVectorVTInfo _> {
4352   let Predicates = [HasAVX512] in {
4353     defm Z      : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info512>,
4354                   avx512_fma3_231_round<opc, OpcodeStr, OpNodeRnd, _.info512>,
4355                       EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
4356   }
4357   let Predicates = [HasVLX, HasAVX512] in {
4358     defm Z256 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info256>,
4359                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
4360     defm Z128 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info128>,
4361                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
4362   }
4363 }
4364
4365 multiclass avx512_fma3p_231_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
4366                                                             SDNode OpNodeRnd > {
4367     defm PS : avx512_fma3p_231_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
4368                                       avx512vl_f32_info>;
4369     defm PD : avx512_fma3p_231_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
4370                                       avx512vl_f64_info>, VEX_W;
4371 }
4372
4373 defm VFMADD231    : avx512_fma3p_231_f<0xB8, "vfmadd231", X86Fmadd, X86FmaddRnd>;
4374 defm VFMSUB231    : avx512_fma3p_231_f<0xBA, "vfmsub231", X86Fmsub, X86FmsubRnd>;
4375 defm VFMADDSUB231 : avx512_fma3p_231_f<0xB6, "vfmaddsub231", X86Fmaddsub, X86FmaddsubRnd>;
4376 defm VFMSUBADD231 : avx512_fma3p_231_f<0xB7, "vfmsubadd231", X86Fmsubadd, X86FmsubaddRnd>;
4377 defm VFNMADD231   : avx512_fma3p_231_f<0xBC, "vfnmadd231", X86Fnmadd, X86FnmaddRnd>;
4378 defm VFNMSUB231   : avx512_fma3p_231_f<0xBE, "vfnmsub231", X86Fnmsub, X86FnmsubRnd>;
4379
4380 let Constraints = "$src1 = $dst" in {
4381 multiclass avx512_fma3p_132_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4382                                                             X86VectorVTInfo _> {
4383   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4384           (ins _.RC:$src3, _.RC:$src2),
4385           OpcodeStr, "$src2, $src3", "$src3, $src2",
4386           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>,
4387          AVX512FMA3Base;
4388
4389   let mayLoad = 1 in {
4390     defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4391             (ins _.RC:$src3, _.MemOp:$src2),
4392             OpcodeStr, "$src2, $src3", "$src3, $src2",
4393             (_.VT (OpNode _.RC:$src1, (_.LdFrag addr:$src2), _.RC:$src3))>,
4394            AVX512FMA3Base;
4395
4396     defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
4397            (ins _.RC:$src3, _.ScalarMemOp:$src2),
4398            OpcodeStr, "${src2}"##_.BroadcastStr##", $src3",
4399            "$src3, ${src2}"##_.BroadcastStr,
4400            (_.VT (OpNode _.RC:$src1,
4401                         (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
4402                         _.RC:$src3))>, AVX512FMA3Base, EVEX_B;
4403   }
4404 }
4405
4406 multiclass avx512_fma3_132_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
4407                                                             X86VectorVTInfo _> {
4408   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
4409           (ins _.RC:$src3, _.RC:$src2, AVX512RC:$rc),
4410           OpcodeStr, "$rc, $src2, $src3", "$src3, $src2, $rc",
4411           (_.VT ( OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3, (i32 imm:$rc)))>,
4412           AVX512FMA3Base, EVEX_B, EVEX_RC;
4413 }
4414 } // Constraints = "$src1 = $dst"
4415
4416 multiclass avx512_fma3p_132_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
4417                                      SDNode OpNodeRnd, AVX512VLVectorVTInfo _> {
4418   let Predicates = [HasAVX512] in {
4419     defm Z      : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info512>,
4420                   avx512_fma3_132_round<opc, OpcodeStr, OpNodeRnd, _.info512>,
4421                       EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
4422   }
4423   let Predicates = [HasVLX, HasAVX512] in {
4424     defm Z256 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info256>,
4425                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
4426     defm Z128 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info128>,
4427                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
4428   }
4429 }
4430
4431 multiclass avx512_fma3p_132_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
4432                                                             SDNode OpNodeRnd > {
4433     defm PS : avx512_fma3p_132_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
4434                                       avx512vl_f32_info>;
4435     defm PD : avx512_fma3p_132_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
4436                                       avx512vl_f64_info>, VEX_W;
4437 }
4438
4439 defm VFMADD132    : avx512_fma3p_132_f<0x98, "vfmadd132", X86Fmadd, X86FmaddRnd>;
4440 defm VFMSUB132    : avx512_fma3p_132_f<0x9A, "vfmsub132", X86Fmsub, X86FmsubRnd>;
4441 defm VFMADDSUB132 : avx512_fma3p_132_f<0x96, "vfmaddsub132", X86Fmaddsub, X86FmaddsubRnd>;
4442 defm VFMSUBADD132 : avx512_fma3p_132_f<0x97, "vfmsubadd132", X86Fmsubadd, X86FmsubaddRnd>;
4443 defm VFNMADD132   : avx512_fma3p_132_f<0x9C, "vfnmadd132", X86Fnmadd, X86FnmaddRnd>;
4444 defm VFNMSUB132   : avx512_fma3p_132_f<0x9E, "vfnmsub132", X86Fnmsub, X86FnmsubRnd>;
4445
4446 // Scalar FMA
4447 let Constraints = "$src1 = $dst" in {
4448 multiclass avx512_fma3s_common<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4449                                dag RHS_VEC_r, dag RHS_VEC_m, dag RHS_VEC_rb,
4450                                                         dag RHS_r, dag RHS_m > {
4451   defm r_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4452           (ins _.RC:$src2, _.RC:$src3), OpcodeStr,
4453           "$src3, $src2", "$src2, $src3", RHS_VEC_r>, AVX512FMA3Base;
4454
4455   let mayLoad = 1 in
4456     defm m_Int: AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4457             (ins _.RC:$src2, _.MemOp:$src3), OpcodeStr,
4458             "$src3, $src2", "$src2, $src3", RHS_VEC_m>, AVX512FMA3Base;
4459
4460   defm rb_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4461          (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
4462          OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", RHS_VEC_rb>,
4463                                        AVX512FMA3Base, EVEX_B, EVEX_RC;
4464
4465   let isCodeGenOnly = 1 in {
4466     def r     : AVX512FMA3<opc, MRMSrcReg, (outs _.FRC:$dst),
4467                      (ins _.FRC:$src1, _.FRC:$src2, _.FRC:$src3),
4468                      !strconcat(OpcodeStr,
4469                               "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4470                      [RHS_r]>;
4471     let mayLoad = 1 in
4472       def m     : AVX512FMA3<opc, MRMSrcMem, (outs _.FRC:$dst),
4473                       (ins _.FRC:$src1, _.FRC:$src2, _.ScalarMemOp:$src3),
4474                       !strconcat(OpcodeStr,
4475                                  "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4476                       [RHS_m]>;
4477   }// isCodeGenOnly = 1
4478 }
4479 }// Constraints = "$src1 = $dst"
4480
4481 multiclass avx512_fma3s_all<bits<8> opc213, bits<8> opc231, bits<8> opc132,
4482          string OpcodeStr, SDNode OpNode, SDNode OpNodeRnd, X86VectorVTInfo _ ,
4483                                                                   string SUFF> {
4484
4485   defm NAME#213#SUFF: avx512_fma3s_common<opc213, OpcodeStr#"213"#_.Suffix , _ ,
4486                 (_.VT (OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3)),
4487                 (_.VT (OpNode _.RC:$src2, _.RC:$src1,
4488                          (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))))),
4489                 (_.VT ( OpNodeRnd _.RC:$src2, _.RC:$src1, _.RC:$src3,
4490                          (i32 imm:$rc))),
4491                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
4492                          _.FRC:$src3))),
4493                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
4494                          (_.ScalarLdFrag addr:$src3))))>;
4495
4496   defm NAME#231#SUFF: avx512_fma3s_common<opc231, OpcodeStr#"231"#_.Suffix , _ ,
4497                 (_.VT (OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1)),
4498                 (_.VT (OpNode _.RC:$src2,
4499                        (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))),
4500                               _.RC:$src1)),
4501                 (_.VT ( OpNodeRnd _.RC:$src2, _.RC:$src3, _.RC:$src1,
4502                                   (i32 imm:$rc))),
4503                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src3,
4504                                           _.FRC:$src1))),
4505                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2,
4506                             (_.ScalarLdFrag addr:$src3), _.FRC:$src1)))>;
4507
4508   defm NAME#132#SUFF: avx512_fma3s_common<opc132, OpcodeStr#"132"#_.Suffix , _ ,
4509                 (_.VT (OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2)),
4510                 (_.VT (OpNode _.RC:$src1,
4511                        (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))),
4512                               _.RC:$src2)),
4513                 (_.VT ( OpNodeRnd _.RC:$src1, _.RC:$src3, _.RC:$src2,
4514                          (i32 imm:$rc))),
4515                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1, _.FRC:$src3,
4516                          _.FRC:$src2))),
4517                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1,
4518                           (_.ScalarLdFrag addr:$src3), _.FRC:$src2)))>;
4519 }
4520
4521 multiclass avx512_fma3s<bits<8> opc213, bits<8> opc231, bits<8> opc132,
4522                              string OpcodeStr, SDNode OpNode, SDNode OpNodeRnd>{
4523   let Predicates = [HasAVX512] in {
4524     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
4525                                    OpNodeRnd, f32x_info, "SS">,
4526                                    EVEX_CD8<32, CD8VT1>, VEX_LIG;
4527     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
4528                                    OpNodeRnd, f64x_info, "SD">,
4529                                    EVEX_CD8<64, CD8VT1>, VEX_LIG, VEX_W;
4530   }
4531 }
4532
4533 defm VFMADD  : avx512_fma3s<0xA9, 0xB9, 0x99, "vfmadd", X86Fmadd, X86FmaddRnd>;
4534 defm VFMSUB  : avx512_fma3s<0xAB, 0xBB, 0x9B, "vfmsub", X86Fmsub, X86FmsubRnd>;
4535 defm VFNMADD : avx512_fma3s<0xAD, 0xBD, 0x9D, "vfnmadd", X86Fnmadd, X86FnmaddRnd>;
4536 defm VFNMSUB : avx512_fma3s<0xAF, 0xBF, 0x9F, "vfnmsub", X86Fnmsub, X86FnmsubRnd>;
4537
4538 //===----------------------------------------------------------------------===//
4539 // AVX-512  Scalar convert from sign integer to float/double
4540 //===----------------------------------------------------------------------===//
4541
4542 multiclass avx512_vcvtsi<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
4543                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
4544                     PatFrag ld_frag, string asm> {
4545   let hasSideEffects = 0 in {
4546     def rr : SI<opc, MRMSrcReg, (outs DstVT.FRC:$dst),
4547               (ins DstVT.FRC:$src1, SrcRC:$src),
4548               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
4549               EVEX_4V;
4550     let mayLoad = 1 in
4551       def rm : SI<opc, MRMSrcMem, (outs DstVT.FRC:$dst),
4552               (ins DstVT.FRC:$src1, x86memop:$src),
4553               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
4554               EVEX_4V;
4555   } // hasSideEffects = 0
4556   let isCodeGenOnly = 1 in {
4557     def rr_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
4558                   (ins DstVT.RC:$src1, SrcRC:$src2),
4559                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4560                   [(set DstVT.RC:$dst,
4561                         (OpNode (DstVT.VT DstVT.RC:$src1),
4562                                  SrcRC:$src2,
4563                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
4564
4565     def rm_Int : SI<opc, MRMSrcMem, (outs DstVT.RC:$dst),
4566                   (ins DstVT.RC:$src1, x86memop:$src2),
4567                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4568                   [(set DstVT.RC:$dst,
4569                         (OpNode (DstVT.VT DstVT.RC:$src1),
4570                                  (ld_frag addr:$src2),
4571                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
4572   }//isCodeGenOnly = 1
4573 }
4574
4575 multiclass avx512_vcvtsi_round<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
4576                     X86VectorVTInfo DstVT, string asm> {
4577   def rrb_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
4578               (ins DstVT.RC:$src1, SrcRC:$src2, AVX512RC:$rc),
4579               !strconcat(asm,
4580                   "\t{$src2, $rc, $src1, $dst|$dst, $src1, $rc, $src2}"),
4581               [(set DstVT.RC:$dst,
4582                     (OpNode (DstVT.VT DstVT.RC:$src1),
4583                              SrcRC:$src2,
4584                              (i32 imm:$rc)))]>, EVEX_4V, EVEX_B, EVEX_RC;
4585 }
4586
4587 multiclass avx512_vcvtsi_common<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
4588                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
4589                     PatFrag ld_frag, string asm> {
4590   defm NAME : avx512_vcvtsi_round<opc, OpNode, SrcRC, DstVT, asm>,
4591               avx512_vcvtsi<opc, OpNode, SrcRC, DstVT, x86memop, ld_frag, asm>,
4592                         VEX_LIG;
4593 }
4594
4595 let Predicates = [HasAVX512] in {
4596 defm VCVTSI2SSZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
4597                                  v4f32x_info, i32mem, loadi32, "cvtsi2ss{l}">,
4598                                  XS, EVEX_CD8<32, CD8VT1>;
4599 defm VCVTSI642SSZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
4600                                  v4f32x_info, i64mem, loadi64, "cvtsi2ss{q}">,
4601                                  XS, VEX_W, EVEX_CD8<64, CD8VT1>;
4602 defm VCVTSI2SDZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
4603                                  v2f64x_info, i32mem, loadi32, "cvtsi2sd{l}">,
4604                                  XD, EVEX_CD8<32, CD8VT1>;
4605 defm VCVTSI642SDZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
4606                                  v2f64x_info, i64mem, loadi64, "cvtsi2sd{q}">,
4607                                  XD, VEX_W, EVEX_CD8<64, CD8VT1>;
4608
4609 def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
4610           (VCVTSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
4611 def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
4612           (VCVTSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
4613 def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
4614           (VCVTSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
4615 def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
4616           (VCVTSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
4617
4618 def : Pat<(f32 (sint_to_fp GR32:$src)),
4619           (VCVTSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
4620 def : Pat<(f32 (sint_to_fp GR64:$src)),
4621           (VCVTSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
4622 def : Pat<(f64 (sint_to_fp GR32:$src)),
4623           (VCVTSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
4624 def : Pat<(f64 (sint_to_fp GR64:$src)),
4625           (VCVTSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
4626
4627 defm VCVTUSI2SSZ   : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR32,
4628                                   v4f32x_info, i32mem, loadi32,
4629                                   "cvtusi2ss{l}">, XS, EVEX_CD8<32, CD8VT1>;
4630 defm VCVTUSI642SSZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
4631                                   v4f32x_info, i64mem, loadi64, "cvtusi2ss{q}">,
4632                                   XS, VEX_W, EVEX_CD8<64, CD8VT1>;
4633 defm VCVTUSI2SDZ   : avx512_vcvtsi<0x7B, X86UintToFpRnd, GR32, v2f64x_info,
4634                                   i32mem, loadi32, "cvtusi2sd{l}">,
4635                                   XD, VEX_LIG, EVEX_CD8<32, CD8VT1>;
4636 defm VCVTUSI642SDZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
4637                                   v2f64x_info, i64mem, loadi64, "cvtusi2sd{q}">,
4638                                   XD, VEX_W, EVEX_CD8<64, CD8VT1>;
4639
4640 def : Pat<(f32 (uint_to_fp (loadi32 addr:$src))),
4641           (VCVTUSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
4642 def : Pat<(f32 (uint_to_fp (loadi64 addr:$src))),
4643           (VCVTUSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
4644 def : Pat<(f64 (uint_to_fp (loadi32 addr:$src))),
4645           (VCVTUSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
4646 def : Pat<(f64 (uint_to_fp (loadi64 addr:$src))),
4647           (VCVTUSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
4648
4649 def : Pat<(f32 (uint_to_fp GR32:$src)),
4650           (VCVTUSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
4651 def : Pat<(f32 (uint_to_fp GR64:$src)),
4652           (VCVTUSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
4653 def : Pat<(f64 (uint_to_fp GR32:$src)),
4654           (VCVTUSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
4655 def : Pat<(f64 (uint_to_fp GR64:$src)),
4656           (VCVTUSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
4657 }
4658
4659 //===----------------------------------------------------------------------===//
4660 // AVX-512  Scalar convert from float/double to integer
4661 //===----------------------------------------------------------------------===//
4662 multiclass avx512_cvt_s_int_round<bits<8> opc, RegisterClass SrcRC, 
4663                                   RegisterClass DstRC, Intrinsic Int,
4664                            Operand memop, ComplexPattern mem_cpat, string asm> {
4665   let hasSideEffects = 0, Predicates = [HasAVX512] in {
4666     def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
4667                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
4668                 [(set DstRC:$dst, (Int SrcRC:$src))]>, EVEX, VEX_LIG;
4669     def rb : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src, AVX512RC:$rc),
4670                 !strconcat(asm,"\t{$rc, $src, $dst|$dst, $src, $rc}"), []>, 
4671                 EVEX, VEX_LIG, EVEX_B, EVEX_RC;
4672     let mayLoad = 1 in
4673     def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
4674                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"), []>, EVEX, VEX_LIG;
4675   } // hasSideEffects = 0, Predicates = [HasAVX512] 
4676 }
4677
4678 // Convert float/double to signed/unsigned int 32/64
4679 defm VCVTSS2SIZ: avx512_cvt_s_int_round<0x2D, VR128X, GR32, int_x86_sse_cvtss2si,
4680                                    ssmem, sse_load_f32, "cvtss2si">,
4681                                    XS, EVEX_CD8<32, CD8VT1>;
4682 defm VCVTSS2SI64Z: avx512_cvt_s_int_round<0x2D, VR128X, GR64, 
4683                                   int_x86_sse_cvtss2si64,
4684                                    ssmem, sse_load_f32, "cvtss2si">,
4685                                    XS, VEX_W, EVEX_CD8<32, CD8VT1>;
4686 defm VCVTSS2USIZ: avx512_cvt_s_int_round<0x79, VR128X, GR32, 
4687                                   int_x86_avx512_cvtss2usi,
4688                                    ssmem, sse_load_f32, "cvtss2usi">,
4689                                    XS, EVEX_CD8<32, CD8VT1>;
4690 defm VCVTSS2USI64Z: avx512_cvt_s_int_round<0x79, VR128X, GR64,
4691                                    int_x86_avx512_cvtss2usi64, ssmem,
4692                                    sse_load_f32, "cvtss2usi">, XS, VEX_W,
4693                                    EVEX_CD8<32, CD8VT1>;
4694 defm VCVTSD2SIZ: avx512_cvt_s_int_round<0x2D, VR128X, GR32, int_x86_sse2_cvtsd2si,
4695                                    sdmem, sse_load_f64, "cvtsd2si">,
4696                                    XD, EVEX_CD8<64, CD8VT1>;
4697 defm VCVTSD2SI64Z: avx512_cvt_s_int_round<0x2D, VR128X, GR64, 
4698                                    int_x86_sse2_cvtsd2si64,
4699                                    sdmem, sse_load_f64, "cvtsd2si">,
4700                                    XD, VEX_W, EVEX_CD8<64, CD8VT1>;
4701 defm VCVTSD2USIZ:   avx512_cvt_s_int_round<0x79, VR128X, GR32, 
4702                                    int_x86_avx512_cvtsd2usi,
4703                                    sdmem, sse_load_f64, "cvtsd2usi">,
4704                                    XD, EVEX_CD8<64, CD8VT1>;
4705 defm VCVTSD2USI64Z: avx512_cvt_s_int_round<0x79, VR128X, GR64,
4706                                    int_x86_avx512_cvtsd2usi64, sdmem,
4707                                    sse_load_f64, "cvtsd2usi">, XD, VEX_W,
4708                                    EVEX_CD8<64, CD8VT1>;
4709
4710 let isCodeGenOnly = 1 , Predicates = [HasAVX512] in {
4711   defm Int_VCVTSI2SSZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
4712             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
4713             SSE_CVT_Scalar, 0>, XS, EVEX_4V;
4714   defm Int_VCVTSI2SS64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
4715             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
4716             SSE_CVT_Scalar, 0>, XS, EVEX_4V, VEX_W;
4717   defm Int_VCVTSI2SDZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
4718             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
4719             SSE_CVT_Scalar, 0>, XD, EVEX_4V;
4720   defm Int_VCVTSI2SD64Z : sse12_cvt_sint_3addr<0x2A, GR64, VR128X,
4721             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
4722             SSE_CVT_Scalar, 0>, XD, EVEX_4V, VEX_W;
4723
4724   defm Int_VCVTUSI2SDZ : sse12_cvt_sint_3addr<0x2A, GR32, VR128X,
4725             int_x86_avx512_cvtusi2sd, i32mem, loadi32, "cvtusi2sd{l}",
4726             SSE_CVT_Scalar, 0>, XD, EVEX_4V;
4727 } // isCodeGenOnly = 1, Predicates = [HasAVX512]
4728
4729 // Convert float/double to signed/unsigned int 32/64 with truncation
4730 multiclass avx512_cvt_s_all<bits<8> opc, string asm, X86VectorVTInfo _SrcRC, 
4731                             X86VectorVTInfo _DstRC, SDNode OpNode, 
4732                             SDNode OpNodeRnd>{
4733 let Predicates = [HasAVX512] in {
4734   def rr : SI<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
4735               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
4736               [(set _DstRC.RC:$dst, (OpNode _SrcRC.FRC:$src))]>, EVEX;
4737   def rb : SI<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
4738                 !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
4739                 []>, EVEX, EVEX_B;
4740   def rm : SI<opc, MRMSrcMem, (outs _DstRC.RC:$dst), (ins _SrcRC.MemOp:$src),
4741               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
4742               [(set _DstRC.RC:$dst, (OpNode (_SrcRC.ScalarLdFrag addr:$src)))]>, 
4743               EVEX;
4744
4745   let isCodeGenOnly = 1,hasSideEffects = 0 in {
4746       def rr_Int : SI<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
4747                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
4748                [(set _DstRC.RC:$dst, (OpNodeRnd _SrcRC.RC:$src,
4749                                      (i32 FROUND_CURRENT)))]>, EVEX, VEX_LIG;
4750       def rb_Int : SI<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
4751                 !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
4752                 [(set _DstRC.RC:$dst, (OpNodeRnd _SrcRC.RC:$src, 
4753                                       (i32 FROUND_NO_EXC)))]>, 
4754                                       EVEX,VEX_LIG , EVEX_B;
4755       let mayLoad = 1 in
4756         def rm_Int : SI<opc, MRMSrcMem, (outs _DstRC.RC:$dst), 
4757                     (ins _SrcRC.MemOp:$src),
4758                     !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
4759                     []>, EVEX, VEX_LIG;
4760
4761   } // isCodeGenOnly = 1, hasSideEffects = 0
4762 } //HasAVX512
4763 }
4764
4765
4766 defm VCVTTSS2SIZ: avx512_cvt_s_all<0x2C, "cvttss2si", f32x_info, i32x_info, 
4767                         fp_to_sint,X86cvttss2IntRnd>, 
4768                         XS, EVEX_CD8<32, CD8VT1>;
4769 defm VCVTTSS2SI64Z: avx512_cvt_s_all<0x2C, "cvttss2si", f32x_info, i64x_info, 
4770                         fp_to_sint,X86cvttss2IntRnd>, 
4771                         VEX_W, XS, EVEX_CD8<32, CD8VT1>;
4772 defm VCVTTSD2SIZ: avx512_cvt_s_all<0x2C, "cvttsd2si", f64x_info, i32x_info, 
4773                         fp_to_sint,X86cvttsd2IntRnd>,
4774                         XD, EVEX_CD8<64, CD8VT1>;
4775 defm VCVTTSD2SI64Z: avx512_cvt_s_all<0x2C, "cvttsd2si", f64x_info, i64x_info, 
4776                         fp_to_sint,X86cvttsd2IntRnd>, 
4777                         VEX_W, XD, EVEX_CD8<64, CD8VT1>;
4778
4779 defm VCVTTSS2USIZ: avx512_cvt_s_all<0x78, "cvttss2usi", f32x_info, i32x_info, 
4780                         fp_to_uint,X86cvttss2UIntRnd>, 
4781                         XS, EVEX_CD8<32, CD8VT1>;
4782 defm VCVTTSS2USI64Z: avx512_cvt_s_all<0x78, "cvttss2usi", f32x_info, i64x_info, 
4783                         fp_to_uint,X86cvttss2UIntRnd>, 
4784                         XS,VEX_W, EVEX_CD8<32, CD8VT1>;
4785 defm VCVTTSD2USIZ: avx512_cvt_s_all<0x78, "cvttsd2usi", f64x_info, i32x_info, 
4786                         fp_to_uint,X86cvttsd2UIntRnd>, 
4787                         XD, EVEX_CD8<64, CD8VT1>;
4788 defm VCVTTSD2USI64Z: avx512_cvt_s_all<0x78, "cvttsd2usi", f64x_info, i64x_info, 
4789                         fp_to_uint,X86cvttsd2UIntRnd>, 
4790                         XD, VEX_W, EVEX_CD8<64, CD8VT1>;
4791 let Predicates = [HasAVX512] in {
4792   def : Pat<(i32 (int_x86_sse_cvttss2si (v4f32 VR128X:$src))),
4793             (VCVTTSS2SIZrr_Int (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
4794   def : Pat<(i64 (int_x86_sse_cvttss2si64 (v4f32 VR128X:$src))),
4795             (VCVTTSS2SI64Zrr_Int (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
4796   def : Pat<(i32 (int_x86_sse2_cvttsd2si (v2f64 VR128X:$src))),
4797             (VCVTTSD2SIZrr_Int (COPY_TO_REGCLASS VR128X:$src, FR64X))>;
4798   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (v2f64 VR128X:$src))),
4799             (VCVTTSD2SI64Zrr_Int (COPY_TO_REGCLASS VR128X:$src, FR64X))>;
4800
4801 } // HasAVX512
4802 //===----------------------------------------------------------------------===//
4803 // AVX-512  Convert form float to double and back
4804 //===----------------------------------------------------------------------===//
4805 multiclass avx512_cvt_fp_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4806                          X86VectorVTInfo _Src, SDNode OpNode> {
4807   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4808                          (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr, 
4809                          "$src2, $src1", "$src1, $src2",
4810                          (_.VT (OpNode (_Src.VT _Src.RC:$src1),
4811                                        (_Src.VT _Src.RC:$src2)))>, 
4812                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
4813   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4814                          (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr, 
4815                          "$src2, $src1", "$src1, $src2",
4816                          (_.VT (OpNode (_Src.VT _Src.RC:$src1), 
4817                                   (_Src.VT (scalar_to_vector 
4818                                             (_Src.ScalarLdFrag addr:$src2)))))>, 
4819                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
4820 }
4821
4822 // Scalar Coversion with SAE - suppress all exceptions
4823 multiclass avx512_cvt_fp_sae_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4824                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
4825   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4826                         (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
4827                         "{sae}, $src2, $src1", "$src1, $src2, {sae}",
4828                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src1), 
4829                                          (_Src.VT _Src.RC:$src2),
4830                                          (i32 FROUND_NO_EXC)))>,
4831                         EVEX_4V, VEX_LIG, EVEX_B;
4832 }
4833
4834 // Scalar Conversion with rounding control (RC)
4835 multiclass avx512_cvt_fp_rc_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4836                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
4837   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4838                         (ins _Src.RC:$src1, _Src.RC:$src2, AVX512RC:$rc), OpcodeStr,
4839                         "$rc, $src2, $src1", "$src1, $src2, $rc",
4840                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src1), 
4841                                          (_Src.VT _Src.RC:$src2), (i32 imm:$rc)))>,
4842                         EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>,
4843                         EVEX_B, EVEX_RC;
4844 }
4845 multiclass avx512_cvt_fp_scalar_sd2ss<bits<8> opc, string OpcodeStr, SDNode OpNode, 
4846                                   SDNode OpNodeRnd, X86VectorVTInfo _src, 
4847                                                         X86VectorVTInfo _dst> {
4848   let Predicates = [HasAVX512] in {
4849     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNode>,
4850              avx512_cvt_fp_rc_scalar<opc, OpcodeStr, _dst, _src,
4851                                OpNodeRnd>, VEX_W, EVEX_CD8<64, CD8VT1>,
4852                                EVEX_V512, XD;
4853   }
4854 }
4855
4856 multiclass avx512_cvt_fp_scalar_ss2sd<bits<8> opc, string OpcodeStr, SDNode OpNode, 
4857                                     SDNode OpNodeRnd, X86VectorVTInfo _src, 
4858                                                           X86VectorVTInfo _dst> {
4859   let Predicates = [HasAVX512] in {
4860     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNode>,
4861              avx512_cvt_fp_sae_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>, 
4862              EVEX_CD8<32, CD8VT1>, XS, EVEX_V512;
4863   }
4864 }
4865 defm VCVTSD2SS : avx512_cvt_fp_scalar_sd2ss<0x5A, "vcvtsd2ss", X86fround,
4866                                          X86froundRnd, f64x_info, f32x_info>;
4867 defm VCVTSS2SD : avx512_cvt_fp_scalar_ss2sd<0x5A, "vcvtss2sd", X86fpext, 
4868                                           X86fpextRnd,f32x_info, f64x_info >;
4869
4870 def : Pat<(f64 (fextend FR32X:$src)), 
4871           (COPY_TO_REGCLASS (VCVTSS2SDZrr (COPY_TO_REGCLASS FR32X:$src, VR128X), 
4872                                (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>,
4873           Requires<[HasAVX512]>;
4874 def : Pat<(f64 (fextend (loadf32 addr:$src))),
4875           (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
4876           Requires<[HasAVX512]>;
4877
4878 def : Pat<(f64 (extloadf32 addr:$src)),
4879       (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
4880       Requires<[HasAVX512, OptForSize]>;
4881
4882 def : Pat<(f64 (extloadf32 addr:$src)),
4883           (COPY_TO_REGCLASS (VCVTSS2SDZrr (v4f32 (IMPLICIT_DEF)), 
4884                     (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)), VR128X)>,
4885           Requires<[HasAVX512, OptForSpeed]>;
4886
4887 def : Pat<(f32 (fround FR64X:$src)), 
4888           (COPY_TO_REGCLASS (VCVTSD2SSZrr (COPY_TO_REGCLASS FR64X:$src, VR128X), 
4889                     (COPY_TO_REGCLASS FR64X:$src, VR128X)), VR128X)>,
4890            Requires<[HasAVX512]>;
4891 //===----------------------------------------------------------------------===//
4892 // AVX-512  Vector convert from signed/unsigned integer to float/double
4893 //          and from float/double to signed/unsigned integer
4894 //===----------------------------------------------------------------------===//
4895
4896 multiclass avx512_vcvt_fp<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4897                          X86VectorVTInfo _Src, SDNode OpNode,
4898                          string Broadcast = _.BroadcastStr,
4899                          string Alias = ""> {
4900
4901   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4902                          (ins _Src.RC:$src), OpcodeStr, "$src", "$src",
4903                          (_.VT (OpNode (_Src.VT _Src.RC:$src)))>, EVEX;
4904
4905   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4906                          (ins _Src.MemOp:$src), OpcodeStr#Alias, "$src", "$src",
4907                          (_.VT (OpNode (_Src.VT
4908                              (bitconvert (_Src.LdFrag addr:$src)))))>, EVEX;
4909
4910   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4911                          (ins _Src.MemOp:$src), OpcodeStr,
4912                          "${src}"##Broadcast, "${src}"##Broadcast,
4913                          (_.VT (OpNode (_Src.VT
4914                                   (X86VBroadcast (_Src.ScalarLdFrag addr:$src)))
4915                             ))>, EVEX, EVEX_B;
4916 }
4917 // Coversion with SAE - suppress all exceptions
4918 multiclass avx512_vcvt_fp_sae<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4919                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
4920   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4921                         (ins _Src.RC:$src), OpcodeStr,
4922                         "{sae}, $src", "$src, {sae}",
4923                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src),
4924                                (i32 FROUND_NO_EXC)))>,
4925                         EVEX, EVEX_B;
4926 }
4927
4928 // Conversion with rounding control (RC)
4929 multiclass avx512_vcvt_fp_rc<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
4930                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
4931   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4932                         (ins _Src.RC:$src, AVX512RC:$rc), OpcodeStr,
4933                         "$rc, $src", "$src, $rc",
4934                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 imm:$rc)))>,
4935                         EVEX, EVEX_B, EVEX_RC;
4936 }
4937
4938 // Extend Float to Double
4939 multiclass avx512_cvtps2pd<bits<8> opc, string OpcodeStr> {
4940   let Predicates = [HasAVX512] in {
4941     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8f32x_info, fextend>,
4942              avx512_vcvt_fp_sae<opc, OpcodeStr, v8f64_info, v8f32x_info,
4943                                 X86vfpextRnd>, EVEX_V512;
4944   }
4945   let Predicates = [HasVLX] in {
4946     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4f32x_info,
4947                                X86vfpext, "{1to2}">, EVEX_V128;
4948     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4f32x_info, fextend>,
4949                                      EVEX_V256;
4950   }
4951 }
4952
4953 // Truncate Double to Float
4954 multiclass avx512_cvtpd2ps<bits<8> opc, string OpcodeStr> {
4955   let Predicates = [HasAVX512] in {
4956     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8f64_info, fround>,
4957              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8f64_info,
4958                                X86vfproundRnd>, EVEX_V512;
4959   }
4960   let Predicates = [HasVLX] in {
4961     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2f64x_info,
4962                                X86vfpround, "{1to2}", "{x}">, EVEX_V128;
4963     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4f64x_info, fround,
4964                                "{1to4}", "{y}">, EVEX_V256;
4965   }
4966 }
4967
4968 defm VCVTPD2PS : avx512_cvtpd2ps<0x5A, "vcvtpd2ps">,
4969                                   VEX_W, PD, EVEX_CD8<64, CD8VF>;
4970 defm VCVTPS2PD : avx512_cvtps2pd<0x5A, "vcvtps2pd">,
4971                                   PS, EVEX_CD8<32, CD8VH>;
4972
4973 def : Pat<(v8f64 (extloadv8f32 addr:$src)),
4974             (VCVTPS2PDZrm addr:$src)>;
4975
4976 let Predicates = [HasVLX] in {
4977   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
4978               (VCVTPS2PDZ256rm addr:$src)>;
4979 }
4980
4981 // Convert Signed/Unsigned Doubleword to Double
4982 multiclass avx512_cvtdq2pd<bits<8> opc, string OpcodeStr, SDNode OpNode,
4983                            SDNode OpNode128> {
4984   // No rounding in this op
4985   let Predicates = [HasAVX512] in
4986     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i32x_info, OpNode>,
4987                                      EVEX_V512;
4988
4989   let Predicates = [HasVLX] in {
4990     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4i32x_info,
4991                                      OpNode128, "{1to2}">, EVEX_V128;
4992     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i32x_info, OpNode>,
4993                                      EVEX_V256;
4994   }
4995 }
4996
4997 // Convert Signed/Unsigned Doubleword to Float
4998 multiclass avx512_cvtdq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
4999                            SDNode OpNodeRnd> {
5000   let Predicates = [HasAVX512] in
5001     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16f32_info, v16i32_info, OpNode>,
5002              avx512_vcvt_fp_rc<opc, OpcodeStr, v16f32_info, v16i32_info,
5003                                OpNodeRnd>, EVEX_V512;
5004
5005   let Predicates = [HasVLX] in {
5006     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i32x_info, OpNode>,
5007                                      EVEX_V128;
5008     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i32x_info, OpNode>,
5009                                      EVEX_V256;
5010   }
5011 }
5012
5013 // Convert Float to Signed/Unsigned Doubleword with truncation
5014 multiclass avx512_cvttps2dq<bits<8> opc, string OpcodeStr,
5015                                   SDNode OpNode, SDNode OpNodeRnd> {
5016   let Predicates = [HasAVX512] in {
5017     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
5018              avx512_vcvt_fp_sae<opc, OpcodeStr, v16i32_info, v16f32_info,
5019                                 OpNodeRnd>, EVEX_V512;
5020   }
5021   let Predicates = [HasVLX] in {
5022     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
5023                                      EVEX_V128;
5024     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
5025                                      EVEX_V256;
5026   }
5027 }
5028
5029 // Convert Float to Signed/Unsigned Doubleword
5030 multiclass avx512_cvtps2dq<bits<8> opc, string OpcodeStr,
5031                                   SDNode OpNode, SDNode OpNodeRnd> {
5032   let Predicates = [HasAVX512] in {
5033     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
5034              avx512_vcvt_fp_rc<opc, OpcodeStr, v16i32_info, v16f32_info,
5035                                 OpNodeRnd>, EVEX_V512;
5036   }
5037   let Predicates = [HasVLX] in {
5038     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
5039                                      EVEX_V128;
5040     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
5041                                      EVEX_V256;
5042   }
5043 }
5044
5045 // Convert Double to Signed/Unsigned Doubleword with truncation
5046 multiclass avx512_cvttpd2dq<bits<8> opc, string OpcodeStr,
5047                                   SDNode OpNode, SDNode OpNodeRnd> {
5048   let Predicates = [HasAVX512] in {
5049     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
5050              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i32x_info, v8f64_info,
5051                                 OpNodeRnd>, EVEX_V512;
5052   }
5053   let Predicates = [HasVLX] in {
5054     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
5055     // memory forms of these instructions in Asm Parcer. They have the same
5056     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
5057     // due to the same reason.
5058     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info, OpNode,
5059                                "{1to2}", "{x}">, EVEX_V128;
5060     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
5061                                "{1to4}", "{y}">, EVEX_V256;
5062   }
5063 }
5064
5065 // Convert Double to Signed/Unsigned Doubleword
5066 multiclass avx512_cvtpd2dq<bits<8> opc, string OpcodeStr,
5067                                   SDNode OpNode, SDNode OpNodeRnd> {
5068   let Predicates = [HasAVX512] in {
5069     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
5070              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i32x_info, v8f64_info,
5071                                OpNodeRnd>, EVEX_V512;
5072   }
5073   let Predicates = [HasVLX] in {
5074     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
5075     // memory forms of these instructions in Asm Parcer. They have the same
5076     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
5077     // due to the same reason.
5078     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info, OpNode,
5079                                "{1to2}", "{x}">, EVEX_V128;
5080     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
5081                                "{1to4}", "{y}">, EVEX_V256;
5082   }
5083 }
5084
5085 // Convert Double to Signed/Unsigned Quardword
5086 multiclass avx512_cvtpd2qq<bits<8> opc, string OpcodeStr,
5087                                   SDNode OpNode, SDNode OpNodeRnd> {
5088   let Predicates = [HasDQI] in {
5089     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
5090              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f64_info,
5091                                OpNodeRnd>, EVEX_V512;
5092   }
5093   let Predicates = [HasDQI, HasVLX] in {
5094     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
5095                                EVEX_V128;
5096     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
5097                                EVEX_V256;
5098   }
5099 }
5100
5101 // Convert Double to Signed/Unsigned Quardword with truncation
5102 multiclass avx512_cvttpd2qq<bits<8> opc, string OpcodeStr,
5103                                   SDNode OpNode, SDNode OpNodeRnd> {
5104   let Predicates = [HasDQI] in {
5105     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
5106              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f64_info,
5107                                OpNodeRnd>, EVEX_V512;
5108   }
5109   let Predicates = [HasDQI, HasVLX] in {
5110     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
5111                                EVEX_V128;
5112     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
5113                                EVEX_V256;
5114   }
5115 }
5116
5117 // Convert Signed/Unsigned Quardword to Double
5118 multiclass avx512_cvtqq2pd<bits<8> opc, string OpcodeStr,
5119                                   SDNode OpNode, SDNode OpNodeRnd> {
5120   let Predicates = [HasDQI] in {
5121     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i64_info, OpNode>,
5122              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f64_info, v8i64_info,
5123                                OpNodeRnd>, EVEX_V512;
5124   }
5125   let Predicates = [HasDQI, HasVLX] in {
5126     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v2i64x_info, OpNode>,
5127                                EVEX_V128;
5128     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i64x_info, OpNode>,
5129                                EVEX_V256;
5130   }
5131 }
5132
5133 // Convert Float to Signed/Unsigned Quardword
5134 multiclass avx512_cvtps2qq<bits<8> opc, string OpcodeStr,
5135                                   SDNode OpNode, SDNode OpNodeRnd> {
5136   let Predicates = [HasDQI] in {
5137     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
5138              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f32x_info,
5139                                OpNodeRnd>, EVEX_V512;
5140   }
5141   let Predicates = [HasDQI, HasVLX] in {
5142     // Explicitly specified broadcast string, since we take only 2 elements
5143     // from v4f32x_info source
5144     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode,
5145                                "{1to2}">, EVEX_V128;
5146     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
5147                                EVEX_V256;
5148   }
5149 }
5150
5151 // Convert Float to Signed/Unsigned Quardword with truncation
5152 multiclass avx512_cvttps2qq<bits<8> opc, string OpcodeStr,
5153                                   SDNode OpNode, SDNode OpNodeRnd> {
5154   let Predicates = [HasDQI] in {
5155     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
5156              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f32x_info,
5157                                OpNodeRnd>, EVEX_V512;
5158   }
5159   let Predicates = [HasDQI, HasVLX] in {
5160     // Explicitly specified broadcast string, since we take only 2 elements
5161     // from v4f32x_info source
5162     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode,
5163                                "{1to2}">, EVEX_V128;
5164     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
5165                                EVEX_V256;
5166   }
5167 }
5168
5169 // Convert Signed/Unsigned Quardword to Float
5170 multiclass avx512_cvtqq2ps<bits<8> opc, string OpcodeStr,
5171                                   SDNode OpNode, SDNode OpNodeRnd> {
5172   let Predicates = [HasDQI] in {
5173     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i64_info, OpNode>,
5174              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8i64_info,
5175                                OpNodeRnd>, EVEX_V512;
5176   }
5177   let Predicates = [HasDQI, HasVLX] in {
5178     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
5179     // memory forms of these instructions in Asm Parcer. They have the same
5180     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
5181     // due to the same reason.
5182     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2i64x_info, OpNode,
5183                                "{1to2}", "{x}">, EVEX_V128;
5184     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i64x_info, OpNode,
5185                                "{1to4}", "{y}">, EVEX_V256;
5186   }
5187 }
5188
5189 defm VCVTDQ2PD : avx512_cvtdq2pd<0xE6, "vcvtdq2pd", sint_to_fp, X86cvtdq2pd>, XS,
5190                                 EVEX_CD8<32, CD8VH>;
5191
5192 defm VCVTDQ2PS : avx512_cvtdq2ps<0x5B, "vcvtdq2ps", sint_to_fp,
5193                                 X86VSintToFpRnd>,
5194                                 PS, EVEX_CD8<32, CD8VF>;
5195
5196 defm VCVTTPS2DQ : avx512_cvttps2dq<0x5B, "vcvttps2dq", fp_to_sint,
5197                                 X86VFpToSintRnd>,
5198                                 XS, EVEX_CD8<32, CD8VF>;
5199
5200 defm VCVTTPD2DQ : avx512_cvttpd2dq<0xE6, "vcvttpd2dq", fp_to_sint,
5201                                  X86VFpToSintRnd>,
5202                                  PD, VEX_W, EVEX_CD8<64, CD8VF>;
5203
5204 defm VCVTTPS2UDQ : avx512_cvttps2dq<0x78, "vcvttps2udq", fp_to_uint,
5205                                  X86VFpToUintRnd>, PS,
5206                                  EVEX_CD8<32, CD8VF>;
5207
5208 defm VCVTTPD2UDQ : avx512_cvttpd2dq<0x78, "vcvttpd2udq", fp_to_uint,
5209                                  X86VFpToUintRnd>, PS, VEX_W,
5210                                  EVEX_CD8<64, CD8VF>;
5211
5212 defm VCVTUDQ2PD : avx512_cvtdq2pd<0x7A, "vcvtudq2pd", uint_to_fp, X86cvtudq2pd>,
5213                                  XS, EVEX_CD8<32, CD8VH>;
5214
5215 defm VCVTUDQ2PS : avx512_cvtdq2ps<0x7A, "vcvtudq2ps", uint_to_fp,
5216                                  X86VUintToFpRnd>, XD,
5217                                  EVEX_CD8<32, CD8VF>;
5218
5219 defm VCVTPS2DQ : avx512_cvtps2dq<0x5B, "vcvtps2dq", X86cvtps2Int,
5220                                  X86cvtps2IntRnd>, PD, EVEX_CD8<32, CD8VF>;
5221
5222 defm VCVTPD2DQ : avx512_cvtpd2dq<0xE6, "vcvtpd2dq", X86cvtpd2Int,
5223                                  X86cvtpd2IntRnd>, XD, VEX_W,
5224                                  EVEX_CD8<64, CD8VF>;
5225
5226 defm VCVTPS2UDQ : avx512_cvtps2dq<0x79, "vcvtps2udq", X86cvtps2UInt,
5227                                  X86cvtps2UIntRnd>,
5228                                  PS, EVEX_CD8<32, CD8VF>;
5229 defm VCVTPD2UDQ : avx512_cvtpd2dq<0x79, "vcvtpd2udq", X86cvtpd2UInt,
5230                                  X86cvtpd2UIntRnd>, VEX_W,
5231                                  PS, EVEX_CD8<64, CD8VF>;
5232
5233 defm VCVTPD2QQ : avx512_cvtpd2qq<0x7B, "vcvtpd2qq", X86cvtpd2Int,
5234                                  X86cvtpd2IntRnd>, VEX_W,
5235                                  PD, EVEX_CD8<64, CD8VF>;
5236
5237 defm VCVTPS2QQ : avx512_cvtps2qq<0x7B, "vcvtps2qq", X86cvtps2Int,
5238                                  X86cvtps2IntRnd>, PD, EVEX_CD8<32, CD8VH>;
5239
5240 defm VCVTPD2UQQ : avx512_cvtpd2qq<0x79, "vcvtpd2uqq", X86cvtpd2UInt,
5241                                  X86cvtpd2UIntRnd>, VEX_W,
5242                                  PD, EVEX_CD8<64, CD8VF>;
5243
5244 defm VCVTPS2UQQ : avx512_cvtps2qq<0x79, "vcvtps2uqq", X86cvtps2UInt,
5245                                  X86cvtps2UIntRnd>, PD, EVEX_CD8<32, CD8VH>;
5246
5247 defm VCVTTPD2QQ : avx512_cvttpd2qq<0x7A, "vcvttpd2qq", fp_to_sint,
5248                                  X86VFpToSlongRnd>, VEX_W,
5249                                  PD, EVEX_CD8<64, CD8VF>;
5250
5251 defm VCVTTPS2QQ : avx512_cvttps2qq<0x7A, "vcvttps2qq", fp_to_sint,
5252                                  X86VFpToSlongRnd>, PD, EVEX_CD8<32, CD8VH>;
5253
5254 defm VCVTTPD2UQQ : avx512_cvttpd2qq<0x78, "vcvttpd2uqq", fp_to_uint,
5255                                  X86VFpToUlongRnd>, VEX_W,
5256                                  PD, EVEX_CD8<64, CD8VF>;
5257
5258 defm VCVTTPS2UQQ : avx512_cvttps2qq<0x78, "vcvttps2uqq", fp_to_uint,
5259                                  X86VFpToUlongRnd>, PD, EVEX_CD8<32, CD8VH>;
5260
5261 defm VCVTQQ2PD : avx512_cvtqq2pd<0xE6, "vcvtqq2pd", sint_to_fp,
5262                             X86VSlongToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
5263
5264 defm VCVTUQQ2PD : avx512_cvtqq2pd<0x7A, "vcvtuqq2pd", uint_to_fp,
5265                             X86VUlongToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
5266
5267 defm VCVTQQ2PS : avx512_cvtqq2ps<0x5B, "vcvtqq2ps", sint_to_fp,
5268                             X86VSlongToFpRnd>, VEX_W, PS, EVEX_CD8<64, CD8VF>;
5269
5270 defm VCVTUQQ2PS : avx512_cvtqq2ps<0x7A, "vcvtuqq2ps", uint_to_fp,
5271                             X86VUlongToFpRnd>, VEX_W, XD, EVEX_CD8<64, CD8VF>;
5272
5273 let Predicates = [NoVLX] in {
5274 def : Pat<(v8i32 (fp_to_uint (v8f32 VR256X:$src1))),
5275           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
5276            (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
5277
5278 def : Pat<(v4i32 (fp_to_uint (v4f32 VR128X:$src1))),
5279           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
5280            (v16f32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_xmm)>;
5281
5282 def : Pat<(v8f32 (uint_to_fp (v8i32 VR256X:$src1))),
5283           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
5284            (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
5285
5286 def : Pat<(v4f32 (uint_to_fp (v4i32 VR128X:$src1))),
5287           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
5288            (v16i32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_xmm)>;
5289
5290 def : Pat<(v4f64 (uint_to_fp (v4i32 VR128X:$src1))),
5291           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
5292            (v8i32 (SUBREG_TO_REG (i32 0), VR128X:$src1, sub_xmm)))), sub_ymm)>;
5293 }
5294
5295 let Predicates = [HasAVX512] in {
5296   def : Pat<(v8f32 (fround (loadv8f64 addr:$src))),
5297             (VCVTPD2PSZrm addr:$src)>;
5298   def : Pat<(v8f64 (extloadv8f32 addr:$src)),
5299             (VCVTPS2PDZrm addr:$src)>;
5300 }
5301
5302 //===----------------------------------------------------------------------===//
5303 // Half precision conversion instructions
5304 //===----------------------------------------------------------------------===//
5305 multiclass avx512_cvtph2ps<RegisterClass destRC, RegisterClass srcRC,
5306                              X86MemOperand x86memop> {
5307   def rr : AVX5128I<0x13, MRMSrcReg, (outs destRC:$dst), (ins srcRC:$src),
5308              "vcvtph2ps\t{$src, $dst|$dst, $src}",
5309              []>, EVEX;
5310   let hasSideEffects = 0, mayLoad = 1 in
5311   def rm : AVX5128I<0x13, MRMSrcMem, (outs destRC:$dst), (ins x86memop:$src),
5312              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, EVEX;
5313 }
5314
5315 multiclass avx512_cvtps2ph<RegisterClass destRC, RegisterClass srcRC,
5316                              X86MemOperand x86memop> {
5317   def rr : AVX512AIi8<0x1D, MRMDestReg, (outs destRC:$dst),
5318                (ins srcRC:$src1, i32u8imm:$src2),
5319                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5320                []>, EVEX;
5321   let hasSideEffects = 0, mayStore = 1 in
5322   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
5323                (ins x86memop:$dst, srcRC:$src1, i32u8imm:$src2),
5324                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, EVEX;
5325 }
5326
5327 defm VCVTPH2PSZ : avx512_cvtph2ps<VR512, VR256X, f256mem>, EVEX_V512,
5328                                     EVEX_CD8<32, CD8VH>;
5329 defm VCVTPS2PHZ : avx512_cvtps2ph<VR256X, VR512, f256mem>, EVEX_V512,
5330                                     EVEX_CD8<32, CD8VH>;
5331
5332 def : Pat<(v16i16 (int_x86_avx512_mask_vcvtps2ph_512 (v16f32 VR512:$src),
5333            imm:$rc, (bc_v16i16(v8i32 immAllZerosV)), (i16 -1))),
5334            (VCVTPS2PHZrr VR512:$src, imm:$rc)>;
5335
5336 def : Pat<(v16f32 (int_x86_avx512_mask_vcvtph2ps_512 (v16i16 VR256X:$src),
5337            (bc_v16f32(v16i32 immAllZerosV)), (i16 -1), (i32 FROUND_CURRENT))),
5338            (VCVTPH2PSZrr VR256X:$src)>;
5339
5340 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
5341   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
5342                                  "ucomiss">, PS, EVEX, VEX_LIG,
5343                                  EVEX_CD8<32, CD8VT1>;
5344   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
5345                                   "ucomisd">, PD, EVEX,
5346                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5347   let Pattern = []<dag> in {
5348     defm VCOMISSZ  : sse12_ord_cmp<0x2F, FR32X, undef, f32, f32mem, loadf32,
5349                                    "comiss">, PS, EVEX, VEX_LIG,
5350                                    EVEX_CD8<32, CD8VT1>;
5351     defm VCOMISDZ  : sse12_ord_cmp<0x2F, FR64X, undef, f64, f64mem, loadf64,
5352                                    "comisd">, PD, EVEX,
5353                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5354   }
5355   let isCodeGenOnly = 1 in {
5356     defm Int_VUCOMISSZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v4f32, f128mem,
5357                               load, "ucomiss">, PS, EVEX, VEX_LIG,
5358                               EVEX_CD8<32, CD8VT1>;
5359     defm Int_VUCOMISDZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v2f64, f128mem,
5360                               load, "ucomisd">, PD, EVEX,
5361                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5362
5363     defm Int_VCOMISSZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v4f32, f128mem,
5364                               load, "comiss">, PS, EVEX, VEX_LIG,
5365                               EVEX_CD8<32, CD8VT1>;
5366     defm Int_VCOMISDZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v2f64, f128mem,
5367                               load, "comisd">, PD, EVEX,
5368                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5369   }
5370 }
5371
5372 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
5373 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
5374                             X86VectorVTInfo _> {
5375   let hasSideEffects = 0, AddedComplexity = 20 , Predicates = [HasAVX512] in {
5376   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5377                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5378                            "$src2, $src1", "$src1, $src2",
5379                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>, EVEX_4V;
5380   let mayLoad = 1 in {
5381   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5382                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5383                          "$src2, $src1", "$src1, $src2",
5384                          (OpNode (_.VT _.RC:$src1),
5385                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))))>, EVEX_4V;
5386   }
5387 }
5388 }
5389
5390 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", X86frcp14s, f32x_info>,
5391                   EVEX_CD8<32, CD8VT1>, T8PD;
5392 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", X86frcp14s, f64x_info>,
5393                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
5394 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", X86frsqrt14s, f32x_info>,
5395                   EVEX_CD8<32, CD8VT1>, T8PD;
5396 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", X86frsqrt14s, f64x_info>,
5397                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
5398
5399 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
5400 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
5401                          X86VectorVTInfo _> {
5402   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5403                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5404                          (_.FloatVT (OpNode _.RC:$src))>, EVEX, T8PD;
5405   let mayLoad = 1 in {
5406     defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5407                            (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5408                            (OpNode (_.FloatVT
5409                              (bitconvert (_.LdFrag addr:$src))))>, EVEX, T8PD;
5410     defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5411                             (ins _.ScalarMemOp:$src), OpcodeStr,
5412                             "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5413                             (OpNode (_.FloatVT
5414                               (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
5415                             EVEX, T8PD, EVEX_B;
5416   }
5417 }
5418
5419 multiclass avx512_fp14_p_vl_all<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5420   defm PSZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"), OpNode, v16f32_info>,
5421                           EVEX_V512, EVEX_CD8<32, CD8VF>;
5422   defm PDZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"), OpNode, v8f64_info>,
5423                           EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
5424
5425   // Define only if AVX512VL feature is present.
5426   let Predicates = [HasVLX] in {
5427     defm PSZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
5428                                 OpNode, v4f32x_info>,
5429                                EVEX_V128, EVEX_CD8<32, CD8VF>;
5430     defm PSZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
5431                                 OpNode, v8f32x_info>,
5432                                EVEX_V256, EVEX_CD8<32, CD8VF>;
5433     defm PDZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
5434                                 OpNode, v2f64x_info>,
5435                                EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
5436     defm PDZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
5437                                 OpNode, v4f64x_info>,
5438                                EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
5439   }
5440 }
5441
5442 defm VRSQRT14 : avx512_fp14_p_vl_all<0x4E, "vrsqrt14", X86frsqrt>;
5443 defm VRCP14 : avx512_fp14_p_vl_all<0x4C, "vrcp14", X86frcp>;
5444
5445 def : Pat <(v16f32 (int_x86_avx512_rsqrt14_ps_512 (v16f32 VR512:$src),
5446               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
5447            (VRSQRT14PSZr VR512:$src)>;
5448 def : Pat <(v8f64 (int_x86_avx512_rsqrt14_pd_512 (v8f64 VR512:$src),
5449               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
5450            (VRSQRT14PDZr VR512:$src)>;
5451
5452 def : Pat <(v16f32 (int_x86_avx512_rcp14_ps_512 (v16f32 VR512:$src),
5453               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
5454            (VRCP14PSZr VR512:$src)>;
5455 def : Pat <(v8f64 (int_x86_avx512_rcp14_pd_512 (v8f64 VR512:$src),
5456               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
5457            (VRCP14PDZr VR512:$src)>;
5458
5459 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
5460 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
5461                          SDNode OpNode> {
5462
5463   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5464                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5465                            "$src2, $src1", "$src1, $src2",
5466                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5467                            (i32 FROUND_CURRENT))>;
5468
5469   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5470                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5471                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
5472                             (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5473                             (i32 FROUND_NO_EXC))>, EVEX_B;
5474
5475   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5476                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5477                          "$src2, $src1", "$src1, $src2",
5478                          (OpNode (_.VT _.RC:$src1),
5479                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
5480                          (i32 FROUND_CURRENT))>;
5481 }
5482
5483 multiclass avx512_eri_s<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5484   defm SS : avx512_fp28_s<opc, OpcodeStr#"ss", f32x_info, OpNode>,
5485               EVEX_CD8<32, CD8VT1>;
5486   defm SD : avx512_fp28_s<opc, OpcodeStr#"sd", f64x_info, OpNode>,
5487               EVEX_CD8<64, CD8VT1>, VEX_W;
5488 }
5489
5490 let hasSideEffects = 0, Predicates = [HasERI] in {
5491   defm VRCP28   : avx512_eri_s<0xCB, "vrcp28",   X86rcp28s>,   T8PD, EVEX_4V;
5492   defm VRSQRT28 : avx512_eri_s<0xCD, "vrsqrt28", X86rsqrt28s>, T8PD, EVEX_4V;
5493 }
5494
5495 defm VGETEXP   : avx512_eri_s<0x43, "vgetexp", X86fgetexpRnds>, T8PD, EVEX_4V;
5496 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
5497
5498 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5499                          SDNode OpNode> {
5500
5501   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5502                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5503                          (OpNode (_.VT _.RC:$src), (i32 FROUND_CURRENT))>;
5504
5505   defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5506                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5507                          (OpNode (_.FloatVT
5508                              (bitconvert (_.LdFrag addr:$src))),
5509                           (i32 FROUND_CURRENT))>;
5510
5511   defm mb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5512                          (ins _.MemOp:$src), OpcodeStr,
5513                          "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5514                          (OpNode (_.FloatVT
5515                                   (X86VBroadcast (_.ScalarLdFrag addr:$src))),
5516                                  (i32 FROUND_CURRENT))>, EVEX_B;
5517 }
5518 multiclass avx512_fp28_p_round<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5519                          SDNode OpNode> {
5520   defm rb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5521                         (ins _.RC:$src), OpcodeStr,
5522                         "{sae}, $src", "$src, {sae}",
5523                         (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, EVEX_B;
5524 }
5525
5526 multiclass  avx512_eri<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5527    defm PS : avx512_fp28_p<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
5528              avx512_fp28_p_round<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
5529              T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
5530    defm PD : avx512_fp28_p<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
5531              avx512_fp28_p_round<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
5532              T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
5533 }
5534
5535 multiclass avx512_fp_unaryop_packed<bits<8> opc, string OpcodeStr,
5536                                   SDNode OpNode> {
5537   // Define only if AVX512VL feature is present.
5538   let Predicates = [HasVLX] in {
5539     defm PSZ128 : avx512_fp28_p<opc, OpcodeStr#"ps", v4f32x_info, OpNode>,
5540                                      EVEX_V128, T8PD, EVEX_CD8<32, CD8VF>;
5541     defm PSZ256 : avx512_fp28_p<opc, OpcodeStr#"ps", v8f32x_info, OpNode>,
5542                                      EVEX_V256, T8PD, EVEX_CD8<32, CD8VF>;
5543     defm PDZ128 : avx512_fp28_p<opc, OpcodeStr#"pd", v2f64x_info, OpNode>,
5544                                      EVEX_V128, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
5545     defm PDZ256 : avx512_fp28_p<opc, OpcodeStr#"pd", v4f64x_info, OpNode>,
5546                                      EVEX_V256, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
5547   }
5548 }
5549 let Predicates = [HasERI], hasSideEffects = 0 in {
5550
5551  defm VRSQRT28 : avx512_eri<0xCC, "vrsqrt28", X86rsqrt28>, EVEX;
5552  defm VRCP28   : avx512_eri<0xCA, "vrcp28",   X86rcp28>,   EVEX;
5553  defm VEXP2    : avx512_eri<0xC8, "vexp2",    X86exp2>,    EVEX;
5554 }
5555 defm VGETEXP   : avx512_eri<0x42, "vgetexp", X86fgetexpRnd>,
5556                  avx512_fp_unaryop_packed<0x42, "vgetexp", X86fgetexpRnd> , EVEX;
5557
5558 multiclass avx512_sqrt_packed_round<bits<8> opc, string OpcodeStr,
5559                               SDNode OpNodeRnd, X86VectorVTInfo _>{
5560   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5561                          (ins _.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc",
5562                          (_.VT (OpNodeRnd _.RC:$src, (i32 imm:$rc)))>,
5563                          EVEX, EVEX_B, EVEX_RC;
5564 }
5565
5566 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr,
5567                               SDNode OpNode, X86VectorVTInfo _>{
5568   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5569                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5570                          (_.FloatVT (OpNode _.RC:$src))>, EVEX;
5571   let mayLoad = 1 in {
5572     defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5573                            (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5574                            (OpNode (_.FloatVT
5575                              (bitconvert (_.LdFrag addr:$src))))>, EVEX;
5576
5577     defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5578                             (ins _.ScalarMemOp:$src), OpcodeStr,
5579                             "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5580                             (OpNode (_.FloatVT
5581                               (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
5582                             EVEX, EVEX_B;
5583   }
5584 }
5585
5586 multiclass avx512_sqrt_packed_all<bits<8> opc, string OpcodeStr,
5587                                   SDNode OpNode> {
5588   defm PSZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
5589                                 v16f32_info>,
5590                                 EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
5591   defm PDZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
5592                                 v8f64_info>,
5593                                 EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5594   // Define only if AVX512VL feature is present.
5595   let Predicates = [HasVLX] in {
5596     defm PSZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
5597                                      OpNode, v4f32x_info>,
5598                                      EVEX_V128, PS, EVEX_CD8<32, CD8VF>;
5599     defm PSZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
5600                                      OpNode, v8f32x_info>,
5601                                      EVEX_V256, PS, EVEX_CD8<32, CD8VF>;
5602     defm PDZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
5603                                      OpNode, v2f64x_info>,
5604                                      EVEX_V128, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5605     defm PDZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
5606                                      OpNode, v4f64x_info>,
5607                                      EVEX_V256, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5608   }
5609 }
5610
5611 multiclass avx512_sqrt_packed_all_round<bits<8> opc, string OpcodeStr,
5612                                           SDNode OpNodeRnd> {
5613   defm PSZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "ps"), OpNodeRnd,
5614                                 v16f32_info>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
5615   defm PDZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "pd"), OpNodeRnd,
5616                                 v8f64_info>, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5617 }
5618
5619 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
5620                               string SUFF, SDNode OpNode, SDNode OpNodeRnd> {
5621
5622   defm r_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5623                          (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5624                          "$src2, $src1", "$src1, $src2",
5625                          (OpNodeRnd (_.VT _.RC:$src1),
5626                                     (_.VT _.RC:$src2),
5627                                     (i32 FROUND_CURRENT))>;
5628   let mayLoad = 1 in
5629     defm m_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5630                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5631                          "$src2, $src1", "$src1, $src2",
5632                          (OpNodeRnd (_.VT _.RC:$src1),
5633                                     (_.VT (scalar_to_vector
5634                                               (_.ScalarLdFrag addr:$src2))),
5635                                     (i32 FROUND_CURRENT))>;
5636
5637   defm rb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5638                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
5639                          "$rc, $src2, $src1", "$src1, $src2, $rc",
5640                          (OpNodeRnd (_.VT _.RC:$src1),
5641                                      (_.VT _.RC:$src2),
5642                                      (i32 imm:$rc))>,
5643                          EVEX_B, EVEX_RC;
5644
5645   let isCodeGenOnly = 1 in {
5646     def r : SI<opc, MRMSrcReg, (outs _.FRC:$dst),
5647                (ins _.FRC:$src1, _.FRC:$src2),
5648                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
5649
5650     let mayLoad = 1 in
5651       def m : SI<opc, MRMSrcMem, (outs _.FRC:$dst),
5652                  (ins _.FRC:$src1, _.ScalarMemOp:$src2),
5653                  OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
5654   }
5655
5656   def : Pat<(_.EltVT (OpNode _.FRC:$src)),
5657             (!cast<Instruction>(NAME#SUFF#Zr)
5658                 (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>;
5659
5660   def : Pat<(_.EltVT (OpNode (load addr:$src))),
5661             (!cast<Instruction>(NAME#SUFF#Zm)
5662                 (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[OptForSize]>;
5663 }
5664
5665 multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
5666   defm SSZ : avx512_sqrt_scalar<opc, OpcodeStr#"ss", f32x_info, "SS", fsqrt,
5667                         X86fsqrtRnds>, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS;
5668   defm SDZ : avx512_sqrt_scalar<opc, OpcodeStr#"sd", f64x_info, "SD", fsqrt,
5669                         X86fsqrtRnds>, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W;
5670 }
5671
5672 defm VSQRT   : avx512_sqrt_packed_all<0x51, "vsqrt", fsqrt>,
5673                avx512_sqrt_packed_all_round<0x51, "vsqrt", X86fsqrtRnd>;
5674
5675 defm VSQRT   : avx512_sqrt_scalar_all<0x51, "vsqrt">, VEX_LIG;
5676
5677 let Predicates = [HasAVX512] in {
5678   def : Pat<(f32 (X86frsqrt FR32X:$src)),
5679             (COPY_TO_REGCLASS (VRSQRT14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>;
5680   def : Pat<(f32 (X86frsqrt (load addr:$src))),
5681             (COPY_TO_REGCLASS (VRSQRT14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
5682             Requires<[OptForSize]>;
5683   def : Pat<(f32 (X86frcp FR32X:$src)),
5684             (COPY_TO_REGCLASS (VRCP14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X )>;
5685   def : Pat<(f32 (X86frcp (load addr:$src))),
5686             (COPY_TO_REGCLASS (VRCP14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
5687             Requires<[OptForSize]>;
5688 }
5689
5690 multiclass
5691 avx512_rndscale_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
5692
5693   let ExeDomain = _.ExeDomain in {
5694   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5695                            (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
5696                            "$src3, $src2, $src1", "$src1, $src2, $src3",
5697                            (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5698                             (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
5699
5700   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5701                          (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
5702                          "$src3, {sae}, $src2, $src1", "$src1, $src2, {sae}, $src3",
5703                          (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5704                          (i32 imm:$src3), (i32 FROUND_NO_EXC)))>, EVEX_B;
5705
5706   let mayLoad = 1 in
5707   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5708                          (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3), OpcodeStr,
5709                          "$src3, $src2, $src1", "$src1, $src2, $src3",
5710                          (_.VT (X86RndScales (_.VT _.RC:$src1),
5711                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
5712                           (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
5713   }
5714   let Predicates = [HasAVX512] in {
5715   def : Pat<(ffloor _.FRC:$src), (COPY_TO_REGCLASS
5716              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5717              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x1))), _.FRC)>;
5718   def : Pat<(fceil _.FRC:$src), (COPY_TO_REGCLASS
5719              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5720              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x2))), _.FRC)>;
5721   def : Pat<(ftrunc _.FRC:$src), (COPY_TO_REGCLASS
5722              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5723              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x3))), _.FRC)>;
5724   def : Pat<(frint _.FRC:$src), (COPY_TO_REGCLASS
5725              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5726              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x4))), _.FRC)>;
5727   def : Pat<(fnearbyint _.FRC:$src), (COPY_TO_REGCLASS
5728              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5729              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0xc))), _.FRC)>;
5730
5731   def : Pat<(ffloor (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5732              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5733              addr:$src, (i32 0x1))), _.FRC)>;
5734   def : Pat<(fceil (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5735              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5736              addr:$src, (i32 0x2))), _.FRC)>;
5737   def : Pat<(ftrunc (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5738              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5739              addr:$src, (i32 0x3))), _.FRC)>;
5740   def : Pat<(frint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5741              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5742              addr:$src, (i32 0x4))), _.FRC)>;
5743   def : Pat<(fnearbyint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5744              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5745              addr:$src, (i32 0xc))), _.FRC)>;
5746   }
5747 }
5748
5749 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", f32x_info>,
5750                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VT1>;
5751
5752 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", f64x_info>, VEX_W,
5753                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VT1>;
5754
5755 //-------------------------------------------------
5756 // Integer truncate and extend operations
5757 //-------------------------------------------------
5758
5759 multiclass avx512_trunc_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5760                               X86VectorVTInfo SrcInfo, X86VectorVTInfo DestInfo,
5761                               X86MemOperand x86memop> {
5762
5763   defm rr  : AVX512_maskable<opc, MRMDestReg, DestInfo, (outs DestInfo.RC:$dst),
5764                       (ins SrcInfo.RC:$src1), OpcodeStr ,"$src1", "$src1",
5765                       (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1)))>,
5766                        EVEX, T8XS;
5767
5768   // for intrinsic patter match
5769   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5770                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5771                            undef)),
5772             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
5773                                       SrcInfo.RC:$src1)>;
5774
5775   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5776                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5777                            DestInfo.ImmAllZerosV)),
5778             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
5779                                       SrcInfo.RC:$src1)>;
5780
5781   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5782                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5783                            DestInfo.RC:$src0)),
5784             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrk) DestInfo.RC:$src0,
5785                                       DestInfo.KRCWM:$mask ,
5786                                       SrcInfo.RC:$src1)>;
5787
5788   let mayStore = 1 in {
5789     def mr : AVX512XS8I<opc, MRMDestMem, (outs),
5790                (ins x86memop:$dst, SrcInfo.RC:$src),
5791                OpcodeStr # "\t{$src, $dst |$dst, $src}",
5792                []>, EVEX;
5793
5794     def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
5795                (ins x86memop:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src),
5796                OpcodeStr # "\t{$src, $dst {${mask}} |$dst {${mask}}, $src}",
5797                []>, EVEX, EVEX_K;
5798   }//mayStore = 1
5799 }
5800
5801 multiclass avx512_trunc_mr_lowering<X86VectorVTInfo SrcInfo,
5802                                     X86VectorVTInfo DestInfo,
5803                                     PatFrag truncFrag, PatFrag mtruncFrag > {
5804
5805   def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst),
5806             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr)
5807                                     addr:$dst, SrcInfo.RC:$src)>;
5808
5809   def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask,
5810                                                (SrcInfo.VT SrcInfo.RC:$src)),
5811             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk)
5812                             addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>;
5813 }
5814
5815 multiclass avx512_trunc_sat_mr_lowering<X86VectorVTInfo SrcInfo,
5816                                         X86VectorVTInfo DestInfo, string sat > {
5817
5818   def: Pat<(!cast<Intrinsic>("int_x86_avx512_mask_pmov"#sat#"_"#SrcInfo.Suffix#
5819                                DestInfo.Suffix#"_mem_"#SrcInfo.Size)
5820                   addr:$ptr, (SrcInfo.VT SrcInfo.RC:$src), SrcInfo.MRC:$mask),
5821            (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk) addr:$ptr,
5822                     (COPY_TO_REGCLASS SrcInfo.MRC:$mask, SrcInfo.KRCWM),
5823                     (SrcInfo.VT SrcInfo.RC:$src))>;
5824
5825   def: Pat<(!cast<Intrinsic>("int_x86_avx512_mask_pmov"#sat#"_"#SrcInfo.Suffix#
5826                                DestInfo.Suffix#"_mem_"#SrcInfo.Size)
5827                   addr:$ptr, (SrcInfo.VT SrcInfo.RC:$src), -1),
5828            (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr) addr:$ptr,
5829                     (SrcInfo.VT SrcInfo.RC:$src))>;
5830 }
5831
5832 multiclass avx512_trunc<bits<8> opc, string OpcodeStr, SDNode OpNode,
5833          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
5834          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
5835          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
5836          X86MemOperand x86memopZ, PatFrag truncFrag, PatFrag mtruncFrag,
5837                                                      Predicate prd = HasAVX512>{
5838
5839   let Predicates = [HasVLX, prd] in {
5840     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
5841                              DestInfoZ128, x86memopZ128>,
5842                 avx512_trunc_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
5843                              truncFrag, mtruncFrag>, EVEX_V128;
5844
5845     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
5846                              DestInfoZ256, x86memopZ256>,
5847                 avx512_trunc_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
5848                              truncFrag, mtruncFrag>, EVEX_V256;
5849   }
5850   let Predicates = [prd] in
5851     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
5852                              DestInfoZ, x86memopZ>,
5853                 avx512_trunc_mr_lowering<VTSrcInfo.info512, DestInfoZ,
5854                              truncFrag, mtruncFrag>, EVEX_V512;
5855 }
5856
5857 multiclass avx512_trunc_sat<bits<8> opc, string OpcodeStr, SDNode OpNode,
5858          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
5859          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
5860          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
5861          X86MemOperand x86memopZ, string sat, Predicate prd = HasAVX512>{
5862
5863   let Predicates = [HasVLX, prd] in {
5864     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
5865                              DestInfoZ128, x86memopZ128>,
5866                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
5867                              sat>, EVEX_V128;
5868
5869     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
5870                              DestInfoZ256, x86memopZ256>,
5871                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
5872                              sat>, EVEX_V256;
5873   }
5874   let Predicates = [prd] in
5875     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
5876                              DestInfoZ, x86memopZ>,
5877                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info512, DestInfoZ,
5878                              sat>, EVEX_V512;
5879 }
5880
5881 multiclass avx512_trunc_qb<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5882   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5883                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
5884                truncstorevi8, masked_truncstorevi8>, EVEX_CD8<8, CD8VO>;
5885 }
5886 multiclass avx512_trunc_sat_qb<bits<8> opc, string sat, SDNode OpNode> {
5887   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qb", OpNode, avx512vl_i64_info,
5888                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
5889                sat>, EVEX_CD8<8, CD8VO>;
5890 }
5891
5892 multiclass avx512_trunc_qw<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5893   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5894                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
5895                truncstorevi16, masked_truncstorevi16>, EVEX_CD8<16, CD8VQ>;
5896 }
5897 multiclass avx512_trunc_sat_qw<bits<8> opc, string sat, SDNode OpNode> {
5898   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qw", OpNode, avx512vl_i64_info,
5899                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
5900                sat>, EVEX_CD8<16, CD8VQ>;
5901 }
5902
5903 multiclass avx512_trunc_qd<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5904   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5905                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
5906                truncstorevi32, masked_truncstorevi32>, EVEX_CD8<32, CD8VH>;
5907 }
5908 multiclass avx512_trunc_sat_qd<bits<8> opc, string sat, SDNode OpNode> {
5909   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qd", OpNode, avx512vl_i64_info,
5910                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
5911                sat>, EVEX_CD8<32, CD8VH>;
5912 }
5913
5914 multiclass avx512_trunc_db<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5915   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
5916                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
5917                truncstorevi8, masked_truncstorevi8>, EVEX_CD8<8, CD8VQ>;
5918 }
5919 multiclass avx512_trunc_sat_db<bits<8> opc, string sat, SDNode OpNode> {
5920   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"db", OpNode, avx512vl_i32_info,
5921                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
5922                sat>, EVEX_CD8<8, CD8VQ>;
5923 }
5924
5925 multiclass avx512_trunc_dw<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5926   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
5927               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
5928               truncstorevi16, masked_truncstorevi16>, EVEX_CD8<16, CD8VH>;
5929 }
5930 multiclass avx512_trunc_sat_dw<bits<8> opc, string sat, SDNode OpNode> {
5931   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"dw", OpNode, avx512vl_i32_info,
5932               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
5933               sat>, EVEX_CD8<16, CD8VH>;
5934 }
5935
5936 multiclass avx512_trunc_wb<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5937   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i16_info,
5938               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
5939               truncstorevi8, masked_truncstorevi8,HasBWI>, EVEX_CD8<16, CD8VH>;
5940 }
5941 multiclass avx512_trunc_sat_wb<bits<8> opc, string sat, SDNode OpNode> {
5942   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"wb", OpNode, avx512vl_i16_info,
5943               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
5944               sat, HasBWI>, EVEX_CD8<16, CD8VH>;
5945 }
5946
5947 defm VPMOVQB    : avx512_trunc_qb<0x32, "vpmovqb", X86vtrunc>;
5948 defm VPMOVSQB   : avx512_trunc_sat_qb<0x22, "s",   X86vtruncs>;
5949 defm VPMOVUSQB  : avx512_trunc_sat_qb<0x12, "us",  X86vtruncus>;
5950
5951 defm VPMOVQW    : avx512_trunc_qw<0x34, "vpmovqw", X86vtrunc>;
5952 defm VPMOVSQW   : avx512_trunc_sat_qw<0x24, "s",   X86vtruncs>;
5953 defm VPMOVUSQW  : avx512_trunc_sat_qw<0x14, "us",  X86vtruncus>;
5954
5955 defm VPMOVQD    : avx512_trunc_qd<0x35, "vpmovqd", X86vtrunc>;
5956 defm VPMOVSQD   : avx512_trunc_sat_qd<0x25, "s",   X86vtruncs>;
5957 defm VPMOVUSQD  : avx512_trunc_sat_qd<0x15, "us",  X86vtruncus>;
5958
5959 defm VPMOVDB    : avx512_trunc_db<0x31, "vpmovdb", X86vtrunc>;
5960 defm VPMOVSDB   : avx512_trunc_sat_db<0x21, "s",   X86vtruncs>;
5961 defm VPMOVUSDB  : avx512_trunc_sat_db<0x11, "us",  X86vtruncus>;
5962
5963 defm VPMOVDW    : avx512_trunc_dw<0x33, "vpmovdw", X86vtrunc>;
5964 defm VPMOVSDW   : avx512_trunc_sat_dw<0x23, "s",   X86vtruncs>;
5965 defm VPMOVUSDW  : avx512_trunc_sat_dw<0x13, "us",  X86vtruncus>;
5966
5967 defm VPMOVWB    : avx512_trunc_wb<0x30, "vpmovwb", X86vtrunc>;
5968 defm VPMOVSWB   : avx512_trunc_sat_wb<0x20, "s",   X86vtruncs>;
5969 defm VPMOVUSWB  : avx512_trunc_sat_wb<0x10, "us",  X86vtruncus>;
5970
5971 multiclass avx512_extend_common<bits<8> opc, string OpcodeStr,
5972                   X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo,
5973                   X86MemOperand x86memop, PatFrag LdFrag, SDNode OpNode>{
5974
5975   defm rr   : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
5976                     (ins SrcInfo.RC:$src), OpcodeStr ,"$src", "$src",
5977                     (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src)))>,
5978                   EVEX;
5979
5980   let mayLoad = 1 in {
5981     defm rm : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
5982                     (ins x86memop:$src), OpcodeStr ,"$src", "$src",
5983                     (DestInfo.VT (LdFrag addr:$src))>,
5984                   EVEX;
5985   }
5986 }
5987
5988 multiclass avx512_extend_BW<bits<8> opc, string OpcodeStr, SDNode OpNode,
5989           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
5990   let Predicates = [HasVLX, HasBWI] in {
5991     defm Z128:  avx512_extend_common<opc, OpcodeStr, v8i16x_info,
5992                     v16i8x_info, i64mem, LdFrag, OpNode>,
5993                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V128;
5994
5995     defm Z256:  avx512_extend_common<opc, OpcodeStr, v16i16x_info,
5996                     v16i8x_info, i128mem, LdFrag, OpNode>,
5997                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V256;
5998   }
5999   let Predicates = [HasBWI] in {
6000     defm Z   :  avx512_extend_common<opc, OpcodeStr, v32i16_info,
6001                     v32i8x_info, i256mem, LdFrag, OpNode>,
6002                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V512;
6003   }
6004 }
6005
6006 multiclass avx512_extend_BD<bits<8> opc, string OpcodeStr, SDNode OpNode,
6007           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
6008   let Predicates = [HasVLX, HasAVX512] in {
6009     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
6010                    v16i8x_info, i32mem, LdFrag, OpNode>,
6011                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V128;
6012
6013     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
6014                    v16i8x_info, i64mem, LdFrag, OpNode>,
6015                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V256;
6016   }
6017   let Predicates = [HasAVX512] in {
6018     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
6019                    v16i8x_info, i128mem, LdFrag, OpNode>,
6020                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V512;
6021   }
6022 }
6023
6024 multiclass avx512_extend_BQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6025           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
6026   let Predicates = [HasVLX, HasAVX512] in {
6027     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6028                    v16i8x_info, i16mem, LdFrag, OpNode>,
6029                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V128;
6030
6031     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6032                    v16i8x_info, i32mem, LdFrag, OpNode>,
6033                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V256;
6034   }
6035   let Predicates = [HasAVX512] in {
6036     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6037                    v16i8x_info, i64mem, LdFrag, OpNode>,
6038                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V512;
6039   }
6040 }
6041
6042 multiclass avx512_extend_WD<bits<8> opc, string OpcodeStr, SDNode OpNode,
6043          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
6044   let Predicates = [HasVLX, HasAVX512] in {
6045     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
6046                    v8i16x_info, i64mem, LdFrag, OpNode>,
6047                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V128;
6048
6049     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
6050                    v8i16x_info, i128mem, LdFrag, OpNode>,
6051                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V256;
6052   }
6053   let Predicates = [HasAVX512] in {
6054     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
6055                    v16i16x_info, i256mem, LdFrag, OpNode>,
6056                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V512;
6057   }
6058 }
6059
6060 multiclass avx512_extend_WQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6061          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
6062   let Predicates = [HasVLX, HasAVX512] in {
6063     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6064                    v8i16x_info, i32mem, LdFrag, OpNode>,
6065                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V128;
6066
6067     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6068                    v8i16x_info, i64mem, LdFrag, OpNode>,
6069                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V256;
6070   }
6071   let Predicates = [HasAVX512] in {
6072     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6073                    v8i16x_info, i128mem, LdFrag, OpNode>,
6074                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V512;
6075   }
6076 }
6077
6078 multiclass avx512_extend_DQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6079          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi32")> {
6080
6081   let Predicates = [HasVLX, HasAVX512] in {
6082     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6083                    v4i32x_info, i64mem, LdFrag, OpNode>,
6084                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V128;
6085
6086     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6087                    v4i32x_info, i128mem, LdFrag, OpNode>,
6088                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V256;
6089   }
6090   let Predicates = [HasAVX512] in {
6091     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6092                    v8i32x_info, i256mem, LdFrag, OpNode>,
6093                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V512;
6094   }
6095 }
6096
6097 defm VPMOVZXBW : avx512_extend_BW<0x30, "vpmovzxbw", X86vzext, "z">;
6098 defm VPMOVZXBD : avx512_extend_BD<0x31, "vpmovzxbd", X86vzext, "z">;
6099 defm VPMOVZXBQ : avx512_extend_BQ<0x32, "vpmovzxbq", X86vzext, "z">;
6100 defm VPMOVZXWD : avx512_extend_WD<0x33, "vpmovzxwd", X86vzext, "z">;
6101 defm VPMOVZXWQ : avx512_extend_WQ<0x34, "vpmovzxwq", X86vzext, "z">;
6102 defm VPMOVZXDQ : avx512_extend_DQ<0x35, "vpmovzxdq", X86vzext, "z">;
6103
6104
6105 defm VPMOVSXBW: avx512_extend_BW<0x20, "vpmovsxbw", X86vsext, "s">;
6106 defm VPMOVSXBD: avx512_extend_BD<0x21, "vpmovsxbd", X86vsext, "s">;
6107 defm VPMOVSXBQ: avx512_extend_BQ<0x22, "vpmovsxbq", X86vsext, "s">;
6108 defm VPMOVSXWD: avx512_extend_WD<0x23, "vpmovsxwd", X86vsext, "s">;
6109 defm VPMOVSXWQ: avx512_extend_WQ<0x24, "vpmovsxwq", X86vsext, "s">;
6110 defm VPMOVSXDQ: avx512_extend_DQ<0x25, "vpmovsxdq", X86vsext, "s">;
6111
6112 //===----------------------------------------------------------------------===//
6113 // GATHER - SCATTER Operations
6114
6115 multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6116                          X86MemOperand memop, PatFrag GatherNode> {
6117   let Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb",
6118       ExeDomain = _.ExeDomain in
6119   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),
6120             (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),
6121             !strconcat(OpcodeStr#_.Suffix,
6122             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
6123             [(set _.RC:$dst, _.KRCWM:$mask_wb,
6124               (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,
6125                      vectoraddr:$src2))]>, EVEX, EVEX_K,
6126              EVEX_CD8<_.EltSize, CD8VT1>;
6127 }
6128
6129 multiclass avx512_gather_q_pd<bits<8> dopc, bits<8> qopc,
6130                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6131   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512,
6132                                       vy32xmem, mgatherv8i32>, EVEX_V512, VEX_W;
6133   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info512,
6134                                       vz64mem,  mgatherv8i64>, EVEX_V512, VEX_W;
6135 let Predicates = [HasVLX] in {
6136   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
6137                               vx32xmem, mgatherv4i32>, EVEX_V256, VEX_W;
6138   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info256,
6139                               vy64xmem, mgatherv4i64>, EVEX_V256, VEX_W;
6140   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
6141                               vx32xmem, mgatherv4i32>, EVEX_V128, VEX_W;
6142   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6143                               vx64xmem, mgatherv2i64>, EVEX_V128, VEX_W;
6144 }
6145 }
6146
6147 multiclass avx512_gather_d_ps<bits<8> dopc, bits<8> qopc,
6148                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6149   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512, vz32mem,
6150                                        mgatherv16i32>, EVEX_V512;
6151   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info256, vz64mem,
6152                                        mgatherv8i64>, EVEX_V512;
6153 let Predicates = [HasVLX] in {
6154   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
6155                                           vy32xmem, mgatherv8i32>, EVEX_V256;
6156   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6157                                           vy64xmem, mgatherv4i64>, EVEX_V256;
6158   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
6159                                           vx32xmem, mgatherv4i32>, EVEX_V128;
6160   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6161                                           vx64xmem, mgatherv2i64>, EVEX_V128;
6162 }
6163 }
6164
6165
6166 defm VGATHER : avx512_gather_q_pd<0x92, 0x93, avx512vl_f64_info, "vgather", "PD">,
6167                avx512_gather_d_ps<0x92, 0x93, avx512vl_f32_info, "vgather", "PS">;
6168
6169 defm VPGATHER : avx512_gather_q_pd<0x90, 0x91, avx512vl_i64_info, "vpgather", "Q">,
6170                 avx512_gather_d_ps<0x90, 0x91, avx512vl_i32_info, "vpgather", "D">;
6171
6172 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6173                           X86MemOperand memop, PatFrag ScatterNode> {
6174
6175 let mayStore = 1, Constraints = "$mask = $mask_wb", ExeDomain = _.ExeDomain in
6176
6177   def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),
6178             (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),
6179             !strconcat(OpcodeStr#_.Suffix,
6180             "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
6181             [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),
6182                                      _.KRCWM:$mask,  vectoraddr:$dst))]>,
6183             EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
6184 }
6185
6186 multiclass avx512_scatter_q_pd<bits<8> dopc, bits<8> qopc,
6187                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6188   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512,
6189                                       vy32xmem, mscatterv8i32>, EVEX_V512, VEX_W;
6190   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info512,
6191                                       vz64mem,  mscatterv8i64>, EVEX_V512, VEX_W;
6192 let Predicates = [HasVLX] in {
6193   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
6194                               vx32xmem, mscatterv4i32>, EVEX_V256, VEX_W;
6195   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info256,
6196                               vy64xmem, mscatterv4i64>, EVEX_V256, VEX_W;
6197   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
6198                               vx32xmem, mscatterv4i32>, EVEX_V128, VEX_W;
6199   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6200                               vx64xmem, mscatterv2i64>, EVEX_V128, VEX_W;
6201 }
6202 }
6203
6204 multiclass avx512_scatter_d_ps<bits<8> dopc, bits<8> qopc,
6205                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6206   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512, vz32mem,
6207                                        mscatterv16i32>, EVEX_V512;
6208   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info256, vz64mem,
6209                                        mscatterv8i64>, EVEX_V512;
6210 let Predicates = [HasVLX] in {
6211   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
6212                                           vy32xmem, mscatterv8i32>, EVEX_V256;
6213   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6214                                           vy64xmem, mscatterv4i64>, EVEX_V256;
6215   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
6216                                           vx32xmem, mscatterv4i32>, EVEX_V128;
6217   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6218                                           vx64xmem, mscatterv2i64>, EVEX_V128;
6219 }
6220 }
6221
6222 defm VSCATTER : avx512_scatter_q_pd<0xA2, 0xA3, avx512vl_f64_info, "vscatter", "PD">,
6223                avx512_scatter_d_ps<0xA2, 0xA3, avx512vl_f32_info, "vscatter", "PS">;
6224
6225 defm VPSCATTER : avx512_scatter_q_pd<0xA0, 0xA1, avx512vl_i64_info, "vpscatter", "Q">,
6226                 avx512_scatter_d_ps<0xA0, 0xA1, avx512vl_i32_info, "vpscatter", "D">;
6227
6228 // prefetch
6229 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
6230                        RegisterClass KRC, X86MemOperand memop> {
6231   let Predicates = [HasPFI], hasSideEffects = 1 in
6232   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
6233             !strconcat(OpcodeStr, "\t{$src {${mask}}|{${mask}}, $src}"),
6234             []>, EVEX, EVEX_K;
6235 }
6236
6237 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
6238                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6239
6240 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
6241                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6242
6243 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
6244                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6245
6246 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
6247                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6248
6249 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
6250                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6251
6252 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
6253                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6254
6255 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
6256                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6257
6258 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
6259                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6260
6261 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
6262                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6263
6264 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
6265                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6266
6267 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
6268                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6269
6270 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
6271                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6272
6273 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
6274                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6275
6276 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
6277                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6278
6279 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
6280                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6281
6282 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
6283                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6284
6285 // Helper fragments to match sext vXi1 to vXiY.
6286 def v16i1sextv16i32  : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
6287 def v8i1sextv8i64  : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
6288
6289 def : Pat<(store (i1 -1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
6290 def : Pat<(store (i1  1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
6291 def : Pat<(store (i1  0), addr:$dst), (MOV8mi addr:$dst, (i8 0))>;
6292
6293 def : Pat<(store VK1:$src, addr:$dst),
6294           (MOV8mr addr:$dst,
6295            (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)),
6296             sub_8bit))>, Requires<[HasAVX512, NoDQI]>;
6297
6298 def : Pat<(store VK8:$src, addr:$dst),
6299           (MOV8mr addr:$dst,
6300            (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
6301             sub_8bit))>, Requires<[HasAVX512, NoDQI]>;
6302
6303 def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
6304                            (truncstore node:$val, node:$ptr), [{
6305   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
6306 }]>;
6307
6308 def : Pat<(truncstorei1 GR8:$src, addr:$dst),
6309           (MOV8mr addr:$dst, GR8:$src)>;
6310
6311 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
6312 def rr : AVX512XS8I<opc, MRMSrcReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
6313                   !strconcat(OpcodeStr##Vec.Suffix, "\t{$src, $dst|$dst, $src}"),
6314                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
6315 }
6316
6317 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
6318                                  string OpcodeStr, Predicate prd> {
6319 let Predicates = [prd] in
6320   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6321
6322   let Predicates = [prd, HasVLX] in {
6323     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6324     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6325   }
6326 }
6327
6328 multiclass avx512_convert_mask_to_vector<string OpcodeStr> {
6329   defm NAME##B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info,  OpcodeStr,
6330                                        HasBWI>;
6331   defm NAME##W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, OpcodeStr,
6332                                        HasBWI>, VEX_W;
6333   defm NAME##D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, OpcodeStr,
6334                                        HasDQI>;
6335   defm NAME##Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, OpcodeStr,
6336                                        HasDQI>, VEX_W;
6337 }
6338
6339 defm VPMOVM2 : avx512_convert_mask_to_vector<"vpmovm2">;
6340
6341 multiclass convert_vector_to_mask_common<bits<8> opc, X86VectorVTInfo _, string OpcodeStr > {
6342 def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.KRC:$dst), (ins _.RC:$src),
6343                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6344                   [(set _.KRC:$dst, (trunc (_.VT _.RC:$src)))]>, EVEX;
6345 }
6346
6347 multiclass avx512_convert_vector_to_mask<bits<8> opc, string OpcodeStr,
6348                         AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6349 let Predicates = [prd] in
6350   defm Z : convert_vector_to_mask_common <opc, VTInfo.info512, OpcodeStr>,
6351    EVEX_V512;
6352
6353   let Predicates = [prd, HasVLX] in {
6354     defm Z256 : convert_vector_to_mask_common<opc, VTInfo.info256, OpcodeStr>,
6355      EVEX_V256;
6356     defm Z128 : convert_vector_to_mask_common<opc, VTInfo.info128, OpcodeStr>,
6357      EVEX_V128;
6358   }
6359 }
6360
6361 defm VPMOVB2M : avx512_convert_vector_to_mask<0x29, "vpmovb2m",
6362                                               avx512vl_i8_info, HasBWI>;
6363 defm VPMOVW2M : avx512_convert_vector_to_mask<0x29, "vpmovw2m",
6364                                               avx512vl_i16_info, HasBWI>, VEX_W;
6365 defm VPMOVD2M : avx512_convert_vector_to_mask<0x39, "vpmovd2m",
6366                                               avx512vl_i32_info, HasDQI>;
6367 defm VPMOVQ2M : avx512_convert_vector_to_mask<0x39, "vpmovq2m",
6368                                               avx512vl_i64_info, HasDQI>, VEX_W;
6369
6370 //===----------------------------------------------------------------------===//
6371 // AVX-512 - COMPRESS and EXPAND
6372 //
6373
6374 multiclass compress_by_vec_width<bits<8> opc, X86VectorVTInfo _,
6375                                  string OpcodeStr> {
6376   defm rr : AVX512_maskable<opc, MRMDestReg, _, (outs _.RC:$dst),
6377               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
6378               (_.VT (X86compress _.RC:$src1))>, AVX5128IBase;
6379
6380   let mayStore = 1 in {
6381   def mr : AVX5128I<opc, MRMDestMem, (outs),
6382               (ins _.MemOp:$dst, _.RC:$src),
6383               OpcodeStr # "\t{$src, $dst |$dst, $src}",
6384               []>, EVEX_CD8<_.EltSize, CD8VT1>;
6385
6386   def mrk : AVX5128I<opc, MRMDestMem, (outs),
6387               (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
6388               OpcodeStr # "\t{$src, $dst {${mask}} |$dst {${mask}}, $src}",
6389               [(store (_.VT (vselect _.KRCWM:$mask,
6390                              (_.VT (X86compress  _.RC:$src)), _.ImmAllZerosV)),
6391                 addr:$dst)]>,
6392               EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
6393   }
6394 }
6395
6396 multiclass compress_by_elt_width<bits<8> opc, string OpcodeStr,
6397                                  AVX512VLVectorVTInfo VTInfo> {
6398   defm Z : compress_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6399
6400   let Predicates = [HasVLX] in {
6401     defm Z256 : compress_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6402     defm Z128 : compress_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6403   }
6404 }
6405
6406 defm VPCOMPRESSD : compress_by_elt_width <0x8B, "vpcompressd", avx512vl_i32_info>,
6407                                          EVEX;
6408 defm VPCOMPRESSQ : compress_by_elt_width <0x8B, "vpcompressq", avx512vl_i64_info>,
6409                                          EVEX, VEX_W;
6410 defm VCOMPRESSPS : compress_by_elt_width <0x8A, "vcompressps", avx512vl_f32_info>,
6411                                          EVEX;
6412 defm VCOMPRESSPD : compress_by_elt_width <0x8A, "vcompresspd", avx512vl_f64_info>,
6413                                          EVEX, VEX_W;
6414
6415 // expand
6416 multiclass expand_by_vec_width<bits<8> opc, X86VectorVTInfo _,
6417                                  string OpcodeStr> {
6418   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6419               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
6420               (_.VT (X86expand _.RC:$src1))>, AVX5128IBase;
6421
6422   let mayLoad = 1 in
6423   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6424               (ins _.MemOp:$src1), OpcodeStr, "$src1", "$src1",
6425               (_.VT (X86expand (_.VT (bitconvert
6426                                       (_.LdFrag addr:$src1)))))>,
6427             AVX5128IBase, EVEX_CD8<_.EltSize, CD8VT1>;
6428 }
6429
6430 multiclass expand_by_elt_width<bits<8> opc, string OpcodeStr,
6431                                  AVX512VLVectorVTInfo VTInfo> {
6432   defm Z : expand_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6433
6434   let Predicates = [HasVLX] in {
6435     defm Z256 : expand_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6436     defm Z128 : expand_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6437   }
6438 }
6439
6440 defm VPEXPANDD : expand_by_elt_width <0x89, "vpexpandd", avx512vl_i32_info>,
6441                                          EVEX;
6442 defm VPEXPANDQ : expand_by_elt_width <0x89, "vpexpandq", avx512vl_i64_info>,
6443                                          EVEX, VEX_W;
6444 defm VEXPANDPS : expand_by_elt_width <0x88, "vexpandps", avx512vl_f32_info>,
6445                                          EVEX;
6446 defm VEXPANDPD : expand_by_elt_width <0x88, "vexpandpd", avx512vl_f64_info>,
6447                                          EVEX, VEX_W;
6448
6449 //handle instruction  reg_vec1 = op(reg_vec,imm)
6450 //                               op(mem_vec,imm)
6451 //                               op(broadcast(eltVt),imm)
6452 //all instruction created with FROUND_CURRENT
6453 multiclass avx512_unary_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6454                                                             X86VectorVTInfo _>{
6455   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6456                       (ins _.RC:$src1, i32u8imm:$src2),
6457                       OpcodeStr##_.Suffix, "$src2, $src1", "$src2, $src2",
6458                       (OpNode (_.VT _.RC:$src1),
6459                               (i32 imm:$src2),
6460                               (i32 FROUND_CURRENT))>;
6461   let mayLoad = 1 in {
6462     defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6463                       (ins _.MemOp:$src1, i32u8imm:$src2),
6464                       OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
6465                       (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
6466                               (i32 imm:$src2),
6467                               (i32 FROUND_CURRENT))>;
6468     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6469                       (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
6470                       OpcodeStr##_.Suffix, "$src2, ${src1}"##_.BroadcastStr,
6471                       "${src1}"##_.BroadcastStr##", $src2",
6472                       (OpNode (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src1))),
6473                               (i32 imm:$src2),
6474                               (i32 FROUND_CURRENT))>, EVEX_B;
6475   }
6476 }
6477
6478 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6479 multiclass avx512_unary_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
6480                                              SDNode OpNode, X86VectorVTInfo _>{
6481   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6482                       (ins _.RC:$src1, i32u8imm:$src2),
6483                       OpcodeStr##_.Suffix, "$src2,{sae}, $src1",
6484                       "$src1, {sae}, $src2",
6485                       (OpNode (_.VT _.RC:$src1),
6486                               (i32 imm:$src2),
6487                               (i32 FROUND_NO_EXC))>, EVEX_B;
6488 }
6489
6490 multiclass avx512_common_unary_fp_sae_packed_imm<string OpcodeStr,
6491             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6492   let Predicates = [prd] in {
6493     defm Z    : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6494                 avx512_unary_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6495                                   EVEX_V512;
6496   }
6497   let Predicates = [prd, HasVLX] in {
6498     defm Z128 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
6499                                   EVEX_V128;
6500     defm Z256 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
6501                                   EVEX_V256;
6502   }
6503 }
6504
6505 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6506 //                               op(reg_vec2,mem_vec,imm)
6507 //                               op(reg_vec2,broadcast(eltVt),imm)
6508 //all instruction created with FROUND_CURRENT
6509 multiclass avx512_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6510                                                             X86VectorVTInfo _>{
6511   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6512                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6513                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6514                       (OpNode (_.VT _.RC:$src1),
6515                               (_.VT _.RC:$src2),
6516                               (i32 imm:$src3),
6517                               (i32 FROUND_CURRENT))>;
6518   let mayLoad = 1 in {
6519     defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6520                       (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
6521                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6522                       (OpNode (_.VT _.RC:$src1),
6523                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
6524                               (i32 imm:$src3),
6525                               (i32 FROUND_CURRENT))>;
6526     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6527                       (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
6528                       OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
6529                       "$src1, ${src2}"##_.BroadcastStr##", $src3",
6530                       (OpNode (_.VT _.RC:$src1),
6531                               (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
6532                               (i32 imm:$src3),
6533                               (i32 FROUND_CURRENT))>, EVEX_B;
6534   }
6535 }
6536
6537 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6538 //                               op(reg_vec2,mem_vec,imm)
6539 multiclass avx512_3Op_rm_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
6540                              X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo>{
6541
6542   defm rri : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
6543                   (ins SrcInfo.RC:$src1, SrcInfo.RC:$src2, u8imm:$src3),
6544                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6545                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
6546                                (SrcInfo.VT SrcInfo.RC:$src2),
6547                                (i8 imm:$src3)))>;
6548   let mayLoad = 1 in
6549     defm rmi : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
6550                   (ins SrcInfo.RC:$src1, SrcInfo.MemOp:$src2, u8imm:$src3),
6551                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6552                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
6553                                (SrcInfo.VT (bitconvert
6554                                                   (SrcInfo.LdFrag addr:$src2))),
6555                                (i8 imm:$src3)))>;
6556 }
6557
6558 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6559 //                               op(reg_vec2,mem_vec,imm)
6560 //                               op(reg_vec2,broadcast(eltVt),imm)
6561 multiclass avx512_3Op_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
6562                            X86VectorVTInfo _>:
6563   avx512_3Op_rm_imm8<opc, OpcodeStr, OpNode, _, _>{
6564
6565   let mayLoad = 1 in
6566     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6567                       (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
6568                       OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
6569                       "$src1, ${src2}"##_.BroadcastStr##", $src3",
6570                       (OpNode (_.VT _.RC:$src1),
6571                               (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
6572                               (i8 imm:$src3))>, EVEX_B;
6573 }
6574
6575 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6576 //                                      op(reg_vec2,mem_scalar,imm)
6577 //all instruction created with FROUND_CURRENT
6578 multiclass avx512_fp_scalar_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6579                                                            X86VectorVTInfo _> {
6580
6581   defm rri : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6582                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6583                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6584                       (OpNode (_.VT _.RC:$src1),
6585                               (_.VT _.RC:$src2),
6586                               (i32 imm:$src3),
6587                               (i32 FROUND_CURRENT))>;
6588   let mayLoad = 1 in {
6589     defm rmi : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6590                       (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
6591                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6592                       (OpNode (_.VT _.RC:$src1),
6593                               (_.VT (scalar_to_vector
6594                                         (_.ScalarLdFrag addr:$src2))),
6595                               (i32 imm:$src3),
6596                               (i32 FROUND_CURRENT))>;
6597
6598     let isAsmParserOnly = 1 in {
6599       defm rmi_alt :AVX512_maskable_in_asm<opc, MRMSrcMem, _, (outs _.FRC:$dst),
6600                       (ins _.FRC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
6601                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6602                       []>;
6603     }
6604   }
6605 }
6606
6607 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6608 multiclass avx512_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
6609                                              SDNode OpNode, X86VectorVTInfo _>{
6610   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6611                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6612                       OpcodeStr, "$src3,{sae}, $src2, $src1",
6613                       "$src1, $src2,{sae}, $src3",
6614                       (OpNode (_.VT _.RC:$src1),
6615                               (_.VT _.RC:$src2),
6616                               (i32 imm:$src3),
6617                               (i32 FROUND_NO_EXC))>, EVEX_B;
6618 }
6619 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6620 multiclass avx512_fp_sae_scalar_imm<bits<8> opc, string OpcodeStr,
6621                                              SDNode OpNode, X86VectorVTInfo _> {
6622   defm NAME#rrib : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6623                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6624                       OpcodeStr, "$src3,{sae}, $src2, $src1",
6625                       "$src1, $src2,{sae}, $src3",
6626                       (OpNode (_.VT _.RC:$src1),
6627                               (_.VT _.RC:$src2),
6628                               (i32 imm:$src3),
6629                               (i32 FROUND_NO_EXC))>, EVEX_B;
6630 }
6631
6632 multiclass avx512_common_fp_sae_packed_imm<string OpcodeStr,
6633             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6634   let Predicates = [prd] in {
6635     defm Z    : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6636                 avx512_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6637                                   EVEX_V512;
6638
6639   }
6640   let Predicates = [prd, HasVLX] in {
6641     defm Z128 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
6642                                   EVEX_V128;
6643     defm Z256 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
6644                                   EVEX_V256;
6645   }
6646 }
6647
6648 multiclass avx512_common_3Op_rm_imm8<bits<8> opc, SDNode OpNode, string OpStr,
6649                    AVX512VLVectorVTInfo DestInfo, AVX512VLVectorVTInfo SrcInfo>{
6650   let Predicates = [HasBWI] in {
6651     defm Z    : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info512,
6652                            SrcInfo.info512>, EVEX_V512, AVX512AIi8Base, EVEX_4V;
6653   }
6654   let Predicates = [HasBWI, HasVLX] in {
6655     defm Z128 : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info128,
6656                            SrcInfo.info128>, EVEX_V128, AVX512AIi8Base, EVEX_4V;
6657     defm Z256 : avx512_3Op_rm_imm8<opc, OpStr, OpNode,  DestInfo.info256,
6658                            SrcInfo.info256>, EVEX_V256, AVX512AIi8Base, EVEX_4V;
6659   }
6660 }
6661
6662 multiclass avx512_common_3Op_imm8<string OpcodeStr, AVX512VLVectorVTInfo _,
6663                                 bits<8> opc, SDNode OpNode>{
6664   let Predicates = [HasAVX512] in {
6665     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
6666   }
6667   let Predicates = [HasAVX512, HasVLX] in {
6668     defm Z128 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
6669     defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
6670   }
6671 }
6672
6673 multiclass avx512_common_fp_sae_scalar_imm<string OpcodeStr,
6674                   X86VectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6675   let Predicates = [prd] in {
6676      defm Z128 : avx512_fp_scalar_imm<opc, OpcodeStr, OpNode, _>,
6677                  avx512_fp_sae_scalar_imm<opc, OpcodeStr, OpNode, _>;
6678   }
6679 }
6680
6681 multiclass avx512_common_unary_fp_sae_packed_imm_all<string OpcodeStr,
6682                     bits<8> opcPs, bits<8> opcPd, SDNode OpNode, Predicate prd>{
6683   defm PS : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f32_info,
6684                             opcPs, OpNode, prd>, EVEX_CD8<32, CD8VF>;
6685   defm PD : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f64_info,
6686                             opcPd, OpNode, prd>, EVEX_CD8<64, CD8VF>, VEX_W;
6687 }
6688
6689 defm VFIXUPIMMPD : avx512_common_fp_sae_packed_imm<"vfixupimmpd",
6690                               avx512vl_f64_info, 0x54, X86VFixupimm, HasAVX512>,
6691       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6692 defm VFIXUPIMMPS : avx512_common_fp_sae_packed_imm<"vfixupimmps",
6693                               avx512vl_f32_info, 0x54, X86VFixupimm, HasAVX512>,
6694       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6695
6696 defm VFIXUPIMMSD: avx512_common_fp_sae_scalar_imm<"vfixupimmsd", f64x_info,
6697                                                  0x55, X86VFixupimm, HasAVX512>,
6698       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6699 defm VFIXUPIMMSS: avx512_common_fp_sae_scalar_imm<"vfixupimmss", f32x_info,
6700                                                  0x55, X86VFixupimm, HasAVX512>,
6701       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6702
6703 defm VREDUCE   : avx512_common_unary_fp_sae_packed_imm_all<"vreduce", 0x56, 0x56,
6704                               X86VReduce, HasDQI>, AVX512AIi8Base, EVEX;
6705 defm VRNDSCALE : avx512_common_unary_fp_sae_packed_imm_all<"vrndscale", 0x08, 0x09,
6706                               X86VRndScale, HasAVX512>, AVX512AIi8Base, EVEX;
6707 defm VGETMANT : avx512_common_unary_fp_sae_packed_imm_all<"vgetmant", 0x26, 0x26,
6708                               X86VGetMant, HasAVX512>, AVX512AIi8Base, EVEX;
6709
6710
6711 defm VRANGEPD : avx512_common_fp_sae_packed_imm<"vrangepd", avx512vl_f64_info,
6712                                                        0x50, X86VRange, HasDQI>,
6713       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6714 defm VRANGEPS : avx512_common_fp_sae_packed_imm<"vrangeps", avx512vl_f32_info,
6715                                                        0x50, X86VRange, HasDQI>,
6716       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6717
6718 defm VRANGESD: avx512_common_fp_sae_scalar_imm<"vrangesd", f64x_info,
6719                                                  0x51, X86VRange, HasDQI>,
6720       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6721 defm VRANGESS: avx512_common_fp_sae_scalar_imm<"vrangess", f32x_info,
6722                                                  0x51, X86VRange, HasDQI>,
6723       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6724
6725 defm VREDUCESD: avx512_common_fp_sae_scalar_imm<"vreducesd", f64x_info,
6726                                                  0x57, X86Reduces, HasDQI>,
6727       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6728 defm VREDUCESS: avx512_common_fp_sae_scalar_imm<"vreducess", f32x_info,
6729                                                  0x57, X86Reduces, HasDQI>,
6730       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6731
6732 defm VGETMANTSD: avx512_common_fp_sae_scalar_imm<"vgetmantsd", f64x_info,
6733                                                  0x27, X86GetMants, HasAVX512>,
6734       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6735 defm VGETMANTSS: avx512_common_fp_sae_scalar_imm<"vgetmantss", f32x_info,
6736                                                  0x27, X86GetMants, HasAVX512>,
6737       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6738
6739 multiclass avx512_shuff_packed_128<string OpcodeStr, AVX512VLVectorVTInfo _,
6740                                        bits<8> opc, SDNode OpNode = X86Shuf128>{
6741   let Predicates = [HasAVX512] in {
6742     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
6743
6744   }
6745   let Predicates = [HasAVX512, HasVLX] in {
6746      defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
6747   }
6748 }
6749 let Predicates = [HasAVX512] in {
6750 def : Pat<(v16f32 (ffloor VR512:$src)),
6751           (VRNDSCALEPSZrri VR512:$src, (i32 0x1))>;
6752 def : Pat<(v16f32 (fnearbyint VR512:$src)),
6753           (VRNDSCALEPSZrri VR512:$src, (i32 0xC))>;
6754 def : Pat<(v16f32 (fceil VR512:$src)),
6755           (VRNDSCALEPSZrri VR512:$src, (i32 0x2))>;
6756 def : Pat<(v16f32 (frint VR512:$src)),
6757           (VRNDSCALEPSZrri VR512:$src, (i32 0x4))>;
6758 def : Pat<(v16f32 (ftrunc VR512:$src)),
6759           (VRNDSCALEPSZrri VR512:$src, (i32 0x3))>;
6760
6761 def : Pat<(v8f64 (ffloor VR512:$src)),
6762           (VRNDSCALEPDZrri VR512:$src, (i32 0x1))>;
6763 def : Pat<(v8f64 (fnearbyint VR512:$src)),
6764           (VRNDSCALEPDZrri VR512:$src, (i32 0xC))>;
6765 def : Pat<(v8f64 (fceil VR512:$src)),
6766           (VRNDSCALEPDZrri VR512:$src, (i32 0x2))>;
6767 def : Pat<(v8f64 (frint VR512:$src)),
6768           (VRNDSCALEPDZrri VR512:$src, (i32 0x4))>;
6769 def : Pat<(v8f64 (ftrunc VR512:$src)),
6770           (VRNDSCALEPDZrri VR512:$src, (i32 0x3))>;
6771 }
6772
6773 defm VSHUFF32X4 : avx512_shuff_packed_128<"vshuff32x4",avx512vl_f32_info, 0x23>,
6774       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6775 defm VSHUFF64X2 : avx512_shuff_packed_128<"vshuff64x2",avx512vl_f64_info, 0x23>,
6776       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6777 defm VSHUFI32X4 : avx512_shuff_packed_128<"vshufi32x4",avx512vl_i32_info, 0x43>,
6778       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6779 defm VSHUFI64X2 : avx512_shuff_packed_128<"vshufi64x2",avx512vl_i64_info, 0x43>,
6780       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6781
6782 multiclass avx512_valign<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
6783                                                 AVX512VLVectorVTInfo VTInfo_FP>{
6784   defm NAME:       avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0x03, X86VAlign>,
6785                            AVX512AIi8Base, EVEX_4V;
6786   let isCodeGenOnly = 1 in {
6787     defm NAME#_FP: avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0x03, X86VAlign>,
6788                            AVX512AIi8Base, EVEX_4V;
6789   }
6790 }
6791
6792 defm VALIGND: avx512_valign<"valignd", avx512vl_i32_info, avx512vl_f32_info>,
6793                                                   EVEX_CD8<32, CD8VF>;
6794 defm VALIGNQ: avx512_valign<"valignq", avx512vl_i64_info, avx512vl_f64_info>,
6795                                                   EVEX_CD8<64, CD8VF>, VEX_W;
6796
6797 multiclass avx512_vpalign_lowering<X86VectorVTInfo _ , list<Predicate> p>{
6798   let Predicates = p in
6799     def NAME#_.VTName#rri:
6800           Pat<(_.VT (X86PAlignr _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
6801               (!cast<Instruction>(NAME#_.ZSuffix#rri)
6802                     _.RC:$src1, _.RC:$src2, imm:$imm)>;
6803 }
6804
6805 multiclass avx512_vpalign_lowering_common<AVX512VLVectorVTInfo _>:
6806       avx512_vpalign_lowering<_.info512, [HasBWI]>,
6807       avx512_vpalign_lowering<_.info128, [HasBWI, HasVLX]>,
6808       avx512_vpalign_lowering<_.info256, [HasBWI, HasVLX]>;
6809
6810 defm VPALIGN:   avx512_common_3Op_rm_imm8<0x0F, X86PAlignr, "vpalignr" ,
6811                                           avx512vl_i8_info, avx512vl_i8_info>,
6812                 avx512_vpalign_lowering_common<avx512vl_i16_info>,
6813                 avx512_vpalign_lowering_common<avx512vl_i32_info>,
6814                 avx512_vpalign_lowering_common<avx512vl_f32_info>,
6815                 avx512_vpalign_lowering_common<avx512vl_i64_info>,
6816                 avx512_vpalign_lowering_common<avx512vl_f64_info>,
6817                 EVEX_CD8<8, CD8VF>;
6818
6819 defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw" ,
6820                     avx512vl_i16_info, avx512vl_i8_info>, EVEX_CD8<8, CD8VF>;
6821
6822 multiclass avx512_unary_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6823                            X86VectorVTInfo _> {
6824   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6825                     (ins _.RC:$src1), OpcodeStr##_.Suffix,
6826                     "$src1", "$src1",
6827                     (_.VT (OpNode _.RC:$src1))>, EVEX, AVX5128IBase;
6828
6829   let mayLoad = 1 in
6830     defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6831                     (ins _.MemOp:$src1), OpcodeStr##_.Suffix,
6832                     "$src1", "$src1",
6833                     (_.VT (OpNode (bitconvert (_.LdFrag addr:$src1))))>,
6834               EVEX, AVX5128IBase, EVEX_CD8<_.EltSize, CD8VF>;
6835 }
6836
6837 multiclass avx512_unary_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
6838                             X86VectorVTInfo _> :
6839            avx512_unary_rm<opc, OpcodeStr, OpNode, _> {
6840   let mayLoad = 1 in
6841     defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6842                     (ins _.ScalarMemOp:$src1), OpcodeStr##_.Suffix,
6843                     "${src1}"##_.BroadcastStr,
6844                     "${src1}"##_.BroadcastStr,
6845                     (_.VT (OpNode (X86VBroadcast
6846                                       (_.ScalarLdFrag addr:$src1))))>,
6847                EVEX, AVX5128IBase, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
6848 }
6849
6850 multiclass avx512_unary_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
6851                               AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6852   let Predicates = [prd] in
6853     defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
6854
6855   let Predicates = [prd, HasVLX] in {
6856     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
6857                               EVEX_V256;
6858     defm Z128 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info128>,
6859                               EVEX_V128;
6860   }
6861 }
6862
6863 multiclass avx512_unary_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
6864                                AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6865   let Predicates = [prd] in
6866     defm Z : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
6867                               EVEX_V512;
6868
6869   let Predicates = [prd, HasVLX] in {
6870     defm Z256 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
6871                                  EVEX_V256;
6872     defm Z128 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
6873                                  EVEX_V128;
6874   }
6875 }
6876
6877 multiclass avx512_unary_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
6878                                  SDNode OpNode, Predicate prd> {
6879   defm Q : avx512_unary_rmb_vl<opc_q, OpcodeStr, OpNode, avx512vl_i64_info,
6880                                prd>, VEX_W;
6881   defm D : avx512_unary_rmb_vl<opc_d, OpcodeStr, OpNode, avx512vl_i32_info, prd>;
6882 }
6883
6884 multiclass avx512_unary_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
6885                                  SDNode OpNode, Predicate prd> {
6886   defm W : avx512_unary_rm_vl<opc_w, OpcodeStr, OpNode, avx512vl_i16_info, prd>;
6887   defm B : avx512_unary_rm_vl<opc_b, OpcodeStr, OpNode, avx512vl_i8_info, prd>;
6888 }
6889
6890 multiclass avx512_unary_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
6891                                   bits<8> opc_d, bits<8> opc_q,
6892                                   string OpcodeStr, SDNode OpNode> {
6893   defm NAME : avx512_unary_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
6894                                     HasAVX512>,
6895               avx512_unary_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
6896                                     HasBWI>;
6897 }
6898
6899 defm VPABS : avx512_unary_rm_vl_all<0x1C, 0x1D, 0x1E, 0x1F, "vpabs", X86Abs>;
6900
6901 def : Pat<(xor
6902           (bc_v16i32 (v16i1sextv16i32)),
6903           (bc_v16i32 (add (v16i32 VR512:$src), (v16i1sextv16i32)))),
6904           (VPABSDZrr VR512:$src)>;
6905 def : Pat<(xor
6906           (bc_v8i64 (v8i1sextv8i64)),
6907           (bc_v8i64 (add (v8i64 VR512:$src), (v8i1sextv8i64)))),
6908           (VPABSQZrr VR512:$src)>;
6909
6910 multiclass avx512_ctlz<bits<8> opc, string OpcodeStr, Predicate prd>{
6911
6912   defm NAME :          avx512_unary_rm_vl_dq<opc, opc, OpcodeStr, ctlz, prd>;
6913   let isCodeGenOnly = 1 in
6914     defm NAME#_UNDEF : avx512_unary_rm_vl_dq<opc, opc, OpcodeStr,
6915                                              ctlz_zero_undef, prd>;
6916 }
6917
6918 defm VPLZCNT    : avx512_ctlz<0x44, "vplzcnt", HasCDI>;
6919 defm VPCONFLICT : avx512_unary_rm_vl_dq<0xC4, 0xC4, "vpconflict", X86Conflict, HasCDI>;
6920
6921 //===----------------------------------------------------------------------===//
6922 // AVX-512 - Unpack Instructions
6923 //===----------------------------------------------------------------------===//
6924 defm VUNPCKH : avx512_fp_binop_p<0x15, "vunpckh", X86Unpckh>;
6925 defm VUNPCKL : avx512_fp_binop_p<0x14, "vunpckl", X86Unpckl>;
6926
6927 defm VPUNPCKLBW : avx512_binop_rm_vl_b<0x60, "vpunpcklbw", X86Unpckl,
6928                                        SSE_INTALU_ITINS_P, HasBWI>;
6929 defm VPUNPCKHBW : avx512_binop_rm_vl_b<0x68, "vpunpckhbw", X86Unpckh,
6930                                        SSE_INTALU_ITINS_P, HasBWI>;
6931 defm VPUNPCKLWD : avx512_binop_rm_vl_w<0x61, "vpunpcklwd", X86Unpckl,
6932                                        SSE_INTALU_ITINS_P, HasBWI>;
6933 defm VPUNPCKHWD : avx512_binop_rm_vl_w<0x69, "vpunpckhwd", X86Unpckh,
6934                                        SSE_INTALU_ITINS_P, HasBWI>;
6935
6936 defm VPUNPCKLDQ : avx512_binop_rm_vl_d<0x62, "vpunpckldq", X86Unpckl,
6937                                        SSE_INTALU_ITINS_P, HasAVX512>;
6938 defm VPUNPCKHDQ : avx512_binop_rm_vl_d<0x6A, "vpunpckhdq", X86Unpckh,
6939                                        SSE_INTALU_ITINS_P, HasAVX512>;
6940 defm VPUNPCKLQDQ : avx512_binop_rm_vl_q<0x6C, "vpunpcklqdq", X86Unpckl,
6941                                        SSE_INTALU_ITINS_P, HasAVX512>;
6942 defm VPUNPCKHQDQ : avx512_binop_rm_vl_q<0x6D, "vpunpckhqdq", X86Unpckh,
6943                                        SSE_INTALU_ITINS_P, HasAVX512>;
6944 //===----------------------------------------------------------------------===//
6945 // VSHUFPS - VSHUFPD Operations
6946 //===----------------------------------------------------------------------===//
6947 multiclass avx512_shufp<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
6948                                                 AVX512VLVectorVTInfo VTInfo_FP>{
6949   defm NAME:     avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0xC6, X86Shufp>,
6950                                    EVEX_CD8<VTInfo_FP.info512.EltSize, CD8VF>,
6951                                    AVX512AIi8Base, EVEX_4V;
6952   let isCodeGenOnly = 1 in {
6953     defm NAME#_I: avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0xC6, X86Shufp>,
6954                                    EVEX_CD8<VTInfo_I.info512.EltSize, CD8VF>,
6955                                    AVX512AIi8Base, EVEX_4V;
6956   }
6957 }
6958
6959 defm VSHUFPS: avx512_shufp<"vshufps", avx512vl_i32_info, avx512vl_f32_info>, PS;
6960 defm VSHUFPD: avx512_shufp<"vshufpd", avx512vl_i64_info, avx512vl_f64_info>, PD, VEX_W;
6961 //===----------------------------------------------------------------------===//
6962 // AVX-512 - Byte shift Left/Right
6963 //===----------------------------------------------------------------------===//
6964
6965 multiclass avx512_shift_packed<bits<8> opc, SDNode OpNode, Format MRMr,
6966                              Format MRMm, string OpcodeStr, X86VectorVTInfo _>{
6967   def rr : AVX512<opc, MRMr,
6968              (outs _.RC:$dst), (ins _.RC:$src1, u8imm:$src2),
6969              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6970              [(set _.RC:$dst,(_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>;
6971   let mayLoad = 1 in
6972     def rm : AVX512<opc, MRMm,
6973              (outs _.RC:$dst), (ins _.MemOp:$src1, u8imm:$src2),
6974              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6975              [(set _.RC:$dst,(_.VT (OpNode 
6976                                    (_.LdFrag addr:$src1), (i8 imm:$src2))))]>;
6977 }
6978
6979 multiclass avx512_shift_packed_all<bits<8> opc, SDNode OpNode, Format MRMr, 
6980                                  Format MRMm, string OpcodeStr, Predicate prd>{
6981   let Predicates = [prd] in
6982     defm Z512 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
6983                                     OpcodeStr, v8i64_info>, EVEX_V512;
6984   let Predicates = [prd, HasVLX] in {
6985     defm Z256 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
6986                                     OpcodeStr, v4i64x_info>, EVEX_V256;
6987     defm Z128 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
6988                                     OpcodeStr, v2i64x_info>, EVEX_V128;
6989   }
6990 }
6991 defm VPSLLDQ : avx512_shift_packed_all<0x73, X86vshldq, MRM7r, MRM7m, "vpslldq", 
6992                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
6993 defm VPSRLDQ : avx512_shift_packed_all<0x73, X86vshrdq, MRM3r, MRM3m, "vpsrldq", 
6994                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
6995
6996
6997 multiclass avx512_psadbw_packed<bits<8> opc, SDNode OpNode, 
6998                                 string OpcodeStr, X86VectorVTInfo _src>{
6999   def rr : AVX512BI<opc, MRMSrcReg,
7000              (outs _src.RC:$dst), (ins _src.RC:$src1, _src.RC:$src2),
7001              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7002              [(set _src.RC:$dst,(_src.VT 
7003                                 (OpNode _src.RC:$src1, _src.RC:$src2)))]>;
7004   let mayLoad = 1 in
7005     def rm : AVX512BI<opc, MRMSrcMem,
7006              (outs _src.RC:$dst), (ins _src.RC:$src1, _src.MemOp:$src2),
7007              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7008              [(set _src.RC:$dst,(_src.VT 
7009                                 (OpNode _src.RC:$src1, 
7010                                 (_src.VT (bitconvert 
7011                                           (_src.LdFrag addr:$src2))))))]>;
7012 }
7013
7014 multiclass avx512_psadbw_packed_all<bits<8> opc, SDNode OpNode, 
7015                                     string OpcodeStr, Predicate prd> {
7016   let Predicates = [prd] in
7017     defm Z512 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v64i8_info>, 
7018                                     EVEX_V512;
7019   let Predicates = [prd, HasVLX] in {
7020     defm Z256 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v32i8x_info>, 
7021                                     EVEX_V256;
7022     defm Z128 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v16i8x_info>,
7023                                     EVEX_V128;
7024   }
7025 }
7026
7027 defm VPSADBW : avx512_psadbw_packed_all<0xf6, X86psadbw, "vpsadbw", 
7028                                        HasBWI>, EVEX_4V;