9f57958b2da65441f36540c1d2cdc7e334c81fd7
[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           vextract128_extract, EXTRACT_get_vextract128_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<RegisterClass destRC, RegisterClass srcRC,
5335                              X86MemOperand x86memop> {
5336   def rr : AVX5128I<0x13, MRMSrcReg, (outs destRC:$dst), (ins srcRC:$src),
5337              "vcvtph2ps\t{$src, $dst|$dst, $src}",
5338              []>, EVEX;
5339   let hasSideEffects = 0, mayLoad = 1 in
5340   def rm : AVX5128I<0x13, MRMSrcMem, (outs destRC:$dst), (ins x86memop:$src),
5341              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, EVEX;
5342 }
5343
5344 multiclass avx512_cvtps2ph<RegisterClass destRC, RegisterClass srcRC,
5345                              X86MemOperand x86memop> {
5346   def rr : AVX512AIi8<0x1D, MRMDestReg, (outs destRC:$dst),
5347                (ins srcRC:$src1, i32u8imm:$src2),
5348                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5349                []>, EVEX;
5350   let hasSideEffects = 0, mayStore = 1 in
5351   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
5352                (ins x86memop:$dst, srcRC:$src1, i32u8imm:$src2),
5353                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, EVEX;
5354 }
5355
5356 defm VCVTPH2PSZ : avx512_cvtph2ps<VR512, VR256X, f256mem>, EVEX_V512,
5357                                     EVEX_CD8<32, CD8VH>;
5358 defm VCVTPS2PHZ : avx512_cvtps2ph<VR256X, VR512, f256mem>, EVEX_V512,
5359                                     EVEX_CD8<32, CD8VH>;
5360
5361 def : Pat<(v16i16 (int_x86_avx512_mask_vcvtps2ph_512 (v16f32 VR512:$src),
5362            imm:$rc, (bc_v16i16(v8i32 immAllZerosV)), (i16 -1))),
5363            (VCVTPS2PHZrr VR512:$src, imm:$rc)>;
5364
5365 def : Pat<(v16f32 (int_x86_avx512_mask_vcvtph2ps_512 (v16i16 VR256X:$src),
5366            (bc_v16f32(v16i32 immAllZerosV)), (i16 -1), (i32 FROUND_CURRENT))),
5367            (VCVTPH2PSZrr VR256X:$src)>;
5368
5369 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
5370   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
5371                                  "ucomiss">, PS, EVEX, VEX_LIG,
5372                                  EVEX_CD8<32, CD8VT1>;
5373   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
5374                                   "ucomisd">, PD, EVEX,
5375                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5376   let Pattern = []<dag> in {
5377     defm VCOMISSZ  : sse12_ord_cmp<0x2F, FR32X, undef, f32, f32mem, loadf32,
5378                                    "comiss">, PS, EVEX, VEX_LIG,
5379                                    EVEX_CD8<32, CD8VT1>;
5380     defm VCOMISDZ  : sse12_ord_cmp<0x2F, FR64X, undef, f64, f64mem, loadf64,
5381                                    "comisd">, PD, EVEX,
5382                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5383   }
5384   let isCodeGenOnly = 1 in {
5385     defm Int_VUCOMISSZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v4f32, f128mem,
5386                               load, "ucomiss">, PS, EVEX, VEX_LIG,
5387                               EVEX_CD8<32, CD8VT1>;
5388     defm Int_VUCOMISDZ  : sse12_ord_cmp<0x2E, VR128X, X86ucomi, v2f64, f128mem,
5389                               load, "ucomisd">, PD, EVEX,
5390                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5391
5392     defm Int_VCOMISSZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v4f32, f128mem,
5393                               load, "comiss">, PS, EVEX, VEX_LIG,
5394                               EVEX_CD8<32, CD8VT1>;
5395     defm Int_VCOMISDZ  : sse12_ord_cmp<0x2F, VR128X, X86comi, v2f64, f128mem,
5396                               load, "comisd">, PD, EVEX,
5397                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
5398   }
5399 }
5400
5401 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
5402 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
5403                             X86VectorVTInfo _> {
5404   let hasSideEffects = 0, AddedComplexity = 20 , Predicates = [HasAVX512] in {
5405   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5406                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5407                            "$src2, $src1", "$src1, $src2",
5408                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>, EVEX_4V;
5409   let mayLoad = 1 in {
5410   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5411                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5412                          "$src2, $src1", "$src1, $src2",
5413                          (OpNode (_.VT _.RC:$src1),
5414                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))))>, EVEX_4V;
5415   }
5416 }
5417 }
5418
5419 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", X86frcp14s, f32x_info>,
5420                   EVEX_CD8<32, CD8VT1>, T8PD;
5421 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", X86frcp14s, f64x_info>,
5422                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
5423 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", X86frsqrt14s, f32x_info>,
5424                   EVEX_CD8<32, CD8VT1>, T8PD;
5425 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", X86frsqrt14s, f64x_info>,
5426                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
5427
5428 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
5429 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
5430                          X86VectorVTInfo _> {
5431   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5432                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5433                          (_.FloatVT (OpNode _.RC:$src))>, EVEX, T8PD;
5434   let mayLoad = 1 in {
5435     defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5436                            (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5437                            (OpNode (_.FloatVT
5438                              (bitconvert (_.LdFrag addr:$src))))>, EVEX, T8PD;
5439     defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5440                             (ins _.ScalarMemOp:$src), OpcodeStr,
5441                             "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5442                             (OpNode (_.FloatVT
5443                               (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
5444                             EVEX, T8PD, EVEX_B;
5445   }
5446 }
5447
5448 multiclass avx512_fp14_p_vl_all<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5449   defm PSZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"), OpNode, v16f32_info>,
5450                           EVEX_V512, EVEX_CD8<32, CD8VF>;
5451   defm PDZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"), OpNode, v8f64_info>,
5452                           EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
5453
5454   // Define only if AVX512VL feature is present.
5455   let Predicates = [HasVLX] in {
5456     defm PSZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
5457                                 OpNode, v4f32x_info>,
5458                                EVEX_V128, EVEX_CD8<32, CD8VF>;
5459     defm PSZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
5460                                 OpNode, v8f32x_info>,
5461                                EVEX_V256, EVEX_CD8<32, CD8VF>;
5462     defm PDZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
5463                                 OpNode, v2f64x_info>,
5464                                EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
5465     defm PDZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
5466                                 OpNode, v4f64x_info>,
5467                                EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
5468   }
5469 }
5470
5471 defm VRSQRT14 : avx512_fp14_p_vl_all<0x4E, "vrsqrt14", X86frsqrt>;
5472 defm VRCP14 : avx512_fp14_p_vl_all<0x4C, "vrcp14", X86frcp>;
5473
5474 def : Pat <(v16f32 (int_x86_avx512_rsqrt14_ps_512 (v16f32 VR512:$src),
5475               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
5476            (VRSQRT14PSZr VR512:$src)>;
5477 def : Pat <(v8f64 (int_x86_avx512_rsqrt14_pd_512 (v8f64 VR512:$src),
5478               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
5479            (VRSQRT14PDZr VR512:$src)>;
5480
5481 def : Pat <(v16f32 (int_x86_avx512_rcp14_ps_512 (v16f32 VR512:$src),
5482               (bc_v16f32 (v16i32 immAllZerosV)), (i16 -1))),
5483            (VRCP14PSZr VR512:$src)>;
5484 def : Pat <(v8f64 (int_x86_avx512_rcp14_pd_512 (v8f64 VR512:$src),
5485               (bc_v8f64 (v16i32 immAllZerosV)), (i8 -1))),
5486            (VRCP14PDZr VR512:$src)>;
5487
5488 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
5489 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
5490                          SDNode OpNode> {
5491
5492   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5493                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5494                            "$src2, $src1", "$src1, $src2",
5495                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5496                            (i32 FROUND_CURRENT))>;
5497
5498   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5499                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5500                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
5501                             (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5502                             (i32 FROUND_NO_EXC))>, EVEX_B;
5503
5504   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5505                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5506                          "$src2, $src1", "$src1, $src2",
5507                          (OpNode (_.VT _.RC:$src1),
5508                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
5509                          (i32 FROUND_CURRENT))>;
5510 }
5511
5512 multiclass avx512_eri_s<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5513   defm SS : avx512_fp28_s<opc, OpcodeStr#"ss", f32x_info, OpNode>,
5514               EVEX_CD8<32, CD8VT1>;
5515   defm SD : avx512_fp28_s<opc, OpcodeStr#"sd", f64x_info, OpNode>,
5516               EVEX_CD8<64, CD8VT1>, VEX_W;
5517 }
5518
5519 let hasSideEffects = 0, Predicates = [HasERI] in {
5520   defm VRCP28   : avx512_eri_s<0xCB, "vrcp28",   X86rcp28s>,   T8PD, EVEX_4V;
5521   defm VRSQRT28 : avx512_eri_s<0xCD, "vrsqrt28", X86rsqrt28s>, T8PD, EVEX_4V;
5522 }
5523
5524 defm VGETEXP   : avx512_eri_s<0x43, "vgetexp", X86fgetexpRnds>, T8PD, EVEX_4V;
5525 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
5526
5527 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5528                          SDNode OpNode> {
5529
5530   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5531                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5532                          (OpNode (_.VT _.RC:$src), (i32 FROUND_CURRENT))>;
5533
5534   defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5535                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5536                          (OpNode (_.FloatVT
5537                              (bitconvert (_.LdFrag addr:$src))),
5538                           (i32 FROUND_CURRENT))>;
5539
5540   defm mb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5541                          (ins _.MemOp:$src), OpcodeStr,
5542                          "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5543                          (OpNode (_.FloatVT
5544                                   (X86VBroadcast (_.ScalarLdFrag addr:$src))),
5545                                  (i32 FROUND_CURRENT))>, EVEX_B;
5546 }
5547 multiclass avx512_fp28_p_round<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5548                          SDNode OpNode> {
5549   defm rb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5550                         (ins _.RC:$src), OpcodeStr,
5551                         "{sae}, $src", "$src, {sae}",
5552                         (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, EVEX_B;
5553 }
5554
5555 multiclass  avx512_eri<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5556    defm PS : avx512_fp28_p<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
5557              avx512_fp28_p_round<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
5558              T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
5559    defm PD : avx512_fp28_p<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
5560              avx512_fp28_p_round<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
5561              T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
5562 }
5563
5564 multiclass avx512_fp_unaryop_packed<bits<8> opc, string OpcodeStr,
5565                                   SDNode OpNode> {
5566   // Define only if AVX512VL feature is present.
5567   let Predicates = [HasVLX] in {
5568     defm PSZ128 : avx512_fp28_p<opc, OpcodeStr#"ps", v4f32x_info, OpNode>,
5569                                      EVEX_V128, T8PD, EVEX_CD8<32, CD8VF>;
5570     defm PSZ256 : avx512_fp28_p<opc, OpcodeStr#"ps", v8f32x_info, OpNode>,
5571                                      EVEX_V256, T8PD, EVEX_CD8<32, CD8VF>;
5572     defm PDZ128 : avx512_fp28_p<opc, OpcodeStr#"pd", v2f64x_info, OpNode>,
5573                                      EVEX_V128, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
5574     defm PDZ256 : avx512_fp28_p<opc, OpcodeStr#"pd", v4f64x_info, OpNode>,
5575                                      EVEX_V256, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
5576   }
5577 }
5578 let Predicates = [HasERI], hasSideEffects = 0 in {
5579
5580  defm VRSQRT28 : avx512_eri<0xCC, "vrsqrt28", X86rsqrt28>, EVEX;
5581  defm VRCP28   : avx512_eri<0xCA, "vrcp28",   X86rcp28>,   EVEX;
5582  defm VEXP2    : avx512_eri<0xC8, "vexp2",    X86exp2>,    EVEX;
5583 }
5584 defm VGETEXP   : avx512_eri<0x42, "vgetexp", X86fgetexpRnd>,
5585                  avx512_fp_unaryop_packed<0x42, "vgetexp", X86fgetexpRnd> , EVEX;
5586
5587 multiclass avx512_sqrt_packed_round<bits<8> opc, string OpcodeStr,
5588                               SDNode OpNodeRnd, X86VectorVTInfo _>{
5589   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5590                          (ins _.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc",
5591                          (_.VT (OpNodeRnd _.RC:$src, (i32 imm:$rc)))>,
5592                          EVEX, EVEX_B, EVEX_RC;
5593 }
5594
5595 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr,
5596                               SDNode OpNode, X86VectorVTInfo _>{
5597   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
5598                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
5599                          (_.FloatVT (OpNode _.RC:$src))>, EVEX;
5600   let mayLoad = 1 in {
5601     defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5602                            (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
5603                            (OpNode (_.FloatVT
5604                              (bitconvert (_.LdFrag addr:$src))))>, EVEX;
5605
5606     defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
5607                             (ins _.ScalarMemOp:$src), OpcodeStr,
5608                             "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
5609                             (OpNode (_.FloatVT
5610                               (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
5611                             EVEX, EVEX_B;
5612   }
5613 }
5614
5615 multiclass avx512_sqrt_packed_all<bits<8> opc, string OpcodeStr,
5616                                   SDNode OpNode> {
5617   defm PSZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
5618                                 v16f32_info>,
5619                                 EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
5620   defm PDZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
5621                                 v8f64_info>,
5622                                 EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5623   // Define only if AVX512VL feature is present.
5624   let Predicates = [HasVLX] in {
5625     defm PSZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
5626                                      OpNode, v4f32x_info>,
5627                                      EVEX_V128, PS, EVEX_CD8<32, CD8VF>;
5628     defm PSZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
5629                                      OpNode, v8f32x_info>,
5630                                      EVEX_V256, PS, EVEX_CD8<32, CD8VF>;
5631     defm PDZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
5632                                      OpNode, v2f64x_info>,
5633                                      EVEX_V128, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5634     defm PDZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
5635                                      OpNode, v4f64x_info>,
5636                                      EVEX_V256, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5637   }
5638 }
5639
5640 multiclass avx512_sqrt_packed_all_round<bits<8> opc, string OpcodeStr,
5641                                           SDNode OpNodeRnd> {
5642   defm PSZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "ps"), OpNodeRnd,
5643                                 v16f32_info>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
5644   defm PDZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "pd"), OpNodeRnd,
5645                                 v8f64_info>, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
5646 }
5647
5648 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
5649                               string SUFF, SDNode OpNode, SDNode OpNodeRnd> {
5650
5651   defm r_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5652                          (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
5653                          "$src2, $src1", "$src1, $src2",
5654                          (OpNodeRnd (_.VT _.RC:$src1),
5655                                     (_.VT _.RC:$src2),
5656                                     (i32 FROUND_CURRENT))>;
5657   let mayLoad = 1 in
5658     defm m_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5659                          (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
5660                          "$src2, $src1", "$src1, $src2",
5661                          (OpNodeRnd (_.VT _.RC:$src1),
5662                                     (_.VT (scalar_to_vector
5663                                               (_.ScalarLdFrag addr:$src2))),
5664                                     (i32 FROUND_CURRENT))>;
5665
5666   defm rb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5667                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
5668                          "$rc, $src2, $src1", "$src1, $src2, $rc",
5669                          (OpNodeRnd (_.VT _.RC:$src1),
5670                                      (_.VT _.RC:$src2),
5671                                      (i32 imm:$rc))>,
5672                          EVEX_B, EVEX_RC;
5673
5674   let isCodeGenOnly = 1 in {
5675     def r : SI<opc, MRMSrcReg, (outs _.FRC:$dst),
5676                (ins _.FRC:$src1, _.FRC:$src2),
5677                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
5678
5679     let mayLoad = 1 in
5680       def m : SI<opc, MRMSrcMem, (outs _.FRC:$dst),
5681                  (ins _.FRC:$src1, _.ScalarMemOp:$src2),
5682                  OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
5683   }
5684
5685   def : Pat<(_.EltVT (OpNode _.FRC:$src)),
5686             (!cast<Instruction>(NAME#SUFF#Zr)
5687                 (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>;
5688
5689   def : Pat<(_.EltVT (OpNode (load addr:$src))),
5690             (!cast<Instruction>(NAME#SUFF#Zm)
5691                 (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[OptForSize]>;
5692 }
5693
5694 multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
5695   defm SSZ : avx512_sqrt_scalar<opc, OpcodeStr#"ss", f32x_info, "SS", fsqrt,
5696                         X86fsqrtRnds>, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS;
5697   defm SDZ : avx512_sqrt_scalar<opc, OpcodeStr#"sd", f64x_info, "SD", fsqrt,
5698                         X86fsqrtRnds>, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W;
5699 }
5700
5701 defm VSQRT   : avx512_sqrt_packed_all<0x51, "vsqrt", fsqrt>,
5702                avx512_sqrt_packed_all_round<0x51, "vsqrt", X86fsqrtRnd>;
5703
5704 defm VSQRT   : avx512_sqrt_scalar_all<0x51, "vsqrt">, VEX_LIG;
5705
5706 let Predicates = [HasAVX512] in {
5707   def : Pat<(f32 (X86frsqrt FR32X:$src)),
5708             (COPY_TO_REGCLASS (VRSQRT14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>;
5709   def : Pat<(f32 (X86frsqrt (load addr:$src))),
5710             (COPY_TO_REGCLASS (VRSQRT14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
5711             Requires<[OptForSize]>;
5712   def : Pat<(f32 (X86frcp FR32X:$src)),
5713             (COPY_TO_REGCLASS (VRCP14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X )>;
5714   def : Pat<(f32 (X86frcp (load addr:$src))),
5715             (COPY_TO_REGCLASS (VRCP14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
5716             Requires<[OptForSize]>;
5717 }
5718
5719 multiclass
5720 avx512_rndscale_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
5721
5722   let ExeDomain = _.ExeDomain in {
5723   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5724                            (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
5725                            "$src3, $src2, $src1", "$src1, $src2, $src3",
5726                            (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5727                             (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
5728
5729   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5730                          (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
5731                          "$src3, {sae}, $src2, $src1", "$src1, $src2, {sae}, $src3",
5732                          (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
5733                          (i32 imm:$src3), (i32 FROUND_NO_EXC)))>, EVEX_B;
5734
5735   let mayLoad = 1 in
5736   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5737                          (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3), OpcodeStr,
5738                          "$src3, $src2, $src1", "$src1, $src2, $src3",
5739                          (_.VT (X86RndScales (_.VT _.RC:$src1),
5740                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
5741                           (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
5742   }
5743   let Predicates = [HasAVX512] in {
5744   def : Pat<(ffloor _.FRC:$src), (COPY_TO_REGCLASS
5745              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5746              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x1))), _.FRC)>;
5747   def : Pat<(fceil _.FRC:$src), (COPY_TO_REGCLASS
5748              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5749              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x2))), _.FRC)>;
5750   def : Pat<(ftrunc _.FRC:$src), (COPY_TO_REGCLASS
5751              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5752              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x3))), _.FRC)>;
5753   def : Pat<(frint _.FRC:$src), (COPY_TO_REGCLASS
5754              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5755              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x4))), _.FRC)>;
5756   def : Pat<(fnearbyint _.FRC:$src), (COPY_TO_REGCLASS
5757              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
5758              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0xc))), _.FRC)>;
5759
5760   def : Pat<(ffloor (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5761              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5762              addr:$src, (i32 0x1))), _.FRC)>;
5763   def : Pat<(fceil (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5764              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5765              addr:$src, (i32 0x2))), _.FRC)>;
5766   def : Pat<(ftrunc (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5767              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5768              addr:$src, (i32 0x3))), _.FRC)>;
5769   def : Pat<(frint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5770              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5771              addr:$src, (i32 0x4))), _.FRC)>;
5772   def : Pat<(fnearbyint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
5773              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
5774              addr:$src, (i32 0xc))), _.FRC)>;
5775   }
5776 }
5777
5778 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", f32x_info>,
5779                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VT1>;
5780
5781 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", f64x_info>, VEX_W,
5782                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VT1>;
5783
5784 //-------------------------------------------------
5785 // Integer truncate and extend operations
5786 //-------------------------------------------------
5787
5788 multiclass avx512_trunc_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5789                               X86VectorVTInfo SrcInfo, X86VectorVTInfo DestInfo,
5790                               X86MemOperand x86memop> {
5791
5792   defm rr  : AVX512_maskable<opc, MRMDestReg, DestInfo, (outs DestInfo.RC:$dst),
5793                       (ins SrcInfo.RC:$src1), OpcodeStr ,"$src1", "$src1",
5794                       (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1)))>,
5795                        EVEX, T8XS;
5796
5797   // for intrinsic patter match
5798   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5799                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5800                            undef)),
5801             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
5802                                       SrcInfo.RC:$src1)>;
5803
5804   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5805                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5806                            DestInfo.ImmAllZerosV)),
5807             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
5808                                       SrcInfo.RC:$src1)>;
5809
5810   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
5811                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
5812                            DestInfo.RC:$src0)),
5813             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrk) DestInfo.RC:$src0,
5814                                       DestInfo.KRCWM:$mask ,
5815                                       SrcInfo.RC:$src1)>;
5816
5817   let mayStore = 1 in {
5818     def mr : AVX512XS8I<opc, MRMDestMem, (outs),
5819                (ins x86memop:$dst, SrcInfo.RC:$src),
5820                OpcodeStr # "\t{$src, $dst |$dst, $src}",
5821                []>, EVEX;
5822
5823     def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
5824                (ins x86memop:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src),
5825                OpcodeStr # "\t{$src, $dst {${mask}} |$dst {${mask}}, $src}",
5826                []>, EVEX, EVEX_K;
5827   }//mayStore = 1
5828 }
5829
5830 multiclass avx512_trunc_mr_lowering<X86VectorVTInfo SrcInfo,
5831                                     X86VectorVTInfo DestInfo,
5832                                     PatFrag truncFrag, PatFrag mtruncFrag > {
5833
5834   def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst),
5835             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr)
5836                                     addr:$dst, SrcInfo.RC:$src)>;
5837
5838   def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask,
5839                                                (SrcInfo.VT SrcInfo.RC:$src)),
5840             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk)
5841                             addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>;
5842 }
5843
5844 multiclass avx512_trunc_sat_mr_lowering<X86VectorVTInfo SrcInfo,
5845                                         X86VectorVTInfo DestInfo, string sat > {
5846
5847   def: Pat<(!cast<Intrinsic>("int_x86_avx512_mask_pmov"#sat#"_"#SrcInfo.Suffix#
5848                                DestInfo.Suffix#"_mem_"#SrcInfo.Size)
5849                   addr:$ptr, (SrcInfo.VT SrcInfo.RC:$src), SrcInfo.MRC:$mask),
5850            (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk) addr:$ptr,
5851                     (COPY_TO_REGCLASS SrcInfo.MRC:$mask, SrcInfo.KRCWM),
5852                     (SrcInfo.VT SrcInfo.RC:$src))>;
5853
5854   def: Pat<(!cast<Intrinsic>("int_x86_avx512_mask_pmov"#sat#"_"#SrcInfo.Suffix#
5855                                DestInfo.Suffix#"_mem_"#SrcInfo.Size)
5856                   addr:$ptr, (SrcInfo.VT SrcInfo.RC:$src), -1),
5857            (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr) addr:$ptr,
5858                     (SrcInfo.VT SrcInfo.RC:$src))>;
5859 }
5860
5861 multiclass avx512_trunc<bits<8> opc, string OpcodeStr, SDNode OpNode,
5862          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
5863          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
5864          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
5865          X86MemOperand x86memopZ, PatFrag truncFrag, PatFrag mtruncFrag,
5866                                                      Predicate prd = HasAVX512>{
5867
5868   let Predicates = [HasVLX, prd] in {
5869     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
5870                              DestInfoZ128, x86memopZ128>,
5871                 avx512_trunc_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
5872                              truncFrag, mtruncFrag>, EVEX_V128;
5873
5874     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
5875                              DestInfoZ256, x86memopZ256>,
5876                 avx512_trunc_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
5877                              truncFrag, mtruncFrag>, EVEX_V256;
5878   }
5879   let Predicates = [prd] in
5880     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
5881                              DestInfoZ, x86memopZ>,
5882                 avx512_trunc_mr_lowering<VTSrcInfo.info512, DestInfoZ,
5883                              truncFrag, mtruncFrag>, EVEX_V512;
5884 }
5885
5886 multiclass avx512_trunc_sat<bits<8> opc, string OpcodeStr, SDNode OpNode,
5887          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
5888          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
5889          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
5890          X86MemOperand x86memopZ, string sat, Predicate prd = HasAVX512>{
5891
5892   let Predicates = [HasVLX, prd] in {
5893     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
5894                              DestInfoZ128, x86memopZ128>,
5895                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
5896                              sat>, EVEX_V128;
5897
5898     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
5899                              DestInfoZ256, x86memopZ256>,
5900                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
5901                              sat>, EVEX_V256;
5902   }
5903   let Predicates = [prd] in
5904     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
5905                              DestInfoZ, x86memopZ>,
5906                 avx512_trunc_sat_mr_lowering<VTSrcInfo.info512, DestInfoZ,
5907                              sat>, EVEX_V512;
5908 }
5909
5910 multiclass avx512_trunc_qb<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5911   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5912                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
5913                truncstorevi8, masked_truncstorevi8>, EVEX_CD8<8, CD8VO>;
5914 }
5915 multiclass avx512_trunc_sat_qb<bits<8> opc, string sat, SDNode OpNode> {
5916   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qb", OpNode, avx512vl_i64_info,
5917                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
5918                sat>, EVEX_CD8<8, CD8VO>;
5919 }
5920
5921 multiclass avx512_trunc_qw<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5922   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5923                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
5924                truncstorevi16, masked_truncstorevi16>, EVEX_CD8<16, CD8VQ>;
5925 }
5926 multiclass avx512_trunc_sat_qw<bits<8> opc, string sat, SDNode OpNode> {
5927   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qw", OpNode, avx512vl_i64_info,
5928                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
5929                sat>, EVEX_CD8<16, CD8VQ>;
5930 }
5931
5932 multiclass avx512_trunc_qd<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5933   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
5934                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
5935                truncstorevi32, masked_truncstorevi32>, EVEX_CD8<32, CD8VH>;
5936 }
5937 multiclass avx512_trunc_sat_qd<bits<8> opc, string sat, SDNode OpNode> {
5938   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"qd", OpNode, avx512vl_i64_info,
5939                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
5940                sat>, EVEX_CD8<32, CD8VH>;
5941 }
5942
5943 multiclass avx512_trunc_db<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5944   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
5945                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
5946                truncstorevi8, masked_truncstorevi8>, EVEX_CD8<8, CD8VQ>;
5947 }
5948 multiclass avx512_trunc_sat_db<bits<8> opc, string sat, SDNode OpNode> {
5949   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"db", OpNode, avx512vl_i32_info,
5950                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
5951                sat>, EVEX_CD8<8, CD8VQ>;
5952 }
5953
5954 multiclass avx512_trunc_dw<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5955   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
5956               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
5957               truncstorevi16, masked_truncstorevi16>, EVEX_CD8<16, CD8VH>;
5958 }
5959 multiclass avx512_trunc_sat_dw<bits<8> opc, string sat, SDNode OpNode> {
5960   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"dw", OpNode, avx512vl_i32_info,
5961               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
5962               sat>, EVEX_CD8<16, CD8VH>;
5963 }
5964
5965 multiclass avx512_trunc_wb<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5966   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i16_info,
5967               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
5968               truncstorevi8, masked_truncstorevi8,HasBWI>, EVEX_CD8<16, CD8VH>;
5969 }
5970 multiclass avx512_trunc_sat_wb<bits<8> opc, string sat, SDNode OpNode> {
5971   defm NAME: avx512_trunc_sat<opc, "vpmov"##sat##"wb", OpNode, avx512vl_i16_info,
5972               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
5973               sat, HasBWI>, EVEX_CD8<16, CD8VH>;
5974 }
5975
5976 defm VPMOVQB    : avx512_trunc_qb<0x32, "vpmovqb", X86vtrunc>;
5977 defm VPMOVSQB   : avx512_trunc_sat_qb<0x22, "s",   X86vtruncs>;
5978 defm VPMOVUSQB  : avx512_trunc_sat_qb<0x12, "us",  X86vtruncus>;
5979
5980 defm VPMOVQW    : avx512_trunc_qw<0x34, "vpmovqw", X86vtrunc>;
5981 defm VPMOVSQW   : avx512_trunc_sat_qw<0x24, "s",   X86vtruncs>;
5982 defm VPMOVUSQW  : avx512_trunc_sat_qw<0x14, "us",  X86vtruncus>;
5983
5984 defm VPMOVQD    : avx512_trunc_qd<0x35, "vpmovqd", X86vtrunc>;
5985 defm VPMOVSQD   : avx512_trunc_sat_qd<0x25, "s",   X86vtruncs>;
5986 defm VPMOVUSQD  : avx512_trunc_sat_qd<0x15, "us",  X86vtruncus>;
5987
5988 defm VPMOVDB    : avx512_trunc_db<0x31, "vpmovdb", X86vtrunc>;
5989 defm VPMOVSDB   : avx512_trunc_sat_db<0x21, "s",   X86vtruncs>;
5990 defm VPMOVUSDB  : avx512_trunc_sat_db<0x11, "us",  X86vtruncus>;
5991
5992 defm VPMOVDW    : avx512_trunc_dw<0x33, "vpmovdw", X86vtrunc>;
5993 defm VPMOVSDW   : avx512_trunc_sat_dw<0x23, "s",   X86vtruncs>;
5994 defm VPMOVUSDW  : avx512_trunc_sat_dw<0x13, "us",  X86vtruncus>;
5995
5996 defm VPMOVWB    : avx512_trunc_wb<0x30, "vpmovwb", X86vtrunc>;
5997 defm VPMOVSWB   : avx512_trunc_sat_wb<0x20, "s",   X86vtruncs>;
5998 defm VPMOVUSWB  : avx512_trunc_sat_wb<0x10, "us",  X86vtruncus>;
5999
6000 multiclass avx512_extend_common<bits<8> opc, string OpcodeStr,
6001                   X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo,
6002                   X86MemOperand x86memop, PatFrag LdFrag, SDNode OpNode>{
6003
6004   defm rr   : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
6005                     (ins SrcInfo.RC:$src), OpcodeStr ,"$src", "$src",
6006                     (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src)))>,
6007                   EVEX;
6008
6009   let mayLoad = 1 in {
6010     defm rm : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
6011                     (ins x86memop:$src), OpcodeStr ,"$src", "$src",
6012                     (DestInfo.VT (LdFrag addr:$src))>,
6013                   EVEX;
6014   }
6015 }
6016
6017 multiclass avx512_extend_BW<bits<8> opc, string OpcodeStr, SDNode OpNode,
6018           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
6019   let Predicates = [HasVLX, HasBWI] in {
6020     defm Z128:  avx512_extend_common<opc, OpcodeStr, v8i16x_info,
6021                     v16i8x_info, i64mem, LdFrag, OpNode>,
6022                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V128;
6023
6024     defm Z256:  avx512_extend_common<opc, OpcodeStr, v16i16x_info,
6025                     v16i8x_info, i128mem, LdFrag, OpNode>,
6026                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V256;
6027   }
6028   let Predicates = [HasBWI] in {
6029     defm Z   :  avx512_extend_common<opc, OpcodeStr, v32i16_info,
6030                     v32i8x_info, i256mem, LdFrag, OpNode>,
6031                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V512;
6032   }
6033 }
6034
6035 multiclass avx512_extend_BD<bits<8> opc, string OpcodeStr, SDNode OpNode,
6036           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
6037   let Predicates = [HasVLX, HasAVX512] in {
6038     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
6039                    v16i8x_info, i32mem, LdFrag, OpNode>,
6040                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V128;
6041
6042     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
6043                    v16i8x_info, i64mem, LdFrag, OpNode>,
6044                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V256;
6045   }
6046   let Predicates = [HasAVX512] in {
6047     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
6048                    v16i8x_info, i128mem, LdFrag, OpNode>,
6049                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V512;
6050   }
6051 }
6052
6053 multiclass avx512_extend_BQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6054           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
6055   let Predicates = [HasVLX, HasAVX512] in {
6056     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6057                    v16i8x_info, i16mem, LdFrag, OpNode>,
6058                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V128;
6059
6060     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6061                    v16i8x_info, i32mem, LdFrag, OpNode>,
6062                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V256;
6063   }
6064   let Predicates = [HasAVX512] in {
6065     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6066                    v16i8x_info, i64mem, LdFrag, OpNode>,
6067                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V512;
6068   }
6069 }
6070
6071 multiclass avx512_extend_WD<bits<8> opc, string OpcodeStr, SDNode OpNode,
6072          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
6073   let Predicates = [HasVLX, HasAVX512] in {
6074     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
6075                    v8i16x_info, i64mem, LdFrag, OpNode>,
6076                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V128;
6077
6078     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
6079                    v8i16x_info, i128mem, LdFrag, OpNode>,
6080                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V256;
6081   }
6082   let Predicates = [HasAVX512] in {
6083     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
6084                    v16i16x_info, i256mem, LdFrag, OpNode>,
6085                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V512;
6086   }
6087 }
6088
6089 multiclass avx512_extend_WQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6090          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
6091   let Predicates = [HasVLX, HasAVX512] in {
6092     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6093                    v8i16x_info, i32mem, LdFrag, OpNode>,
6094                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V128;
6095
6096     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6097                    v8i16x_info, i64mem, LdFrag, OpNode>,
6098                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V256;
6099   }
6100   let Predicates = [HasAVX512] in {
6101     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6102                    v8i16x_info, i128mem, LdFrag, OpNode>,
6103                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V512;
6104   }
6105 }
6106
6107 multiclass avx512_extend_DQ<bits<8> opc, string OpcodeStr, SDNode OpNode,
6108          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi32")> {
6109
6110   let Predicates = [HasVLX, HasAVX512] in {
6111     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
6112                    v4i32x_info, i64mem, LdFrag, OpNode>,
6113                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V128;
6114
6115     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
6116                    v4i32x_info, i128mem, LdFrag, OpNode>,
6117                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V256;
6118   }
6119   let Predicates = [HasAVX512] in {
6120     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
6121                    v8i32x_info, i256mem, LdFrag, OpNode>,
6122                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V512;
6123   }
6124 }
6125
6126 defm VPMOVZXBW : avx512_extend_BW<0x30, "vpmovzxbw", X86vzext, "z">;
6127 defm VPMOVZXBD : avx512_extend_BD<0x31, "vpmovzxbd", X86vzext, "z">;
6128 defm VPMOVZXBQ : avx512_extend_BQ<0x32, "vpmovzxbq", X86vzext, "z">;
6129 defm VPMOVZXWD : avx512_extend_WD<0x33, "vpmovzxwd", X86vzext, "z">;
6130 defm VPMOVZXWQ : avx512_extend_WQ<0x34, "vpmovzxwq", X86vzext, "z">;
6131 defm VPMOVZXDQ : avx512_extend_DQ<0x35, "vpmovzxdq", X86vzext, "z">;
6132
6133
6134 defm VPMOVSXBW: avx512_extend_BW<0x20, "vpmovsxbw", X86vsext, "s">;
6135 defm VPMOVSXBD: avx512_extend_BD<0x21, "vpmovsxbd", X86vsext, "s">;
6136 defm VPMOVSXBQ: avx512_extend_BQ<0x22, "vpmovsxbq", X86vsext, "s">;
6137 defm VPMOVSXWD: avx512_extend_WD<0x23, "vpmovsxwd", X86vsext, "s">;
6138 defm VPMOVSXWQ: avx512_extend_WQ<0x24, "vpmovsxwq", X86vsext, "s">;
6139 defm VPMOVSXDQ: avx512_extend_DQ<0x25, "vpmovsxdq", X86vsext, "s">;
6140
6141 //===----------------------------------------------------------------------===//
6142 // GATHER - SCATTER Operations
6143
6144 multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6145                          X86MemOperand memop, PatFrag GatherNode> {
6146   let Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb",
6147       ExeDomain = _.ExeDomain in
6148   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),
6149             (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),
6150             !strconcat(OpcodeStr#_.Suffix,
6151             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
6152             [(set _.RC:$dst, _.KRCWM:$mask_wb,
6153               (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,
6154                      vectoraddr:$src2))]>, EVEX, EVEX_K,
6155              EVEX_CD8<_.EltSize, CD8VT1>;
6156 }
6157
6158 multiclass avx512_gather_q_pd<bits<8> dopc, bits<8> qopc,
6159                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6160   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512,
6161                                       vy32xmem, mgatherv8i32>, EVEX_V512, VEX_W;
6162   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info512,
6163                                       vz64mem,  mgatherv8i64>, EVEX_V512, VEX_W;
6164 let Predicates = [HasVLX] in {
6165   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
6166                               vx32xmem, mgatherv4i32>, EVEX_V256, VEX_W;
6167   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info256,
6168                               vy64xmem, mgatherv4i64>, EVEX_V256, VEX_W;
6169   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
6170                               vx32xmem, mgatherv4i32>, EVEX_V128, VEX_W;
6171   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6172                               vx64xmem, mgatherv2i64>, EVEX_V128, VEX_W;
6173 }
6174 }
6175
6176 multiclass avx512_gather_d_ps<bits<8> dopc, bits<8> qopc,
6177                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6178   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512, vz32mem,
6179                                        mgatherv16i32>, EVEX_V512;
6180   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info256, vz64mem,
6181                                        mgatherv8i64>, EVEX_V512;
6182 let Predicates = [HasVLX] in {
6183   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
6184                                           vy32xmem, mgatherv8i32>, EVEX_V256;
6185   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6186                                           vy64xmem, mgatherv4i64>, EVEX_V256;
6187   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
6188                                           vx32xmem, mgatherv4i32>, EVEX_V128;
6189   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
6190                                           vx64xmem, mgatherv2i64>, EVEX_V128;
6191 }
6192 }
6193
6194
6195 defm VGATHER : avx512_gather_q_pd<0x92, 0x93, avx512vl_f64_info, "vgather", "PD">,
6196                avx512_gather_d_ps<0x92, 0x93, avx512vl_f32_info, "vgather", "PS">;
6197
6198 defm VPGATHER : avx512_gather_q_pd<0x90, 0x91, avx512vl_i64_info, "vpgather", "Q">,
6199                 avx512_gather_d_ps<0x90, 0x91, avx512vl_i32_info, "vpgather", "D">;
6200
6201 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6202                           X86MemOperand memop, PatFrag ScatterNode> {
6203
6204 let mayStore = 1, Constraints = "$mask = $mask_wb", ExeDomain = _.ExeDomain in
6205
6206   def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),
6207             (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),
6208             !strconcat(OpcodeStr#_.Suffix,
6209             "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
6210             [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),
6211                                      _.KRCWM:$mask,  vectoraddr:$dst))]>,
6212             EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
6213 }
6214
6215 multiclass avx512_scatter_q_pd<bits<8> dopc, bits<8> qopc,
6216                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6217   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512,
6218                                       vy32xmem, mscatterv8i32>, EVEX_V512, VEX_W;
6219   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info512,
6220                                       vz64mem,  mscatterv8i64>, EVEX_V512, VEX_W;
6221 let Predicates = [HasVLX] in {
6222   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
6223                               vx32xmem, mscatterv4i32>, EVEX_V256, VEX_W;
6224   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info256,
6225                               vy64xmem, mscatterv4i64>, EVEX_V256, VEX_W;
6226   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
6227                               vx32xmem, mscatterv4i32>, EVEX_V128, VEX_W;
6228   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6229                               vx64xmem, mscatterv2i64>, EVEX_V128, VEX_W;
6230 }
6231 }
6232
6233 multiclass avx512_scatter_d_ps<bits<8> dopc, bits<8> qopc,
6234                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
6235   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512, vz32mem,
6236                                        mscatterv16i32>, EVEX_V512;
6237   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info256, vz64mem,
6238                                        mscatterv8i64>, EVEX_V512;
6239 let Predicates = [HasVLX] in {
6240   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
6241                                           vy32xmem, mscatterv8i32>, EVEX_V256;
6242   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6243                                           vy64xmem, mscatterv4i64>, EVEX_V256;
6244   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
6245                                           vx32xmem, mscatterv4i32>, EVEX_V128;
6246   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
6247                                           vx64xmem, mscatterv2i64>, EVEX_V128;
6248 }
6249 }
6250
6251 defm VSCATTER : avx512_scatter_q_pd<0xA2, 0xA3, avx512vl_f64_info, "vscatter", "PD">,
6252                avx512_scatter_d_ps<0xA2, 0xA3, avx512vl_f32_info, "vscatter", "PS">;
6253
6254 defm VPSCATTER : avx512_scatter_q_pd<0xA0, 0xA1, avx512vl_i64_info, "vpscatter", "Q">,
6255                 avx512_scatter_d_ps<0xA0, 0xA1, avx512vl_i32_info, "vpscatter", "D">;
6256
6257 // prefetch
6258 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
6259                        RegisterClass KRC, X86MemOperand memop> {
6260   let Predicates = [HasPFI], hasSideEffects = 1 in
6261   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
6262             !strconcat(OpcodeStr, "\t{$src {${mask}}|{${mask}}, $src}"),
6263             []>, EVEX, EVEX_K;
6264 }
6265
6266 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
6267                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6268
6269 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
6270                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6271
6272 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
6273                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6274
6275 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
6276                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6277
6278 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
6279                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6280
6281 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
6282                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6283
6284 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
6285                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6286
6287 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
6288                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6289
6290 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
6291                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6292
6293 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
6294                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6295
6296 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
6297                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6298
6299 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
6300                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6301
6302 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
6303                      VK16WM, vz32mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
6304
6305 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
6306                      VK8WM, vz64mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
6307
6308 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
6309                      VK8WM, vy32mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
6310
6311 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
6312                      VK8WM, vz64mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
6313
6314 // Helper fragments to match sext vXi1 to vXiY.
6315 def v16i1sextv16i32  : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
6316 def v8i1sextv8i64  : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
6317
6318 def : Pat<(store (i1 -1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
6319 def : Pat<(store (i1  1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
6320 def : Pat<(store (i1  0), addr:$dst), (MOV8mi addr:$dst, (i8 0))>;
6321
6322 def : Pat<(store VK1:$src, addr:$dst),
6323           (MOV8mr addr:$dst,
6324            (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)),
6325             sub_8bit))>, Requires<[HasAVX512, NoDQI]>;
6326
6327 def : Pat<(store VK8:$src, addr:$dst),
6328           (MOV8mr addr:$dst,
6329            (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
6330             sub_8bit))>, Requires<[HasAVX512, NoDQI]>;
6331
6332 def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
6333                            (truncstore node:$val, node:$ptr), [{
6334   return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
6335 }]>;
6336
6337 def : Pat<(truncstorei1 GR8:$src, addr:$dst),
6338           (MOV8mr addr:$dst, GR8:$src)>;
6339
6340 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
6341 def rr : AVX512XS8I<opc, MRMSrcReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
6342                   !strconcat(OpcodeStr##Vec.Suffix, "\t{$src, $dst|$dst, $src}"),
6343                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
6344 }
6345
6346 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
6347                                  string OpcodeStr, Predicate prd> {
6348 let Predicates = [prd] in
6349   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6350
6351   let Predicates = [prd, HasVLX] in {
6352     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6353     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6354   }
6355 }
6356
6357 multiclass avx512_convert_mask_to_vector<string OpcodeStr> {
6358   defm NAME##B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info,  OpcodeStr,
6359                                        HasBWI>;
6360   defm NAME##W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, OpcodeStr,
6361                                        HasBWI>, VEX_W;
6362   defm NAME##D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, OpcodeStr,
6363                                        HasDQI>;
6364   defm NAME##Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, OpcodeStr,
6365                                        HasDQI>, VEX_W;
6366 }
6367
6368 defm VPMOVM2 : avx512_convert_mask_to_vector<"vpmovm2">;
6369
6370 multiclass convert_vector_to_mask_common<bits<8> opc, X86VectorVTInfo _, string OpcodeStr > {
6371 def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.KRC:$dst), (ins _.RC:$src),
6372                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6373                   [(set _.KRC:$dst, (trunc (_.VT _.RC:$src)))]>, EVEX;
6374 }
6375
6376 multiclass avx512_convert_vector_to_mask<bits<8> opc, string OpcodeStr,
6377                         AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6378 let Predicates = [prd] in
6379   defm Z : convert_vector_to_mask_common <opc, VTInfo.info512, OpcodeStr>,
6380    EVEX_V512;
6381
6382   let Predicates = [prd, HasVLX] in {
6383     defm Z256 : convert_vector_to_mask_common<opc, VTInfo.info256, OpcodeStr>,
6384      EVEX_V256;
6385     defm Z128 : convert_vector_to_mask_common<opc, VTInfo.info128, OpcodeStr>,
6386      EVEX_V128;
6387   }
6388 }
6389
6390 defm VPMOVB2M : avx512_convert_vector_to_mask<0x29, "vpmovb2m",
6391                                               avx512vl_i8_info, HasBWI>;
6392 defm VPMOVW2M : avx512_convert_vector_to_mask<0x29, "vpmovw2m",
6393                                               avx512vl_i16_info, HasBWI>, VEX_W;
6394 defm VPMOVD2M : avx512_convert_vector_to_mask<0x39, "vpmovd2m",
6395                                               avx512vl_i32_info, HasDQI>;
6396 defm VPMOVQ2M : avx512_convert_vector_to_mask<0x39, "vpmovq2m",
6397                                               avx512vl_i64_info, HasDQI>, VEX_W;
6398
6399 //===----------------------------------------------------------------------===//
6400 // AVX-512 - COMPRESS and EXPAND
6401 //
6402
6403 multiclass compress_by_vec_width<bits<8> opc, X86VectorVTInfo _,
6404                                  string OpcodeStr> {
6405   defm rr : AVX512_maskable<opc, MRMDestReg, _, (outs _.RC:$dst),
6406               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
6407               (_.VT (X86compress _.RC:$src1))>, AVX5128IBase;
6408
6409   let mayStore = 1 in {
6410   def mr : AVX5128I<opc, MRMDestMem, (outs),
6411               (ins _.MemOp:$dst, _.RC:$src),
6412               OpcodeStr # "\t{$src, $dst |$dst, $src}",
6413               []>, EVEX_CD8<_.EltSize, CD8VT1>;
6414
6415   def mrk : AVX5128I<opc, MRMDestMem, (outs),
6416               (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
6417               OpcodeStr # "\t{$src, $dst {${mask}} |$dst {${mask}}, $src}",
6418               [(store (_.VT (vselect _.KRCWM:$mask,
6419                              (_.VT (X86compress  _.RC:$src)), _.ImmAllZerosV)),
6420                 addr:$dst)]>,
6421               EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
6422   }
6423 }
6424
6425 multiclass compress_by_elt_width<bits<8> opc, string OpcodeStr,
6426                                  AVX512VLVectorVTInfo VTInfo> {
6427   defm Z : compress_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6428
6429   let Predicates = [HasVLX] in {
6430     defm Z256 : compress_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6431     defm Z128 : compress_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6432   }
6433 }
6434
6435 defm VPCOMPRESSD : compress_by_elt_width <0x8B, "vpcompressd", avx512vl_i32_info>,
6436                                          EVEX;
6437 defm VPCOMPRESSQ : compress_by_elt_width <0x8B, "vpcompressq", avx512vl_i64_info>,
6438                                          EVEX, VEX_W;
6439 defm VCOMPRESSPS : compress_by_elt_width <0x8A, "vcompressps", avx512vl_f32_info>,
6440                                          EVEX;
6441 defm VCOMPRESSPD : compress_by_elt_width <0x8A, "vcompresspd", avx512vl_f64_info>,
6442                                          EVEX, VEX_W;
6443
6444 // expand
6445 multiclass expand_by_vec_width<bits<8> opc, X86VectorVTInfo _,
6446                                  string OpcodeStr> {
6447   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6448               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
6449               (_.VT (X86expand _.RC:$src1))>, AVX5128IBase;
6450
6451   let mayLoad = 1 in
6452   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6453               (ins _.MemOp:$src1), OpcodeStr, "$src1", "$src1",
6454               (_.VT (X86expand (_.VT (bitconvert
6455                                       (_.LdFrag addr:$src1)))))>,
6456             AVX5128IBase, EVEX_CD8<_.EltSize, CD8VT1>;
6457 }
6458
6459 multiclass expand_by_elt_width<bits<8> opc, string OpcodeStr,
6460                                  AVX512VLVectorVTInfo VTInfo> {
6461   defm Z : expand_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
6462
6463   let Predicates = [HasVLX] in {
6464     defm Z256 : expand_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
6465     defm Z128 : expand_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
6466   }
6467 }
6468
6469 defm VPEXPANDD : expand_by_elt_width <0x89, "vpexpandd", avx512vl_i32_info>,
6470                                          EVEX;
6471 defm VPEXPANDQ : expand_by_elt_width <0x89, "vpexpandq", avx512vl_i64_info>,
6472                                          EVEX, VEX_W;
6473 defm VEXPANDPS : expand_by_elt_width <0x88, "vexpandps", avx512vl_f32_info>,
6474                                          EVEX;
6475 defm VEXPANDPD : expand_by_elt_width <0x88, "vexpandpd", avx512vl_f64_info>,
6476                                          EVEX, VEX_W;
6477
6478 //handle instruction  reg_vec1 = op(reg_vec,imm)
6479 //                               op(mem_vec,imm)
6480 //                               op(broadcast(eltVt),imm)
6481 //all instruction created with FROUND_CURRENT
6482 multiclass avx512_unary_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6483                                                             X86VectorVTInfo _>{
6484   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6485                       (ins _.RC:$src1, i32u8imm:$src2),
6486                       OpcodeStr##_.Suffix, "$src2, $src1", "$src2, $src2",
6487                       (OpNode (_.VT _.RC:$src1),
6488                               (i32 imm:$src2),
6489                               (i32 FROUND_CURRENT))>;
6490   let mayLoad = 1 in {
6491     defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6492                       (ins _.MemOp:$src1, i32u8imm:$src2),
6493                       OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
6494                       (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
6495                               (i32 imm:$src2),
6496                               (i32 FROUND_CURRENT))>;
6497     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6498                       (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
6499                       OpcodeStr##_.Suffix, "$src2, ${src1}"##_.BroadcastStr,
6500                       "${src1}"##_.BroadcastStr##", $src2",
6501                       (OpNode (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src1))),
6502                               (i32 imm:$src2),
6503                               (i32 FROUND_CURRENT))>, EVEX_B;
6504   }
6505 }
6506
6507 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6508 multiclass avx512_unary_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
6509                                              SDNode OpNode, X86VectorVTInfo _>{
6510   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6511                       (ins _.RC:$src1, i32u8imm:$src2),
6512                       OpcodeStr##_.Suffix, "$src2,{sae}, $src1",
6513                       "$src1, {sae}, $src2",
6514                       (OpNode (_.VT _.RC:$src1),
6515                               (i32 imm:$src2),
6516                               (i32 FROUND_NO_EXC))>, EVEX_B;
6517 }
6518
6519 multiclass avx512_common_unary_fp_sae_packed_imm<string OpcodeStr,
6520             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6521   let Predicates = [prd] in {
6522     defm Z    : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6523                 avx512_unary_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6524                                   EVEX_V512;
6525   }
6526   let Predicates = [prd, HasVLX] in {
6527     defm Z128 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
6528                                   EVEX_V128;
6529     defm Z256 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
6530                                   EVEX_V256;
6531   }
6532 }
6533
6534 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6535 //                               op(reg_vec2,mem_vec,imm)
6536 //                               op(reg_vec2,broadcast(eltVt),imm)
6537 //all instruction created with FROUND_CURRENT
6538 multiclass avx512_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6539                                                             X86VectorVTInfo _>{
6540   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6541                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6542                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6543                       (OpNode (_.VT _.RC:$src1),
6544                               (_.VT _.RC:$src2),
6545                               (i32 imm:$src3),
6546                               (i32 FROUND_CURRENT))>;
6547   let mayLoad = 1 in {
6548     defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6549                       (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
6550                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6551                       (OpNode (_.VT _.RC:$src1),
6552                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
6553                               (i32 imm:$src3),
6554                               (i32 FROUND_CURRENT))>;
6555     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6556                       (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
6557                       OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
6558                       "$src1, ${src2}"##_.BroadcastStr##", $src3",
6559                       (OpNode (_.VT _.RC:$src1),
6560                               (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
6561                               (i32 imm:$src3),
6562                               (i32 FROUND_CURRENT))>, EVEX_B;
6563   }
6564 }
6565
6566 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6567 //                               op(reg_vec2,mem_vec,imm)
6568 multiclass avx512_3Op_rm_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
6569                              X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo>{
6570
6571   defm rri : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
6572                   (ins SrcInfo.RC:$src1, SrcInfo.RC:$src2, u8imm:$src3),
6573                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6574                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
6575                                (SrcInfo.VT SrcInfo.RC:$src2),
6576                                (i8 imm:$src3)))>;
6577   let mayLoad = 1 in
6578     defm rmi : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
6579                   (ins SrcInfo.RC:$src1, SrcInfo.MemOp:$src2, u8imm:$src3),
6580                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6581                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
6582                                (SrcInfo.VT (bitconvert
6583                                                   (SrcInfo.LdFrag addr:$src2))),
6584                                (i8 imm:$src3)))>;
6585 }
6586
6587 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6588 //                               op(reg_vec2,mem_vec,imm)
6589 //                               op(reg_vec2,broadcast(eltVt),imm)
6590 multiclass avx512_3Op_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
6591                            X86VectorVTInfo _>:
6592   avx512_3Op_rm_imm8<opc, OpcodeStr, OpNode, _, _>{
6593
6594   let mayLoad = 1 in
6595     defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6596                       (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
6597                       OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
6598                       "$src1, ${src2}"##_.BroadcastStr##", $src3",
6599                       (OpNode (_.VT _.RC:$src1),
6600                               (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
6601                               (i8 imm:$src3))>, EVEX_B;
6602 }
6603
6604 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
6605 //                                      op(reg_vec2,mem_scalar,imm)
6606 //all instruction created with FROUND_CURRENT
6607 multiclass avx512_fp_scalar_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6608                                                            X86VectorVTInfo _> {
6609
6610   defm rri : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6611                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6612                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6613                       (OpNode (_.VT _.RC:$src1),
6614                               (_.VT _.RC:$src2),
6615                               (i32 imm:$src3),
6616                               (i32 FROUND_CURRENT))>;
6617   let mayLoad = 1 in {
6618     defm rmi : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6619                       (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
6620                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6621                       (OpNode (_.VT _.RC:$src1),
6622                               (_.VT (scalar_to_vector
6623                                         (_.ScalarLdFrag addr:$src2))),
6624                               (i32 imm:$src3),
6625                               (i32 FROUND_CURRENT))>;
6626
6627     let isAsmParserOnly = 1 in {
6628       defm rmi_alt :AVX512_maskable_in_asm<opc, MRMSrcMem, _, (outs _.FRC:$dst),
6629                       (ins _.FRC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
6630                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
6631                       []>;
6632     }
6633   }
6634 }
6635
6636 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6637 multiclass avx512_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
6638                                              SDNode OpNode, X86VectorVTInfo _>{
6639   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6640                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6641                       OpcodeStr, "$src3,{sae}, $src2, $src1",
6642                       "$src1, $src2,{sae}, $src3",
6643                       (OpNode (_.VT _.RC:$src1),
6644                               (_.VT _.RC:$src2),
6645                               (i32 imm:$src3),
6646                               (i32 FROUND_NO_EXC))>, EVEX_B;
6647 }
6648 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
6649 multiclass avx512_fp_sae_scalar_imm<bits<8> opc, string OpcodeStr,
6650                                              SDNode OpNode, X86VectorVTInfo _> {
6651   defm NAME#rrib : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6652                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
6653                       OpcodeStr, "$src3,{sae}, $src2, $src1",
6654                       "$src1, $src2,{sae}, $src3",
6655                       (OpNode (_.VT _.RC:$src1),
6656                               (_.VT _.RC:$src2),
6657                               (i32 imm:$src3),
6658                               (i32 FROUND_NO_EXC))>, EVEX_B;
6659 }
6660
6661 multiclass avx512_common_fp_sae_packed_imm<string OpcodeStr,
6662             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6663   let Predicates = [prd] in {
6664     defm Z    : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6665                 avx512_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
6666                                   EVEX_V512;
6667
6668   }
6669   let Predicates = [prd, HasVLX] in {
6670     defm Z128 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
6671                                   EVEX_V128;
6672     defm Z256 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
6673                                   EVEX_V256;
6674   }
6675 }
6676
6677 multiclass avx512_common_3Op_rm_imm8<bits<8> opc, SDNode OpNode, string OpStr,
6678                    AVX512VLVectorVTInfo DestInfo, AVX512VLVectorVTInfo SrcInfo>{
6679   let Predicates = [HasBWI] in {
6680     defm Z    : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info512,
6681                            SrcInfo.info512>, EVEX_V512, AVX512AIi8Base, EVEX_4V;
6682   }
6683   let Predicates = [HasBWI, HasVLX] in {
6684     defm Z128 : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info128,
6685                            SrcInfo.info128>, EVEX_V128, AVX512AIi8Base, EVEX_4V;
6686     defm Z256 : avx512_3Op_rm_imm8<opc, OpStr, OpNode,  DestInfo.info256,
6687                            SrcInfo.info256>, EVEX_V256, AVX512AIi8Base, EVEX_4V;
6688   }
6689 }
6690
6691 multiclass avx512_common_3Op_imm8<string OpcodeStr, AVX512VLVectorVTInfo _,
6692                                 bits<8> opc, SDNode OpNode>{
6693   let Predicates = [HasAVX512] in {
6694     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
6695   }
6696   let Predicates = [HasAVX512, HasVLX] in {
6697     defm Z128 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
6698     defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
6699   }
6700 }
6701
6702 multiclass avx512_common_fp_sae_scalar_imm<string OpcodeStr,
6703                   X86VectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
6704   let Predicates = [prd] in {
6705      defm Z128 : avx512_fp_scalar_imm<opc, OpcodeStr, OpNode, _>,
6706                  avx512_fp_sae_scalar_imm<opc, OpcodeStr, OpNode, _>;
6707   }
6708 }
6709
6710 multiclass avx512_common_unary_fp_sae_packed_imm_all<string OpcodeStr,
6711                     bits<8> opcPs, bits<8> opcPd, SDNode OpNode, Predicate prd>{
6712   defm PS : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f32_info,
6713                             opcPs, OpNode, prd>, EVEX_CD8<32, CD8VF>;
6714   defm PD : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f64_info,
6715                             opcPd, OpNode, prd>, EVEX_CD8<64, CD8VF>, VEX_W;
6716 }
6717
6718 defm VFIXUPIMMPD : avx512_common_fp_sae_packed_imm<"vfixupimmpd",
6719                               avx512vl_f64_info, 0x54, X86VFixupimm, HasAVX512>,
6720       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6721 defm VFIXUPIMMPS : avx512_common_fp_sae_packed_imm<"vfixupimmps",
6722                               avx512vl_f32_info, 0x54, X86VFixupimm, HasAVX512>,
6723       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6724
6725 defm VFIXUPIMMSD: avx512_common_fp_sae_scalar_imm<"vfixupimmsd", f64x_info,
6726                                                  0x55, X86VFixupimm, HasAVX512>,
6727       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6728 defm VFIXUPIMMSS: avx512_common_fp_sae_scalar_imm<"vfixupimmss", f32x_info,
6729                                                  0x55, X86VFixupimm, HasAVX512>,
6730       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6731
6732 defm VREDUCE   : avx512_common_unary_fp_sae_packed_imm_all<"vreduce", 0x56, 0x56,
6733                               X86VReduce, HasDQI>, AVX512AIi8Base, EVEX;
6734 defm VRNDSCALE : avx512_common_unary_fp_sae_packed_imm_all<"vrndscale", 0x08, 0x09,
6735                               X86VRndScale, HasAVX512>, AVX512AIi8Base, EVEX;
6736 defm VGETMANT : avx512_common_unary_fp_sae_packed_imm_all<"vgetmant", 0x26, 0x26,
6737                               X86VGetMant, HasAVX512>, AVX512AIi8Base, EVEX;
6738
6739
6740 defm VRANGEPD : avx512_common_fp_sae_packed_imm<"vrangepd", avx512vl_f64_info,
6741                                                        0x50, X86VRange, HasDQI>,
6742       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6743 defm VRANGEPS : avx512_common_fp_sae_packed_imm<"vrangeps", avx512vl_f32_info,
6744                                                        0x50, X86VRange, HasDQI>,
6745       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6746
6747 defm VRANGESD: avx512_common_fp_sae_scalar_imm<"vrangesd", f64x_info,
6748                                                  0x51, X86VRange, HasDQI>,
6749       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6750 defm VRANGESS: avx512_common_fp_sae_scalar_imm<"vrangess", f32x_info,
6751                                                  0x51, X86VRange, HasDQI>,
6752       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6753
6754 defm VREDUCESD: avx512_common_fp_sae_scalar_imm<"vreducesd", f64x_info,
6755                                                  0x57, X86Reduces, HasDQI>,
6756       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6757 defm VREDUCESS: avx512_common_fp_sae_scalar_imm<"vreducess", f32x_info,
6758                                                  0x57, X86Reduces, HasDQI>,
6759       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6760
6761 defm VGETMANTSD: avx512_common_fp_sae_scalar_imm<"vgetmantsd", f64x_info,
6762                                                  0x27, X86GetMants, HasAVX512>,
6763       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
6764 defm VGETMANTSS: avx512_common_fp_sae_scalar_imm<"vgetmantss", f32x_info,
6765                                                  0x27, X86GetMants, HasAVX512>,
6766       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
6767
6768 multiclass avx512_shuff_packed_128<string OpcodeStr, AVX512VLVectorVTInfo _,
6769                                        bits<8> opc, SDNode OpNode = X86Shuf128>{
6770   let Predicates = [HasAVX512] in {
6771     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
6772
6773   }
6774   let Predicates = [HasAVX512, HasVLX] in {
6775      defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
6776   }
6777 }
6778 let Predicates = [HasAVX512] in {
6779 def : Pat<(v16f32 (ffloor VR512:$src)),
6780           (VRNDSCALEPSZrri VR512:$src, (i32 0x1))>;
6781 def : Pat<(v16f32 (fnearbyint VR512:$src)),
6782           (VRNDSCALEPSZrri VR512:$src, (i32 0xC))>;
6783 def : Pat<(v16f32 (fceil VR512:$src)),
6784           (VRNDSCALEPSZrri VR512:$src, (i32 0x2))>;
6785 def : Pat<(v16f32 (frint VR512:$src)),
6786           (VRNDSCALEPSZrri VR512:$src, (i32 0x4))>;
6787 def : Pat<(v16f32 (ftrunc VR512:$src)),
6788           (VRNDSCALEPSZrri VR512:$src, (i32 0x3))>;
6789
6790 def : Pat<(v8f64 (ffloor VR512:$src)),
6791           (VRNDSCALEPDZrri VR512:$src, (i32 0x1))>;
6792 def : Pat<(v8f64 (fnearbyint VR512:$src)),
6793           (VRNDSCALEPDZrri VR512:$src, (i32 0xC))>;
6794 def : Pat<(v8f64 (fceil VR512:$src)),
6795           (VRNDSCALEPDZrri VR512:$src, (i32 0x2))>;
6796 def : Pat<(v8f64 (frint VR512:$src)),
6797           (VRNDSCALEPDZrri VR512:$src, (i32 0x4))>;
6798 def : Pat<(v8f64 (ftrunc VR512:$src)),
6799           (VRNDSCALEPDZrri VR512:$src, (i32 0x3))>;
6800 }
6801
6802 defm VSHUFF32X4 : avx512_shuff_packed_128<"vshuff32x4",avx512vl_f32_info, 0x23>,
6803       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6804 defm VSHUFF64X2 : avx512_shuff_packed_128<"vshuff64x2",avx512vl_f64_info, 0x23>,
6805       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6806 defm VSHUFI32X4 : avx512_shuff_packed_128<"vshufi32x4",avx512vl_i32_info, 0x43>,
6807       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
6808 defm VSHUFI64X2 : avx512_shuff_packed_128<"vshufi64x2",avx512vl_i64_info, 0x43>,
6809       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
6810
6811 multiclass avx512_valign<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
6812                                                 AVX512VLVectorVTInfo VTInfo_FP>{
6813   defm NAME:       avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0x03, X86VAlign>,
6814                            AVX512AIi8Base, EVEX_4V;
6815   let isCodeGenOnly = 1 in {
6816     defm NAME#_FP: avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0x03, X86VAlign>,
6817                            AVX512AIi8Base, EVEX_4V;
6818   }
6819 }
6820
6821 defm VALIGND: avx512_valign<"valignd", avx512vl_i32_info, avx512vl_f32_info>,
6822                                                   EVEX_CD8<32, CD8VF>;
6823 defm VALIGNQ: avx512_valign<"valignq", avx512vl_i64_info, avx512vl_f64_info>,
6824                                                   EVEX_CD8<64, CD8VF>, VEX_W;
6825
6826 multiclass avx512_vpalign_lowering<X86VectorVTInfo _ , list<Predicate> p>{
6827   let Predicates = p in
6828     def NAME#_.VTName#rri:
6829           Pat<(_.VT (X86PAlignr _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
6830               (!cast<Instruction>(NAME#_.ZSuffix#rri)
6831                     _.RC:$src1, _.RC:$src2, imm:$imm)>;
6832 }
6833
6834 multiclass avx512_vpalign_lowering_common<AVX512VLVectorVTInfo _>:
6835       avx512_vpalign_lowering<_.info512, [HasBWI]>,
6836       avx512_vpalign_lowering<_.info128, [HasBWI, HasVLX]>,
6837       avx512_vpalign_lowering<_.info256, [HasBWI, HasVLX]>;
6838
6839 defm VPALIGN:   avx512_common_3Op_rm_imm8<0x0F, X86PAlignr, "vpalignr" ,
6840                                           avx512vl_i8_info, avx512vl_i8_info>,
6841                 avx512_vpalign_lowering_common<avx512vl_i16_info>,
6842                 avx512_vpalign_lowering_common<avx512vl_i32_info>,
6843                 avx512_vpalign_lowering_common<avx512vl_f32_info>,
6844                 avx512_vpalign_lowering_common<avx512vl_i64_info>,
6845                 avx512_vpalign_lowering_common<avx512vl_f64_info>,
6846                 EVEX_CD8<8, CD8VF>;
6847
6848 defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw" ,
6849                     avx512vl_i16_info, avx512vl_i8_info>, EVEX_CD8<8, CD8VF>;
6850
6851 multiclass avx512_unary_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6852                            X86VectorVTInfo _> {
6853   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6854                     (ins _.RC:$src1), OpcodeStr##_.Suffix,
6855                     "$src1", "$src1",
6856                     (_.VT (OpNode _.RC:$src1))>, EVEX, AVX5128IBase;
6857
6858   let mayLoad = 1 in
6859     defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6860                     (ins _.MemOp:$src1), OpcodeStr##_.Suffix,
6861                     "$src1", "$src1",
6862                     (_.VT (OpNode (bitconvert (_.LdFrag addr:$src1))))>,
6863               EVEX, AVX5128IBase, EVEX_CD8<_.EltSize, CD8VF>;
6864 }
6865
6866 multiclass avx512_unary_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
6867                             X86VectorVTInfo _> :
6868            avx512_unary_rm<opc, OpcodeStr, OpNode, _> {
6869   let mayLoad = 1 in
6870     defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6871                     (ins _.ScalarMemOp:$src1), OpcodeStr##_.Suffix,
6872                     "${src1}"##_.BroadcastStr,
6873                     "${src1}"##_.BroadcastStr,
6874                     (_.VT (OpNode (X86VBroadcast
6875                                       (_.ScalarLdFrag addr:$src1))))>,
6876                EVEX, AVX5128IBase, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
6877 }
6878
6879 multiclass avx512_unary_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
6880                               AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6881   let Predicates = [prd] in
6882     defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
6883
6884   let Predicates = [prd, HasVLX] in {
6885     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
6886                               EVEX_V256;
6887     defm Z128 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info128>,
6888                               EVEX_V128;
6889   }
6890 }
6891
6892 multiclass avx512_unary_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
6893                                AVX512VLVectorVTInfo VTInfo, Predicate prd> {
6894   let Predicates = [prd] in
6895     defm Z : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
6896                               EVEX_V512;
6897
6898   let Predicates = [prd, HasVLX] in {
6899     defm Z256 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
6900                                  EVEX_V256;
6901     defm Z128 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
6902                                  EVEX_V128;
6903   }
6904 }
6905
6906 multiclass avx512_unary_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
6907                                  SDNode OpNode, Predicate prd> {
6908   defm Q : avx512_unary_rmb_vl<opc_q, OpcodeStr, OpNode, avx512vl_i64_info,
6909                                prd>, VEX_W;
6910   defm D : avx512_unary_rmb_vl<opc_d, OpcodeStr, OpNode, avx512vl_i32_info, prd>;
6911 }
6912
6913 multiclass avx512_unary_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
6914                                  SDNode OpNode, Predicate prd> {
6915   defm W : avx512_unary_rm_vl<opc_w, OpcodeStr, OpNode, avx512vl_i16_info, prd>;
6916   defm B : avx512_unary_rm_vl<opc_b, OpcodeStr, OpNode, avx512vl_i8_info, prd>;
6917 }
6918
6919 multiclass avx512_unary_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
6920                                   bits<8> opc_d, bits<8> opc_q,
6921                                   string OpcodeStr, SDNode OpNode> {
6922   defm NAME : avx512_unary_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
6923                                     HasAVX512>,
6924               avx512_unary_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
6925                                     HasBWI>;
6926 }
6927
6928 defm VPABS : avx512_unary_rm_vl_all<0x1C, 0x1D, 0x1E, 0x1F, "vpabs", X86Abs>;
6929
6930 def : Pat<(xor
6931           (bc_v16i32 (v16i1sextv16i32)),
6932           (bc_v16i32 (add (v16i32 VR512:$src), (v16i1sextv16i32)))),
6933           (VPABSDZrr VR512:$src)>;
6934 def : Pat<(xor
6935           (bc_v8i64 (v8i1sextv8i64)),
6936           (bc_v8i64 (add (v8i64 VR512:$src), (v8i1sextv8i64)))),
6937           (VPABSQZrr VR512:$src)>;
6938
6939 multiclass avx512_ctlz<bits<8> opc, string OpcodeStr, Predicate prd>{
6940
6941   defm NAME :          avx512_unary_rm_vl_dq<opc, opc, OpcodeStr, ctlz, prd>;
6942   let isCodeGenOnly = 1 in
6943     defm NAME#_UNDEF : avx512_unary_rm_vl_dq<opc, opc, OpcodeStr,
6944                                              ctlz_zero_undef, prd>;
6945 }
6946
6947 defm VPLZCNT    : avx512_ctlz<0x44, "vplzcnt", HasCDI>;
6948 defm VPCONFLICT : avx512_unary_rm_vl_dq<0xC4, 0xC4, "vpconflict", X86Conflict, HasCDI>;
6949
6950 //===----------------------------------------------------------------------===//
6951 // AVX-512 - Unpack Instructions
6952 //===----------------------------------------------------------------------===//
6953 defm VUNPCKH : avx512_fp_binop_p<0x15, "vunpckh", X86Unpckh>;
6954 defm VUNPCKL : avx512_fp_binop_p<0x14, "vunpckl", X86Unpckl>;
6955
6956 defm VPUNPCKLBW : avx512_binop_rm_vl_b<0x60, "vpunpcklbw", X86Unpckl,
6957                                        SSE_INTALU_ITINS_P, HasBWI>;
6958 defm VPUNPCKHBW : avx512_binop_rm_vl_b<0x68, "vpunpckhbw", X86Unpckh,
6959                                        SSE_INTALU_ITINS_P, HasBWI>;
6960 defm VPUNPCKLWD : avx512_binop_rm_vl_w<0x61, "vpunpcklwd", X86Unpckl,
6961                                        SSE_INTALU_ITINS_P, HasBWI>;
6962 defm VPUNPCKHWD : avx512_binop_rm_vl_w<0x69, "vpunpckhwd", X86Unpckh,
6963                                        SSE_INTALU_ITINS_P, HasBWI>;
6964
6965 defm VPUNPCKLDQ : avx512_binop_rm_vl_d<0x62, "vpunpckldq", X86Unpckl,
6966                                        SSE_INTALU_ITINS_P, HasAVX512>;
6967 defm VPUNPCKHDQ : avx512_binop_rm_vl_d<0x6A, "vpunpckhdq", X86Unpckh,
6968                                        SSE_INTALU_ITINS_P, HasAVX512>;
6969 defm VPUNPCKLQDQ : avx512_binop_rm_vl_q<0x6C, "vpunpcklqdq", X86Unpckl,
6970                                        SSE_INTALU_ITINS_P, HasAVX512>;
6971 defm VPUNPCKHQDQ : avx512_binop_rm_vl_q<0x6D, "vpunpckhqdq", X86Unpckh,
6972                                        SSE_INTALU_ITINS_P, HasAVX512>;
6973
6974 //===----------------------------------------------------------------------===//
6975 // AVX-512 - Extract & Insert Integer Instructions
6976 //===----------------------------------------------------------------------===//
6977
6978 multiclass avx512_extract_elt_bw_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
6979                                                             X86VectorVTInfo _> {
6980   let mayStore = 1 in
6981     def mr : AVX512Ii8<opc, MRMDestMem, (outs),
6982                 (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
6983                 OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6984                 [(store (_.EltVT (trunc (assertzext (OpNode (_.VT _.RC:$src1),
6985                                                             imm:$src2)))),
6986                         addr:$dst)]>,
6987                 EVEX, EVEX_CD8<_.EltSize, CD8VT1>;
6988 }
6989
6990 multiclass avx512_extract_elt_b<string OpcodeStr, X86VectorVTInfo _> {
6991   let Predicates = [HasBWI] in {
6992     def rr : AVX512Ii8<0x14, MRMDestReg, (outs GR32orGR64:$dst),
6993                   (ins _.RC:$src1, u8imm:$src2),
6994                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6995                   [(set GR32orGR64:$dst,
6996                         (X86pextrb (_.VT _.RC:$src1), imm:$src2))]>,
6997                   EVEX, TAPD;
6998
6999     defm NAME : avx512_extract_elt_bw_m<0x14, OpcodeStr, X86pextrb, _>, TAPD;
7000   }
7001 }
7002
7003 multiclass avx512_extract_elt_w<string OpcodeStr, X86VectorVTInfo _> {
7004   let Predicates = [HasBWI] in {
7005     def rr : AVX512Ii8<0xC5, MRMSrcReg, (outs GR32orGR64:$dst),
7006                   (ins _.RC:$src1, u8imm:$src2),
7007                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7008                   [(set GR32orGR64:$dst,
7009                         (X86pextrw (_.VT _.RC:$src1), imm:$src2))]>,
7010                   EVEX, PD;
7011
7012     defm NAME : avx512_extract_elt_bw_m<0x15, OpcodeStr, X86pextrw, _>, TAPD;
7013   }
7014 }
7015
7016 multiclass avx512_extract_elt_dq<string OpcodeStr, X86VectorVTInfo _,
7017                                                             RegisterClass GRC> {
7018   let Predicates = [HasDQI] in {
7019     def rr : AVX512Ii8<0x16, MRMDestReg, (outs GRC:$dst),
7020                   (ins _.RC:$src1, u8imm:$src2),
7021                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7022                   [(set GRC:$dst,
7023                       (extractelt (_.VT _.RC:$src1), imm:$src2))]>,
7024                   EVEX, TAPD;
7025
7026     let mayStore = 1 in
7027       def mr : AVX512Ii8<0x16, MRMDestMem, (outs),
7028                   (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
7029                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7030                   [(store (extractelt (_.VT _.RC:$src1),
7031                                       imm:$src2),addr:$dst)]>,
7032                   EVEX, EVEX_CD8<_.EltSize, CD8VT1>, TAPD;
7033   }
7034 }
7035
7036 defm VPEXTRBZ : avx512_extract_elt_b<"vpextrb", v16i8x_info>;
7037 defm VPEXTRWZ : avx512_extract_elt_w<"vpextrw", v8i16x_info>;
7038 defm VPEXTRDZ : avx512_extract_elt_dq<"vpextrd", v4i32x_info, GR32>;
7039 defm VPEXTRQZ : avx512_extract_elt_dq<"vpextrq", v2i64x_info, GR64>, VEX_W;
7040
7041 multiclass avx512_insert_elt_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
7042                                             X86VectorVTInfo _, PatFrag LdFrag> {
7043   def rm : AVX512Ii8<opc, MRMSrcMem, (outs _.RC:$dst),
7044       (ins _.RC:$src1,  _.ScalarMemOp:$src2, u8imm:$src3),
7045       OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7046       [(set _.RC:$dst,
7047           (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), imm:$src3)))]>,
7048       EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
7049 }
7050
7051 multiclass avx512_insert_elt_bw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7052                                             X86VectorVTInfo _, PatFrag LdFrag> {
7053   let Predicates = [HasBWI] in {
7054     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
7055         (ins _.RC:$src1, GR32orGR64:$src2, u8imm:$src3),
7056         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7057         [(set _.RC:$dst,
7058             (OpNode _.RC:$src1, GR32orGR64:$src2, imm:$src3))]>, EVEX_4V;
7059
7060     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag>;
7061   }
7062 }
7063
7064 multiclass avx512_insert_elt_dq<bits<8> opc, string OpcodeStr,
7065                                          X86VectorVTInfo _, RegisterClass GRC> {
7066   let Predicates = [HasDQI] in {
7067     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
7068         (ins _.RC:$src1, GRC:$src2, u8imm:$src3),
7069         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7070         [(set _.RC:$dst,
7071             (_.VT (insertelt _.RC:$src1, GRC:$src2, imm:$src3)))]>,
7072         EVEX_4V, TAPD;
7073
7074     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, insertelt, _,
7075                                     _.ScalarLdFrag>, TAPD;
7076   }
7077 }
7078
7079 defm VPINSRBZ : avx512_insert_elt_bw<0x20, "vpinsrb", X86pinsrb, v16i8x_info,
7080                                      extloadi8>, TAPD;
7081 defm VPINSRWZ : avx512_insert_elt_bw<0xC4, "vpinsrw", X86pinsrw, v8i16x_info,
7082                                      extloadi16>, PD;
7083 defm VPINSRDZ : avx512_insert_elt_dq<0x22, "vpinsrd", v4i32x_info, GR32>;
7084 defm VPINSRQZ : avx512_insert_elt_dq<0x22, "vpinsrq", v2i64x_info, GR64>, VEX_W;
7085 //===----------------------------------------------------------------------===//
7086 // VSHUFPS - VSHUFPD Operations
7087 //===----------------------------------------------------------------------===//
7088 multiclass avx512_shufp<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
7089                                                 AVX512VLVectorVTInfo VTInfo_FP>{
7090   defm NAME:     avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0xC6, X86Shufp>,
7091                                    EVEX_CD8<VTInfo_FP.info512.EltSize, CD8VF>,
7092                                    AVX512AIi8Base, EVEX_4V;
7093   let isCodeGenOnly = 1 in {
7094     defm NAME#_I: avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0xC6, X86Shufp>,
7095                                    EVEX_CD8<VTInfo_I.info512.EltSize, CD8VF>,
7096                                    AVX512AIi8Base, EVEX_4V;
7097   }
7098 }
7099
7100 defm VSHUFPS: avx512_shufp<"vshufps", avx512vl_i32_info, avx512vl_f32_info>, PS;
7101 defm VSHUFPD: avx512_shufp<"vshufpd", avx512vl_i64_info, avx512vl_f64_info>, PD, VEX_W;
7102 //===----------------------------------------------------------------------===//
7103 // AVX-512 - Byte shift Left/Right
7104 //===----------------------------------------------------------------------===//
7105
7106 multiclass avx512_shift_packed<bits<8> opc, SDNode OpNode, Format MRMr,
7107                              Format MRMm, string OpcodeStr, X86VectorVTInfo _>{
7108   def rr : AVX512<opc, MRMr,
7109              (outs _.RC:$dst), (ins _.RC:$src1, u8imm:$src2),
7110              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7111              [(set _.RC:$dst,(_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>;
7112   let mayLoad = 1 in
7113     def rm : AVX512<opc, MRMm,
7114              (outs _.RC:$dst), (ins _.MemOp:$src1, u8imm:$src2),
7115              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7116              [(set _.RC:$dst,(_.VT (OpNode 
7117                                    (_.LdFrag addr:$src1), (i8 imm:$src2))))]>;
7118 }
7119
7120 multiclass avx512_shift_packed_all<bits<8> opc, SDNode OpNode, Format MRMr, 
7121                                  Format MRMm, string OpcodeStr, Predicate prd>{
7122   let Predicates = [prd] in
7123     defm Z512 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
7124                                     OpcodeStr, v8i64_info>, EVEX_V512;
7125   let Predicates = [prd, HasVLX] in {
7126     defm Z256 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
7127                                     OpcodeStr, v4i64x_info>, EVEX_V256;
7128     defm Z128 : avx512_shift_packed<opc, OpNode, MRMr, MRMm, 
7129                                     OpcodeStr, v2i64x_info>, EVEX_V128;
7130   }
7131 }
7132 defm VPSLLDQ : avx512_shift_packed_all<0x73, X86vshldq, MRM7r, MRM7m, "vpslldq", 
7133                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
7134 defm VPSRLDQ : avx512_shift_packed_all<0x73, X86vshrdq, MRM3r, MRM3m, "vpsrldq", 
7135                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
7136
7137
7138 multiclass avx512_psadbw_packed<bits<8> opc, SDNode OpNode, 
7139                                 string OpcodeStr, X86VectorVTInfo _src>{
7140   def rr : AVX512BI<opc, MRMSrcReg,
7141              (outs _src.RC:$dst), (ins _src.RC:$src1, _src.RC:$src2),
7142              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7143              [(set _src.RC:$dst,(_src.VT 
7144                                 (OpNode _src.RC:$src1, _src.RC:$src2)))]>;
7145   let mayLoad = 1 in
7146     def rm : AVX512BI<opc, MRMSrcMem,
7147              (outs _src.RC:$dst), (ins _src.RC:$src1, _src.MemOp:$src2),
7148              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7149              [(set _src.RC:$dst,(_src.VT 
7150                                 (OpNode _src.RC:$src1, 
7151                                 (_src.VT (bitconvert 
7152                                           (_src.LdFrag addr:$src2))))))]>;
7153 }
7154
7155 multiclass avx512_psadbw_packed_all<bits<8> opc, SDNode OpNode, 
7156                                     string OpcodeStr, Predicate prd> {
7157   let Predicates = [prd] in
7158     defm Z512 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v64i8_info>, 
7159                                     EVEX_V512;
7160   let Predicates = [prd, HasVLX] in {
7161     defm Z256 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v32i8x_info>, 
7162                                     EVEX_V256;
7163     defm Z128 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v16i8x_info>,
7164                                     EVEX_V128;
7165   }
7166 }
7167
7168 defm VPSADBW : avx512_psadbw_packed_all<0xf6, X86psadbw, "vpsadbw", 
7169                                        HasBWI>, EVEX_4V;
7170
7171 multiclass avx512_ternlog<bits<8> opc, string OpcodeStr, SDNode OpNode,
7172                                                             X86VectorVTInfo _>{
7173   let Constraints = "$src1 = $dst" in {
7174   defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
7175                       (ins _.RC:$src2, _.RC:$src3, u8imm:$src4),
7176                       OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src3",
7177                       (OpNode (_.VT _.RC:$src1),
7178                               (_.VT _.RC:$src2),
7179                               (_.VT _.RC:$src3),
7180                               (i8 imm:$src4))>, AVX512AIi8Base, EVEX_4V;
7181   let mayLoad = 1 in {
7182     defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
7183                       (ins _.RC:$src2, _.MemOp:$src3, u8imm:$src4),
7184                       OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src3",
7185                       (OpNode (_.VT _.RC:$src1),
7186                               (_.VT _.RC:$src2),
7187                               (_.VT (bitconvert (_.LdFrag addr:$src3))),
7188                               (i8 imm:$src4))>,
7189                       AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
7190     defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
7191                       (ins _.RC:$src2, _.ScalarMemOp:$src3, u8imm:$src4),
7192                       OpcodeStr, "$src4, ${src3}"##_.BroadcastStr##", $src2",
7193                       "$src2, ${src3}"##_.BroadcastStr##", $src4",
7194                       (OpNode (_.VT _.RC:$src1),
7195                               (_.VT _.RC:$src2),
7196                               (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
7197                               (i8 imm:$src4))>, EVEX_B,
7198                       AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
7199   }
7200   }// Constraints = "$src1 = $dst"
7201 }
7202
7203 multiclass avx512_common_ternlog<string OpcodeStr, AVX512VLVectorVTInfo _>{
7204   let Predicates = [HasAVX512] in
7205     defm Z    : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info512>, EVEX_V512;
7206   let Predicates = [HasAVX512, HasVLX] in {
7207     defm Z128 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info128>, EVEX_V128;
7208     defm Z256 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info256>, EVEX_V256;
7209   }
7210 }
7211
7212 defm VPTERNLOGD : avx512_common_ternlog<"vpternlogd", avx512vl_i32_info>;
7213 defm VPTERNLOGQ : avx512_common_ternlog<"vpternlogq", avx512vl_i64_info>, VEX_W;
7214