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