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