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