xref: /aosp_15_r20/external/llvm/lib/Target/X86/X86InstrSSE.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===-- X86InstrSSE.td - SSE Instruction Set ---------------*- tablegen -*-===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This file describes the X86 SSE instruction set, defining the instructions,
11*9880d681SAndroid Build Coastguard Worker// and properties of the instructions which are needed for code generation,
12*9880d681SAndroid Build Coastguard Worker// machine code emission, and analysis.
13*9880d681SAndroid Build Coastguard Worker//
14*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Workerclass OpndItins<InstrItinClass arg_rr, InstrItinClass arg_rm> {
17*9880d681SAndroid Build Coastguard Worker  InstrItinClass rr = arg_rr;
18*9880d681SAndroid Build Coastguard Worker  InstrItinClass rm = arg_rm;
19*9880d681SAndroid Build Coastguard Worker  // InstrSchedModel info.
20*9880d681SAndroid Build Coastguard Worker  X86FoldableSchedWrite Sched = WriteFAdd;
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Workerclass SizeItins<OpndItins arg_s, OpndItins arg_d> {
24*9880d681SAndroid Build Coastguard Worker  OpndItins s = arg_s;
25*9880d681SAndroid Build Coastguard Worker  OpndItins d = arg_d;
26*9880d681SAndroid Build Coastguard Worker}
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Workerclass ShiftOpndItins<InstrItinClass arg_rr, InstrItinClass arg_rm,
30*9880d681SAndroid Build Coastguard Worker  InstrItinClass arg_ri> {
31*9880d681SAndroid Build Coastguard Worker  InstrItinClass rr = arg_rr;
32*9880d681SAndroid Build Coastguard Worker  InstrItinClass rm = arg_rm;
33*9880d681SAndroid Build Coastguard Worker  InstrItinClass ri = arg_ri;
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker// scalar
38*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFAdd in {
39*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_F32S : OpndItins<
40*9880d681SAndroid Build Coastguard Worker  IIC_SSE_ALU_F32S_RR, IIC_SSE_ALU_F32S_RM
41*9880d681SAndroid Build Coastguard Worker>;
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_F64S : OpndItins<
44*9880d681SAndroid Build Coastguard Worker  IIC_SSE_ALU_F64S_RR, IIC_SSE_ALU_F64S_RM
45*9880d681SAndroid Build Coastguard Worker>;
46*9880d681SAndroid Build Coastguard Worker}
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_ITINS_S : SizeItins<
49*9880d681SAndroid Build Coastguard Worker  SSE_ALU_F32S, SSE_ALU_F64S
50*9880d681SAndroid Build Coastguard Worker>;
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFMul in {
53*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_F32S : OpndItins<
54*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MUL_F32S_RR, IIC_SSE_MUL_F64S_RM
55*9880d681SAndroid Build Coastguard Worker>;
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_F64S : OpndItins<
58*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MUL_F64S_RR, IIC_SSE_MUL_F64S_RM
59*9880d681SAndroid Build Coastguard Worker>;
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_ITINS_S : SizeItins<
63*9880d681SAndroid Build Coastguard Worker  SSE_MUL_F32S, SSE_MUL_F64S
64*9880d681SAndroid Build Coastguard Worker>;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFDiv in {
67*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_F32S : OpndItins<
68*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DIV_F32S_RR, IIC_SSE_DIV_F64S_RM
69*9880d681SAndroid Build Coastguard Worker>;
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_F64S : OpndItins<
72*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DIV_F64S_RR, IIC_SSE_DIV_F64S_RM
73*9880d681SAndroid Build Coastguard Worker>;
74*9880d681SAndroid Build Coastguard Worker}
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_ITINS_S : SizeItins<
77*9880d681SAndroid Build Coastguard Worker  SSE_DIV_F32S, SSE_DIV_F64S
78*9880d681SAndroid Build Coastguard Worker>;
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker// parallel
81*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFAdd in {
82*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_F32P : OpndItins<
83*9880d681SAndroid Build Coastguard Worker  IIC_SSE_ALU_F32P_RR, IIC_SSE_ALU_F32P_RM
84*9880d681SAndroid Build Coastguard Worker>;
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_F64P : OpndItins<
87*9880d681SAndroid Build Coastguard Worker  IIC_SSE_ALU_F64P_RR, IIC_SSE_ALU_F64P_RM
88*9880d681SAndroid Build Coastguard Worker>;
89*9880d681SAndroid Build Coastguard Worker}
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerdef SSE_ALU_ITINS_P : SizeItins<
92*9880d681SAndroid Build Coastguard Worker  SSE_ALU_F32P, SSE_ALU_F64P
93*9880d681SAndroid Build Coastguard Worker>;
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFMul in {
96*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_F32P : OpndItins<
97*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MUL_F32P_RR, IIC_SSE_MUL_F64P_RM
98*9880d681SAndroid Build Coastguard Worker>;
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_F64P : OpndItins<
101*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MUL_F64P_RR, IIC_SSE_MUL_F64P_RM
102*9880d681SAndroid Build Coastguard Worker>;
103*9880d681SAndroid Build Coastguard Worker}
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Workerdef SSE_MUL_ITINS_P : SizeItins<
106*9880d681SAndroid Build Coastguard Worker  SSE_MUL_F32P, SSE_MUL_F64P
107*9880d681SAndroid Build Coastguard Worker>;
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFDiv in {
110*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_F32P : OpndItins<
111*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DIV_F32P_RR, IIC_SSE_DIV_F64P_RM
112*9880d681SAndroid Build Coastguard Worker>;
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_F64P : OpndItins<
115*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DIV_F64P_RR, IIC_SSE_DIV_F64P_RM
116*9880d681SAndroid Build Coastguard Worker>;
117*9880d681SAndroid Build Coastguard Worker}
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Workerdef SSE_DIV_ITINS_P : SizeItins<
120*9880d681SAndroid Build Coastguard Worker  SSE_DIV_F32P, SSE_DIV_F64P
121*9880d681SAndroid Build Coastguard Worker>;
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecLogic in
124*9880d681SAndroid Build Coastguard Workerdef SSE_VEC_BIT_ITINS_P : OpndItins<
125*9880d681SAndroid Build Coastguard Worker  IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
126*9880d681SAndroid Build Coastguard Worker>;
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerdef SSE_BIT_ITINS_P : OpndItins<
129*9880d681SAndroid Build Coastguard Worker  IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
130*9880d681SAndroid Build Coastguard Worker>;
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecALU in {
133*9880d681SAndroid Build Coastguard Workerdef SSE_INTALU_ITINS_P : OpndItins<
134*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
135*9880d681SAndroid Build Coastguard Worker>;
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerdef SSE_INTALUQ_ITINS_P : OpndItins<
138*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTALUQ_P_RR, IIC_SSE_INTALUQ_P_RM
139*9880d681SAndroid Build Coastguard Worker>;
140*9880d681SAndroid Build Coastguard Worker}
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecIMul in
143*9880d681SAndroid Build Coastguard Workerdef SSE_INTMUL_ITINS_P : OpndItins<
144*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTMUL_P_RR, IIC_SSE_INTMUL_P_RM
145*9880d681SAndroid Build Coastguard Worker>;
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Workerdef SSE_INTSHIFT_ITINS_P : ShiftOpndItins<
148*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTSH_P_RR, IIC_SSE_INTSH_P_RM, IIC_SSE_INTSH_P_RI
149*9880d681SAndroid Build Coastguard Worker>;
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Workerdef SSE_MOVA_ITINS : OpndItins<
152*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MOVA_P_RR, IIC_SSE_MOVA_P_RM
153*9880d681SAndroid Build Coastguard Worker>;
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Workerdef SSE_MOVU_ITINS : OpndItins<
156*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MOVU_P_RR, IIC_SSE_MOVU_P_RM
157*9880d681SAndroid Build Coastguard Worker>;
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Workerdef SSE_DPPD_ITINS : OpndItins<
160*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DPPD_RR, IIC_SSE_DPPD_RM
161*9880d681SAndroid Build Coastguard Worker>;
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Workerdef SSE_DPPS_ITINS : OpndItins<
164*9880d681SAndroid Build Coastguard Worker  IIC_SSE_DPPS_RR, IIC_SSE_DPPD_RM
165*9880d681SAndroid Build Coastguard Worker>;
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS : OpndItins<
168*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
169*9880d681SAndroid Build Coastguard Worker>;
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Workerdef SSE_EXTRACT_ITINS : OpndItins<
172*9880d681SAndroid Build Coastguard Worker  IIC_SSE_EXTRACTPS_RR, IIC_SSE_EXTRACTPS_RM
173*9880d681SAndroid Build Coastguard Worker>;
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Workerdef SSE_INSERT_ITINS : OpndItins<
176*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INSERTPS_RR, IIC_SSE_INSERTPS_RM
177*9880d681SAndroid Build Coastguard Worker>;
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Workerlet Sched = WriteMPSAD in
180*9880d681SAndroid Build Coastguard Workerdef SSE_MPSADBW_ITINS : OpndItins<
181*9880d681SAndroid Build Coastguard Worker  IIC_SSE_MPSADBW_RR, IIC_SSE_MPSADBW_RM
182*9880d681SAndroid Build Coastguard Worker>;
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecIMul in
185*9880d681SAndroid Build Coastguard Workerdef SSE_PMULLD_ITINS : OpndItins<
186*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PMULLD_RR, IIC_SSE_PMULLD_RM
187*9880d681SAndroid Build Coastguard Worker>;
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker// Definitions for backward compatibility.
190*9880d681SAndroid Build Coastguard Worker// The instructions mapped on these definitions uses a different itinerary
191*9880d681SAndroid Build Coastguard Worker// than the actual scheduling model.
192*9880d681SAndroid Build Coastguard Workerlet Sched = WriteShuffle in
193*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_SHUFFLESCHED :  OpndItins<
194*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
195*9880d681SAndroid Build Coastguard Worker>;
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecIMul in
198*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_VECIMULSCHED :  OpndItins<
199*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
200*9880d681SAndroid Build Coastguard Worker>;
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Workerlet Sched = WriteShuffle in
203*9880d681SAndroid Build Coastguard Workerdef SSE_INTALU_ITINS_SHUFF_P : OpndItins<
204*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
205*9880d681SAndroid Build Coastguard Worker>;
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Workerlet Sched = WriteMPSAD in
208*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_MPSADSCHED :  OpndItins<
209*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
210*9880d681SAndroid Build Coastguard Worker>;
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFBlend in
213*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_FBLENDSCHED :  OpndItins<
214*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
215*9880d681SAndroid Build Coastguard Worker>;
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workerlet Sched = WriteBlend in
218*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_BLENDSCHED :  OpndItins<
219*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
220*9880d681SAndroid Build Coastguard Worker>;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVarBlend in
223*9880d681SAndroid Build Coastguard Workerdef DEFAULT_ITINS_VARBLENDSCHED :  OpndItins<
224*9880d681SAndroid Build Coastguard Worker  IIC_ALU_NONMEM, IIC_ALU_MEM
225*9880d681SAndroid Build Coastguard Worker>;
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFBlend in
228*9880d681SAndroid Build Coastguard Workerdef SSE_INTALU_ITINS_FBLEND_P : OpndItins<
229*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
230*9880d681SAndroid Build Coastguard Worker>;
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Workerlet Sched = WriteBlend in
233*9880d681SAndroid Build Coastguard Workerdef SSE_INTALU_ITINS_BLEND_P : OpndItins<
234*9880d681SAndroid Build Coastguard Worker  IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
235*9880d681SAndroid Build Coastguard Worker>;
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
238*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 Instructions Classes
239*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker/// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
242*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
243*9880d681SAndroid Build Coastguard Worker                           RegisterClass RC, X86MemOperand x86memop,
244*9880d681SAndroid Build Coastguard Worker                           Domain d, OpndItins itins, bit Is2Addr = 1> {
245*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in {
246*9880d681SAndroid Build Coastguard Worker    def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
247*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
248*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
249*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
250*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpNode RC:$src1, RC:$src2))], itins.rr, d>,
251*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
252*9880d681SAndroid Build Coastguard Worker  }
253*9880d681SAndroid Build Coastguard Worker  def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
254*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
255*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
256*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
257*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))], itins.rm, d>,
258*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
259*9880d681SAndroid Build Coastguard Worker}
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker/// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
262*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
263*9880d681SAndroid Build Coastguard Worker                             string asm, string SSEVer, string FPSizeStr,
264*9880d681SAndroid Build Coastguard Worker                             Operand memopr, ComplexPattern mem_cpat,
265*9880d681SAndroid Build Coastguard Worker                             Domain d, OpndItins itins, bit Is2Addr = 1> {
266*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
267*9880d681SAndroid Build Coastguard Worker  def rr_Int : SI_Int<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
268*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
269*9880d681SAndroid Build Coastguard Worker           !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
270*9880d681SAndroid Build Coastguard Worker           !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
271*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (!cast<Intrinsic>(
272*9880d681SAndroid Build Coastguard Worker                 !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
273*9880d681SAndroid Build Coastguard Worker             RC:$src1, RC:$src2))], itins.rr, d>,
274*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
275*9880d681SAndroid Build Coastguard Worker  def rm_Int : SI_Int<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
276*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
277*9880d681SAndroid Build Coastguard Worker           !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
278*9880d681SAndroid Build Coastguard Worker           !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
279*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
280*9880d681SAndroid Build Coastguard Worker                                          SSEVer, "_", OpcodeStr, FPSizeStr))
281*9880d681SAndroid Build Coastguard Worker             RC:$src1, mem_cpat:$src2))], itins.rm, d>,
282*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
283*9880d681SAndroid Build Coastguard Worker}
284*9880d681SAndroid Build Coastguard Worker}
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker/// sse12_fp_packed - SSE 1 & 2 packed instructions class
287*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
288*9880d681SAndroid Build Coastguard Worker                           RegisterClass RC, ValueType vt,
289*9880d681SAndroid Build Coastguard Worker                           X86MemOperand x86memop, PatFrag mem_frag,
290*9880d681SAndroid Build Coastguard Worker                           Domain d, OpndItins itins, bit Is2Addr = 1> {
291*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
292*9880d681SAndroid Build Coastguard Worker    def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
293*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
294*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
295*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
296*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
297*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
298*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
299*9880d681SAndroid Build Coastguard Worker    def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
300*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
301*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
302*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
303*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
304*9880d681SAndroid Build Coastguard Worker          itins.rm, d>,
305*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
306*9880d681SAndroid Build Coastguard Worker}
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker/// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
309*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
310*9880d681SAndroid Build Coastguard Worker                                      string OpcodeStr, X86MemOperand x86memop,
311*9880d681SAndroid Build Coastguard Worker                                      list<dag> pat_rr, list<dag> pat_rm,
312*9880d681SAndroid Build Coastguard Worker                                      bit Is2Addr = 1> {
313*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1, hasSideEffects = 0 in
314*9880d681SAndroid Build Coastguard Worker    def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
315*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
316*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
317*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
318*9880d681SAndroid Build Coastguard Worker       pat_rr, NoItinerary, d>,
319*9880d681SAndroid Build Coastguard Worker       Sched<[WriteVecLogic]>;
320*9880d681SAndroid Build Coastguard Worker  def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
321*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
322*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
323*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
324*9880d681SAndroid Build Coastguard Worker       pat_rm, NoItinerary, d>,
325*9880d681SAndroid Build Coastguard Worker       Sched<[WriteVecLogicLd, ReadAfterLd]>;
326*9880d681SAndroid Build Coastguard Worker}
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
329*9880d681SAndroid Build Coastguard Worker//  Non-instruction patterns
330*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker// A vector extract of the first f32/f64 position is a subregister copy
333*9880d681SAndroid Build Coastguard Workerdef : Pat<(f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
334*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32)>;
335*9880d681SAndroid Build Coastguard Workerdef : Pat<(f64 (extractelt (v2f64 VR128:$src), (iPTR 0))),
336*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64)>;
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker// A 128-bit subvector extract from the first 256-bit vector position
339*9880d681SAndroid Build Coastguard Worker// is a subregister copy that needs no instruction.
340*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (iPTR 0))),
341*9880d681SAndroid Build Coastguard Worker          (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
342*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (iPTR 0))),
343*9880d681SAndroid Build Coastguard Worker          (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (iPTR 0))),
346*9880d681SAndroid Build Coastguard Worker          (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
347*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (iPTR 0))),
348*9880d681SAndroid Build Coastguard Worker          (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (iPTR 0))),
351*9880d681SAndroid Build Coastguard Worker          (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
352*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (iPTR 0))),
353*9880d681SAndroid Build Coastguard Worker          (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker// A 128-bit subvector insert to the first 256-bit vector position
356*9880d681SAndroid Build Coastguard Worker// is a subregister copy that needs no instruction.
357*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 25 in { // to give priority over vinsertf128rm
358*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)),
359*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
360*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)),
361*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
362*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)),
363*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
364*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)),
365*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
366*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v8i16 VR128:$src), (iPTR 0)),
367*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
368*9880d681SAndroid Build Coastguard Workerdef : Pat<(insert_subvector undef, (v16i8 VR128:$src), (iPTR 0)),
369*9880d681SAndroid Build Coastguard Worker          (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
370*9880d681SAndroid Build Coastguard Worker}
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker// Implicitly promote a 32-bit scalar to a vector.
373*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (scalar_to_vector FR32:$src)),
374*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR32:$src, VR128)>;
375*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (scalar_to_vector FR32:$src)),
376*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR32:$src, VR128)>;
377*9880d681SAndroid Build Coastguard Worker// Implicitly promote a 64-bit scalar to a vector.
378*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (scalar_to_vector FR64:$src)),
379*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128)>;
380*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (scalar_to_vector FR64:$src)),
381*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128)>;
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker// Bitcasts between 128-bit vector types. Return the original type since
384*9880d681SAndroid Build Coastguard Worker// no instruction is needed for the conversion
385*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
386*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
387*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
388*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
389*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
390*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
391*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
392*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
393*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
394*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
395*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
396*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
397*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
398*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
399*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
400*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
401*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
402*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
403*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
404*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
405*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
406*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
407*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
408*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
409*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
410*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
411*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
412*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
413*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
414*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
415*9880d681SAndroid Build Coastguard Workerdef : Pat<(f128  (bitconvert (i128  FR128:$src))), (f128  FR128:$src)>;
416*9880d681SAndroid Build Coastguard Workerdef : Pat<(i128  (bitconvert (f128  FR128:$src))), (i128  FR128:$src)>;
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker// Bitcasts between 256-bit vector types. Return the original type since
419*9880d681SAndroid Build Coastguard Worker// no instruction is needed for the conversion
420*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64  (bitconvert (v8i32  VR256:$src))), (v4i64  VR256:$src)>;
421*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64  VR256:$src)>;
422*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64  (bitconvert (v32i8  VR256:$src))), (v4i64  VR256:$src)>;
423*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64  (bitconvert (v8f32  VR256:$src))), (v4i64  VR256:$src)>;
424*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64  (bitconvert (v4f64  VR256:$src))), (v4i64  VR256:$src)>;
425*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32  (bitconvert (v4i64  VR256:$src))), (v8i32  VR256:$src)>;
426*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32  VR256:$src)>;
427*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32  (bitconvert (v32i8  VR256:$src))), (v8i32  VR256:$src)>;
428*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32  (bitconvert (v4f64  VR256:$src))), (v8i32  VR256:$src)>;
429*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32  (bitconvert (v8f32  VR256:$src))), (v8i32  VR256:$src)>;
430*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (bitconvert (v4i64  VR256:$src))), (v16i16 VR256:$src)>;
431*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (bitconvert (v8i32  VR256:$src))), (v16i16 VR256:$src)>;
432*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (bitconvert (v32i8  VR256:$src))), (v16i16 VR256:$src)>;
433*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (bitconvert (v4f64  VR256:$src))), (v16i16 VR256:$src)>;
434*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (bitconvert (v8f32  VR256:$src))), (v16i16 VR256:$src)>;
435*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8  (bitconvert (v4i64  VR256:$src))), (v32i8  VR256:$src)>;
436*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8  (bitconvert (v8i32  VR256:$src))), (v32i8  VR256:$src)>;
437*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8  VR256:$src)>;
438*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8  (bitconvert (v4f64  VR256:$src))), (v32i8  VR256:$src)>;
439*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8  (bitconvert (v8f32  VR256:$src))), (v32i8  VR256:$src)>;
440*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32  (bitconvert (v4i64  VR256:$src))), (v8f32  VR256:$src)>;
441*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32  (bitconvert (v8i32  VR256:$src))), (v8f32  VR256:$src)>;
442*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32  VR256:$src)>;
443*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32  (bitconvert (v32i8  VR256:$src))), (v8f32  VR256:$src)>;
444*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32  (bitconvert (v4f64  VR256:$src))), (v8f32  VR256:$src)>;
445*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64  (bitconvert (v4i64  VR256:$src))), (v4f64  VR256:$src)>;
446*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64  (bitconvert (v8i32  VR256:$src))), (v4f64  VR256:$src)>;
447*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64  VR256:$src)>;
448*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64  (bitconvert (v32i8  VR256:$src))), (v4f64  VR256:$src)>;
449*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64  (bitconvert (v8f32  VR256:$src))), (v4f64  VR256:$src)>;
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker// Alias instructions that map fld0 to xorps for sse or vxorps for avx.
452*9880d681SAndroid Build Coastguard Worker// This is expanded by ExpandPostRAPseudos.
453*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
454*9880d681SAndroid Build Coastguard Worker    isPseudo = 1, SchedRW = [WriteZero] in {
455*9880d681SAndroid Build Coastguard Worker  def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
456*9880d681SAndroid Build Coastguard Worker                   [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
457*9880d681SAndroid Build Coastguard Worker  def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
458*9880d681SAndroid Build Coastguard Worker                   [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
459*9880d681SAndroid Build Coastguard Worker}
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
462*9880d681SAndroid Build Coastguard Worker// AVX & SSE - Zero/One Vectors
463*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker// Alias instruction that maps zero vector to pxor / xorp* for sse.
466*9880d681SAndroid Build Coastguard Worker// This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
467*9880d681SAndroid Build Coastguard Worker// swizzled by ExecutionDepsFix to pxor.
468*9880d681SAndroid Build Coastguard Worker// We set canFoldAsLoad because this can be converted to a constant-pool
469*9880d681SAndroid Build Coastguard Worker// load of an all-zeros value if folding it would be beneficial.
470*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
471*9880d681SAndroid Build Coastguard Worker    isPseudo = 1, Predicates = [NoVLX], SchedRW = [WriteZero] in {
472*9880d681SAndroid Build Coastguard Workerdef V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "",
473*9880d681SAndroid Build Coastguard Worker               [(set VR128:$dst, (v4f32 immAllZerosV))]>;
474*9880d681SAndroid Build Coastguard Worker}
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Workerlet Predicates = [NoVLX] in
477*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 immAllZerosV), (V_SET0)>;
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker// The same as done above but for AVX.  The 256-bit AVX1 ISA doesn't support PI,
481*9880d681SAndroid Build Coastguard Worker// and doesn't need it because on sandy bridge the register is set to zero
482*9880d681SAndroid Build Coastguard Worker// at the rename stage without using any execution unit, so SET0PSY
483*9880d681SAndroid Build Coastguard Worker// and SET0PDY can be used for vector int instructions without penalty
484*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
485*9880d681SAndroid Build Coastguard Worker    isPseudo = 1, Predicates = [HasAVX, NoVLX], SchedRW = [WriteZero] in {
486*9880d681SAndroid Build Coastguard Workerdef AVX_SET0 : I<0, Pseudo, (outs VR256:$dst), (ins), "",
487*9880d681SAndroid Build Coastguard Worker                 [(set VR256:$dst, (v8i32 immAllZerosV))]>;
488*9880d681SAndroid Build Coastguard Worker}
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Worker// We set canFoldAsLoad because this can be converted to a constant-pool
491*9880d681SAndroid Build Coastguard Worker// load of an all-ones value if folding it would be beneficial.
492*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
493*9880d681SAndroid Build Coastguard Worker    isPseudo = 1, SchedRW = [WriteZero] in {
494*9880d681SAndroid Build Coastguard Worker  def V_SETALLONES : I<0, Pseudo, (outs VR128:$dst), (ins), "",
495*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (v4i32 immAllOnesV))]>;
496*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX2] in
497*9880d681SAndroid Build Coastguard Worker  def AVX2_SETALLONES : I<0, Pseudo, (outs VR256:$dst), (ins), "",
498*9880d681SAndroid Build Coastguard Worker                          [(set VR256:$dst, (v8i32 immAllOnesV))]>;
499*9880d681SAndroid Build Coastguard Worker}
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
503*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Move FP Scalar Instructions
504*9880d681SAndroid Build Coastguard Worker//
505*9880d681SAndroid Build Coastguard Worker// Move Instructions. Register-to-register movss/movsd is not used for FR32/64
506*9880d681SAndroid Build Coastguard Worker// register copies because it's a partial register update; Register-to-register
507*9880d681SAndroid Build Coastguard Worker// movss/movsd is not modeled as an INSERT_SUBREG because INSERT_SUBREG requires
508*9880d681SAndroid Build Coastguard Worker// that the insert be implementable in terms of a copy, and just mentioned, we
509*9880d681SAndroid Build Coastguard Worker// don't use movss/movsd for copies.
510*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Workermulticlass sse12_move_rr<RegisterClass RC, SDNode OpNode, ValueType vt,
513*9880d681SAndroid Build Coastguard Worker                         X86MemOperand x86memop, string base_opc,
514*9880d681SAndroid Build Coastguard Worker                         string asm_opr, Domain d = GenericDomain> {
515*9880d681SAndroid Build Coastguard Worker  def rr : SI<0x10, MRMSrcReg, (outs VR128:$dst),
516*9880d681SAndroid Build Coastguard Worker              (ins VR128:$src1, RC:$src2),
517*9880d681SAndroid Build Coastguard Worker              !strconcat(base_opc, asm_opr),
518*9880d681SAndroid Build Coastguard Worker              [(set VR128:$dst, (vt (OpNode VR128:$src1,
519*9880d681SAndroid Build Coastguard Worker                                 (scalar_to_vector RC:$src2))))],
520*9880d681SAndroid Build Coastguard Worker              IIC_SSE_MOV_S_RR, d>, Sched<[WriteFShuffle]>;
521*9880d681SAndroid Build Coastguard Worker
522*9880d681SAndroid Build Coastguard Worker  // For the disassembler
523*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
524*9880d681SAndroid Build Coastguard Worker  def rr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
525*9880d681SAndroid Build Coastguard Worker                  (ins VR128:$src1, RC:$src2),
526*9880d681SAndroid Build Coastguard Worker                  !strconcat(base_opc, asm_opr),
527*9880d681SAndroid Build Coastguard Worker                  [], IIC_SSE_MOV_S_RR>, Sched<[WriteFShuffle]>;
528*9880d681SAndroid Build Coastguard Worker}
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Workermulticlass sse12_move<RegisterClass RC, SDNode OpNode, ValueType vt,
531*9880d681SAndroid Build Coastguard Worker                      X86MemOperand x86memop, string OpcodeStr,
532*9880d681SAndroid Build Coastguard Worker                      Domain d = GenericDomain> {
533*9880d681SAndroid Build Coastguard Worker  // AVX
534*9880d681SAndroid Build Coastguard Worker  defm V#NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
535*9880d681SAndroid Build Coastguard Worker                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}", d>,
536*9880d681SAndroid Build Coastguard Worker                              VEX_4V, VEX_LIG;
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker  def V#NAME#mr : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
539*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
540*9880d681SAndroid Build Coastguard Worker                     [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR, d>,
541*9880d681SAndroid Build Coastguard Worker                     VEX, VEX_LIG, Sched<[WriteStore]>;
542*9880d681SAndroid Build Coastguard Worker  // SSE1 & 2
543*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
544*9880d681SAndroid Build Coastguard Worker    defm NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
545*9880d681SAndroid Build Coastguard Worker                              "\t{$src2, $dst|$dst, $src2}", d>;
546*9880d681SAndroid Build Coastguard Worker  }
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker  def NAME#mr   : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
549*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
550*9880d681SAndroid Build Coastguard Worker                     [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR, d>,
551*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteStore]>;
552*9880d681SAndroid Build Coastguard Worker}
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker// Loading from memory automatically zeroing upper bits.
555*9880d681SAndroid Build Coastguard Workermulticlass sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
556*9880d681SAndroid Build Coastguard Worker                         PatFrag mem_pat, string OpcodeStr,
557*9880d681SAndroid Build Coastguard Worker                         Domain d = GenericDomain> {
558*9880d681SAndroid Build Coastguard Worker  def V#NAME#rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
559*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
560*9880d681SAndroid Build Coastguard Worker                     [(set RC:$dst, (mem_pat addr:$src))],
561*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_MOV_S_RM, d>, VEX, VEX_LIG, Sched<[WriteLoad]>;
562*9880d681SAndroid Build Coastguard Worker  def NAME#rm   : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
563*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
564*9880d681SAndroid Build Coastguard Worker                     [(set RC:$dst, (mem_pat addr:$src))],
565*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_MOV_S_RM, d>, Sched<[WriteLoad]>;
566*9880d681SAndroid Build Coastguard Worker}
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Workerdefm MOVSS : sse12_move<FR32, X86Movss, v4f32, f32mem, "movss",
569*9880d681SAndroid Build Coastguard Worker                        SSEPackedSingle>, XS;
570*9880d681SAndroid Build Coastguard Workerdefm MOVSD : sse12_move<FR64, X86Movsd, v2f64, f64mem, "movsd",
571*9880d681SAndroid Build Coastguard Worker                        SSEPackedDouble>, XD;
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, isReMaterializable = 1 in {
574*9880d681SAndroid Build Coastguard Worker  defm MOVSS : sse12_move_rm<FR32, f32mem, loadf32, "movss",
575*9880d681SAndroid Build Coastguard Worker                             SSEPackedSingle>, XS;
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in
578*9880d681SAndroid Build Coastguard Worker    defm MOVSD : sse12_move_rm<FR64, f64mem, loadf64, "movsd",
579*9880d681SAndroid Build Coastguard Worker                               SSEPackedDouble>, XD;
580*9880d681SAndroid Build Coastguard Worker}
581*9880d681SAndroid Build Coastguard Worker
582*9880d681SAndroid Build Coastguard Worker// Patterns
583*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
584*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in {
585*9880d681SAndroid Build Coastguard Worker  // MOVSSrm zeros the high parts of the register; represent this
586*9880d681SAndroid Build Coastguard Worker  // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
587*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
588*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
589*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
590*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
591*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
592*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
593*9880d681SAndroid Build Coastguard Worker
594*9880d681SAndroid Build Coastguard Worker  // MOVSDrm zeros the high parts of the register; represent this
595*9880d681SAndroid Build Coastguard Worker  // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
596*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
597*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
598*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
599*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
600*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
601*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
602*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
603*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
604*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzload addr:$src)),
605*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker  // Represent the same patterns above but in the form they appear for
608*9880d681SAndroid Build Coastguard Worker  // 256-bit types
609*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
610*9880d681SAndroid Build Coastguard Worker                   (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
611*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
612*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
613*9880d681SAndroid Build Coastguard Worker                   (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
614*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
615*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86vzload addr:$src)),
616*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
617*9880d681SAndroid Build Coastguard Worker  }
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker  // Extract and store.
620*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
621*9880d681SAndroid Build Coastguard Worker                   addr:$dst),
622*9880d681SAndroid Build Coastguard Worker            (VMOVSSmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32))>;
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker  // Shuffle with VMOVSS
625*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
626*9880d681SAndroid Build Coastguard Worker            (VMOVSSrr (v4i32 VR128:$src1),
627*9880d681SAndroid Build Coastguard Worker                      (COPY_TO_REGCLASS (v4i32 VR128:$src2), FR32))>;
628*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
629*9880d681SAndroid Build Coastguard Worker            (VMOVSSrr (v4f32 VR128:$src1),
630*9880d681SAndroid Build Coastguard Worker                      (COPY_TO_REGCLASS (v4f32 VR128:$src2), FR32))>;
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker  // 256-bit variants
633*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
634*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0),
635*9880d681SAndroid Build Coastguard Worker              (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_xmm),
636*9880d681SAndroid Build Coastguard Worker                        (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_xmm)),
637*9880d681SAndroid Build Coastguard Worker              sub_xmm)>;
638*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
639*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0),
640*9880d681SAndroid Build Coastguard Worker              (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_xmm),
641*9880d681SAndroid Build Coastguard Worker                        (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_xmm)),
642*9880d681SAndroid Build Coastguard Worker              sub_xmm)>;
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Worker  // Shuffle with VMOVSD
645*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
646*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
647*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
648*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
649*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
650*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
651*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
652*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker  // 256-bit variants
655*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
656*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0),
657*9880d681SAndroid Build Coastguard Worker              (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_xmm),
658*9880d681SAndroid Build Coastguard Worker                        (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_xmm)),
659*9880d681SAndroid Build Coastguard Worker              sub_xmm)>;
660*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
661*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0),
662*9880d681SAndroid Build Coastguard Worker              (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_xmm),
663*9880d681SAndroid Build Coastguard Worker                        (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_xmm)),
664*9880d681SAndroid Build Coastguard Worker              sub_xmm)>;
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker  // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
667*9880d681SAndroid Build Coastguard Worker  // is during lowering, where it's not possible to recognize the fold cause
668*9880d681SAndroid Build Coastguard Worker  // it has two uses through a bitcast. One use disappears at isel time and the
669*9880d681SAndroid Build Coastguard Worker  // fold opportunity reappears.
670*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
671*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
672*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
673*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
674*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
675*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
676*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
677*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
678*9880d681SAndroid Build Coastguard Worker}
679*9880d681SAndroid Build Coastguard Worker
680*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
681*9880d681SAndroid Build Coastguard Worker  let Predicates = [NoSSE41], AddedComplexity = 15 in {
682*9880d681SAndroid Build Coastguard Worker  // Move scalar to XMM zero-extended, zeroing a VR128 then do a
683*9880d681SAndroid Build Coastguard Worker  // MOVSS to the lower bits.
684*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
685*9880d681SAndroid Build Coastguard Worker            (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
686*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
687*9880d681SAndroid Build Coastguard Worker            (MOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
688*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
689*9880d681SAndroid Build Coastguard Worker            (MOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
690*9880d681SAndroid Build Coastguard Worker  }
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in {
693*9880d681SAndroid Build Coastguard Worker  // MOVSSrm already zeros the high parts of the register.
694*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
695*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
696*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
697*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
698*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
699*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
700*9880d681SAndroid Build Coastguard Worker  }
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker  // Extract and store.
703*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
704*9880d681SAndroid Build Coastguard Worker                   addr:$dst),
705*9880d681SAndroid Build Coastguard Worker            (MOVSSmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR32))>;
706*9880d681SAndroid Build Coastguard Worker
707*9880d681SAndroid Build Coastguard Worker  // Shuffle with MOVSS
708*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
709*9880d681SAndroid Build Coastguard Worker            (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
710*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
711*9880d681SAndroid Build Coastguard Worker            (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
712*9880d681SAndroid Build Coastguard Worker}
713*9880d681SAndroid Build Coastguard Worker
714*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
715*9880d681SAndroid Build Coastguard Worker  let Predicates = [NoSSE41], AddedComplexity = 15 in {
716*9880d681SAndroid Build Coastguard Worker  // Move scalar to XMM zero-extended, zeroing a VR128 then do a
717*9880d681SAndroid Build Coastguard Worker  // MOVSD to the lower bits.
718*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
719*9880d681SAndroid Build Coastguard Worker            (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
720*9880d681SAndroid Build Coastguard Worker  }
721*9880d681SAndroid Build Coastguard Worker
722*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in {
723*9880d681SAndroid Build Coastguard Worker  // MOVSDrm already zeros the high parts of the register.
724*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
725*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
726*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
727*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
728*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
729*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
730*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
731*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
732*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzload addr:$src)),
733*9880d681SAndroid Build Coastguard Worker            (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
734*9880d681SAndroid Build Coastguard Worker  }
735*9880d681SAndroid Build Coastguard Worker
736*9880d681SAndroid Build Coastguard Worker  // Shuffle with MOVSD
737*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
738*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
739*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
740*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
741*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
742*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
743*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
744*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
745*9880d681SAndroid Build Coastguard Worker
746*9880d681SAndroid Build Coastguard Worker  // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
747*9880d681SAndroid Build Coastguard Worker  // is during lowering, where it's not possible to recognize the fold because
748*9880d681SAndroid Build Coastguard Worker  // it has two uses through a bitcast. One use disappears at isel time and the
749*9880d681SAndroid Build Coastguard Worker  // fold opportunity reappears.
750*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
751*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
752*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
753*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
754*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
755*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
756*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
757*9880d681SAndroid Build Coastguard Worker            (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
758*9880d681SAndroid Build Coastguard Worker}
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker// Aliases to help the assembler pick two byte VEX encodings by swapping the
761*9880d681SAndroid Build Coastguard Worker// operands relative to the normal instructions to use VEX.R instead of VEX.B.
762*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
763*9880d681SAndroid Build Coastguard Worker                (VMOVSSrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
764*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovsd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
765*9880d681SAndroid Build Coastguard Worker                (VMOVSDrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
766*9880d681SAndroid Build Coastguard Worker
767*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
768*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
769*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Workermulticlass sse12_mov_packed<bits<8> opc, RegisterClass RC,
772*9880d681SAndroid Build Coastguard Worker                            X86MemOperand x86memop, PatFrag ld_frag,
773*9880d681SAndroid Build Coastguard Worker                            string asm, Domain d,
774*9880d681SAndroid Build Coastguard Worker                            OpndItins itins,
775*9880d681SAndroid Build Coastguard Worker                            bit IsReMaterializable = 1> {
776*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
777*9880d681SAndroid Build Coastguard Worker  def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
778*9880d681SAndroid Build Coastguard Worker              !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], itins.rr, d>,
779*9880d681SAndroid Build Coastguard Worker           Sched<[WriteFShuffle]>;
780*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
781*9880d681SAndroid Build Coastguard Worker  def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
782*9880d681SAndroid Build Coastguard Worker              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
783*9880d681SAndroid Build Coastguard Worker                   [(set RC:$dst, (ld_frag addr:$src))], itins.rm, d>,
784*9880d681SAndroid Build Coastguard Worker           Sched<[WriteLoad]>;
785*9880d681SAndroid Build Coastguard Worker}
786*9880d681SAndroid Build Coastguard Worker
787*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
788*9880d681SAndroid Build Coastguard Workerdefm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
789*9880d681SAndroid Build Coastguard Worker                              "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
790*9880d681SAndroid Build Coastguard Worker                              PS, VEX;
791*9880d681SAndroid Build Coastguard Workerdefm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
792*9880d681SAndroid Build Coastguard Worker                              "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
793*9880d681SAndroid Build Coastguard Worker                              PD, VEX;
794*9880d681SAndroid Build Coastguard Workerdefm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
795*9880d681SAndroid Build Coastguard Worker                              "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
796*9880d681SAndroid Build Coastguard Worker                              PS, VEX;
797*9880d681SAndroid Build Coastguard Workerdefm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
798*9880d681SAndroid Build Coastguard Worker                              "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
799*9880d681SAndroid Build Coastguard Worker                              PD, VEX;
800*9880d681SAndroid Build Coastguard Worker
801*9880d681SAndroid Build Coastguard Workerdefm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
802*9880d681SAndroid Build Coastguard Worker                              "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
803*9880d681SAndroid Build Coastguard Worker                              PS, VEX, VEX_L;
804*9880d681SAndroid Build Coastguard Workerdefm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
805*9880d681SAndroid Build Coastguard Worker                              "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
806*9880d681SAndroid Build Coastguard Worker                              PD, VEX, VEX_L;
807*9880d681SAndroid Build Coastguard Workerdefm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
808*9880d681SAndroid Build Coastguard Worker                              "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
809*9880d681SAndroid Build Coastguard Worker                              PS, VEX, VEX_L;
810*9880d681SAndroid Build Coastguard Workerdefm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
811*9880d681SAndroid Build Coastguard Worker                              "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
812*9880d681SAndroid Build Coastguard Worker                              PD, VEX, VEX_L;
813*9880d681SAndroid Build Coastguard Worker}
814*9880d681SAndroid Build Coastguard Worker
815*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
816*9880d681SAndroid Build Coastguard Workerdefm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
817*9880d681SAndroid Build Coastguard Worker                              "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
818*9880d681SAndroid Build Coastguard Worker                              PS;
819*9880d681SAndroid Build Coastguard Workerdefm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
820*9880d681SAndroid Build Coastguard Worker                              "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
821*9880d681SAndroid Build Coastguard Worker                              PS;
822*9880d681SAndroid Build Coastguard Worker}
823*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
824*9880d681SAndroid Build Coastguard Workerdefm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
825*9880d681SAndroid Build Coastguard Worker                              "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
826*9880d681SAndroid Build Coastguard Worker                              PD;
827*9880d681SAndroid Build Coastguard Workerdefm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
828*9880d681SAndroid Build Coastguard Worker                              "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
829*9880d681SAndroid Build Coastguard Worker                              PD;
830*9880d681SAndroid Build Coastguard Worker}
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteStore], Predicates = [HasAVX, NoVLX]  in {
833*9880d681SAndroid Build Coastguard Workerdef VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
834*9880d681SAndroid Build Coastguard Worker                   "movaps\t{$src, $dst|$dst, $src}",
835*9880d681SAndroid Build Coastguard Worker                   [(alignedstore (v4f32 VR128:$src), addr:$dst)],
836*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>, VEX;
837*9880d681SAndroid Build Coastguard Workerdef VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
838*9880d681SAndroid Build Coastguard Worker                   "movapd\t{$src, $dst|$dst, $src}",
839*9880d681SAndroid Build Coastguard Worker                   [(alignedstore (v2f64 VR128:$src), addr:$dst)],
840*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>, VEX;
841*9880d681SAndroid Build Coastguard Workerdef VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
842*9880d681SAndroid Build Coastguard Worker                   "movups\t{$src, $dst|$dst, $src}",
843*9880d681SAndroid Build Coastguard Worker                   [(store (v4f32 VR128:$src), addr:$dst)],
844*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>, VEX;
845*9880d681SAndroid Build Coastguard Workerdef VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
846*9880d681SAndroid Build Coastguard Worker                   "movupd\t{$src, $dst|$dst, $src}",
847*9880d681SAndroid Build Coastguard Worker                   [(store (v2f64 VR128:$src), addr:$dst)],
848*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>, VEX;
849*9880d681SAndroid Build Coastguard Workerdef VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
850*9880d681SAndroid Build Coastguard Worker                   "movaps\t{$src, $dst|$dst, $src}",
851*9880d681SAndroid Build Coastguard Worker                   [(alignedstore256 (v8f32 VR256:$src), addr:$dst)],
852*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
853*9880d681SAndroid Build Coastguard Workerdef VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
854*9880d681SAndroid Build Coastguard Worker                   "movapd\t{$src, $dst|$dst, $src}",
855*9880d681SAndroid Build Coastguard Worker                   [(alignedstore256 (v4f64 VR256:$src), addr:$dst)],
856*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
857*9880d681SAndroid Build Coastguard Workerdef VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
858*9880d681SAndroid Build Coastguard Worker                   "movups\t{$src, $dst|$dst, $src}",
859*9880d681SAndroid Build Coastguard Worker                   [(store (v8f32 VR256:$src), addr:$dst)],
860*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
861*9880d681SAndroid Build Coastguard Workerdef VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
862*9880d681SAndroid Build Coastguard Worker                   "movupd\t{$src, $dst|$dst, $src}",
863*9880d681SAndroid Build Coastguard Worker                   [(store (v4f64 VR256:$src), addr:$dst)],
864*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
865*9880d681SAndroid Build Coastguard Worker} // SchedRW
866*9880d681SAndroid Build Coastguard Worker
867*9880d681SAndroid Build Coastguard Worker// For disassembler
868*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
869*9880d681SAndroid Build Coastguard Worker    SchedRW = [WriteFShuffle] in {
870*9880d681SAndroid Build Coastguard Worker  def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
871*9880d681SAndroid Build Coastguard Worker                          (ins VR128:$src),
872*9880d681SAndroid Build Coastguard Worker                          "movaps\t{$src, $dst|$dst, $src}", [],
873*9880d681SAndroid Build Coastguard Worker                          IIC_SSE_MOVA_P_RR>, VEX;
874*9880d681SAndroid Build Coastguard Worker  def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
875*9880d681SAndroid Build Coastguard Worker                           (ins VR128:$src),
876*9880d681SAndroid Build Coastguard Worker                           "movapd\t{$src, $dst|$dst, $src}", [],
877*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_MOVA_P_RR>, VEX;
878*9880d681SAndroid Build Coastguard Worker  def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
879*9880d681SAndroid Build Coastguard Worker                           (ins VR128:$src),
880*9880d681SAndroid Build Coastguard Worker                           "movups\t{$src, $dst|$dst, $src}", [],
881*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_MOVU_P_RR>, VEX;
882*9880d681SAndroid Build Coastguard Worker  def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
883*9880d681SAndroid Build Coastguard Worker                           (ins VR128:$src),
884*9880d681SAndroid Build Coastguard Worker                           "movupd\t{$src, $dst|$dst, $src}", [],
885*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_MOVU_P_RR>, VEX;
886*9880d681SAndroid Build Coastguard Worker  def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
887*9880d681SAndroid Build Coastguard Worker                            (ins VR256:$src),
888*9880d681SAndroid Build Coastguard Worker                            "movaps\t{$src, $dst|$dst, $src}", [],
889*9880d681SAndroid Build Coastguard Worker                            IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
890*9880d681SAndroid Build Coastguard Worker  def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
891*9880d681SAndroid Build Coastguard Worker                            (ins VR256:$src),
892*9880d681SAndroid Build Coastguard Worker                            "movapd\t{$src, $dst|$dst, $src}", [],
893*9880d681SAndroid Build Coastguard Worker                            IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
894*9880d681SAndroid Build Coastguard Worker  def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
895*9880d681SAndroid Build Coastguard Worker                            (ins VR256:$src),
896*9880d681SAndroid Build Coastguard Worker                            "movups\t{$src, $dst|$dst, $src}", [],
897*9880d681SAndroid Build Coastguard Worker                            IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
898*9880d681SAndroid Build Coastguard Worker  def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
899*9880d681SAndroid Build Coastguard Worker                            (ins VR256:$src),
900*9880d681SAndroid Build Coastguard Worker                            "movupd\t{$src, $dst|$dst, $src}", [],
901*9880d681SAndroid Build Coastguard Worker                            IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
902*9880d681SAndroid Build Coastguard Worker}
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Worker// Aliases to help the assembler pick two byte VEX encodings by swapping the
905*9880d681SAndroid Build Coastguard Worker// operands relative to the normal instructions to use VEX.R instead of VEX.B.
906*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
907*9880d681SAndroid Build Coastguard Worker                (VMOVAPSrr_REV VR128L:$dst, VR128H:$src), 0>;
908*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
909*9880d681SAndroid Build Coastguard Worker                (VMOVAPDrr_REV VR128L:$dst, VR128H:$src), 0>;
910*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
911*9880d681SAndroid Build Coastguard Worker                (VMOVUPSrr_REV VR128L:$dst, VR128H:$src), 0>;
912*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
913*9880d681SAndroid Build Coastguard Worker                (VMOVUPDrr_REV VR128L:$dst, VR128H:$src), 0>;
914*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
915*9880d681SAndroid Build Coastguard Worker                (VMOVAPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
916*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
917*9880d681SAndroid Build Coastguard Worker                (VMOVAPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
918*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
919*9880d681SAndroid Build Coastguard Worker                (VMOVUPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
920*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
921*9880d681SAndroid Build Coastguard Worker                (VMOVUPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
922*9880d681SAndroid Build Coastguard Worker
923*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteStore] in {
924*9880d681SAndroid Build Coastguard Workerdef MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
925*9880d681SAndroid Build Coastguard Worker                   "movaps\t{$src, $dst|$dst, $src}",
926*9880d681SAndroid Build Coastguard Worker                   [(alignedstore (v4f32 VR128:$src), addr:$dst)],
927*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>;
928*9880d681SAndroid Build Coastguard Workerdef MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
929*9880d681SAndroid Build Coastguard Worker                   "movapd\t{$src, $dst|$dst, $src}",
930*9880d681SAndroid Build Coastguard Worker                   [(alignedstore (v2f64 VR128:$src), addr:$dst)],
931*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>;
932*9880d681SAndroid Build Coastguard Workerdef MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
933*9880d681SAndroid Build Coastguard Worker                   "movups\t{$src, $dst|$dst, $src}",
934*9880d681SAndroid Build Coastguard Worker                   [(store (v4f32 VR128:$src), addr:$dst)],
935*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>;
936*9880d681SAndroid Build Coastguard Workerdef MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
937*9880d681SAndroid Build Coastguard Worker                   "movupd\t{$src, $dst|$dst, $src}",
938*9880d681SAndroid Build Coastguard Worker                   [(store (v2f64 VR128:$src), addr:$dst)],
939*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>;
940*9880d681SAndroid Build Coastguard Worker} // SchedRW
941*9880d681SAndroid Build Coastguard Worker
942*9880d681SAndroid Build Coastguard Worker// For disassembler
943*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
944*9880d681SAndroid Build Coastguard Worker    SchedRW = [WriteFShuffle] in {
945*9880d681SAndroid Build Coastguard Worker  def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
946*9880d681SAndroid Build Coastguard Worker                         "movaps\t{$src, $dst|$dst, $src}", [],
947*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVA_P_RR>;
948*9880d681SAndroid Build Coastguard Worker  def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
949*9880d681SAndroid Build Coastguard Worker                         "movapd\t{$src, $dst|$dst, $src}", [],
950*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVA_P_RR>;
951*9880d681SAndroid Build Coastguard Worker  def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
952*9880d681SAndroid Build Coastguard Worker                         "movups\t{$src, $dst|$dst, $src}", [],
953*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVU_P_RR>;
954*9880d681SAndroid Build Coastguard Worker  def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
955*9880d681SAndroid Build Coastguard Worker                         "movupd\t{$src, $dst|$dst, $src}", [],
956*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVU_P_RR>;
957*9880d681SAndroid Build Coastguard Worker}
958*9880d681SAndroid Build Coastguard Worker
959*9880d681SAndroid Build Coastguard Worker// Use vmovaps/vmovups for AVX integer load/store.
960*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
961*9880d681SAndroid Build Coastguard Worker  // 128-bit load/store
962*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedloadv2i64 addr:$src),
963*9880d681SAndroid Build Coastguard Worker            (VMOVAPSrm addr:$src)>;
964*9880d681SAndroid Build Coastguard Worker  def : Pat<(loadv2i64 addr:$src),
965*9880d681SAndroid Build Coastguard Worker            (VMOVUPSrm addr:$src)>;
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
968*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, VR128:$src)>;
969*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
970*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, VR128:$src)>;
971*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2i64 VR128:$src), addr:$dst),
972*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, VR128:$src)>;
973*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i32 VR128:$src), addr:$dst),
974*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, VR128:$src)>;
975*9880d681SAndroid Build Coastguard Worker
976*9880d681SAndroid Build Coastguard Worker  // 256-bit load/store
977*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedloadv4i64 addr:$src),
978*9880d681SAndroid Build Coastguard Worker            (VMOVAPSYrm addr:$src)>;
979*9880d681SAndroid Build Coastguard Worker  def : Pat<(loadv4i64 addr:$src),
980*9880d681SAndroid Build Coastguard Worker            (VMOVUPSYrm addr:$src)>;
981*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
982*9880d681SAndroid Build Coastguard Worker            (VMOVAPSYmr addr:$dst, VR256:$src)>;
983*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
984*9880d681SAndroid Build Coastguard Worker            (VMOVAPSYmr addr:$dst, VR256:$src)>;
985*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i64 VR256:$src), addr:$dst),
986*9880d681SAndroid Build Coastguard Worker            (VMOVUPSYmr addr:$dst, VR256:$src)>;
987*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v8i32 VR256:$src), addr:$dst),
988*9880d681SAndroid Build Coastguard Worker            (VMOVUPSYmr addr:$dst, VR256:$src)>;
989*9880d681SAndroid Build Coastguard Worker
990*9880d681SAndroid Build Coastguard Worker  // Special patterns for storing subvector extracts of lower 128-bits
991*9880d681SAndroid Build Coastguard Worker  // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
992*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v2f64 (extract_subvector
993*9880d681SAndroid Build Coastguard Worker                                  (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
994*9880d681SAndroid Build Coastguard Worker            (VMOVAPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
995*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v4f32 (extract_subvector
996*9880d681SAndroid Build Coastguard Worker                                  (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
997*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
998*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v2i64 (extract_subvector
999*9880d681SAndroid Build Coastguard Worker                                  (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1000*9880d681SAndroid Build Coastguard Worker            (VMOVAPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1001*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v4i32 (extract_subvector
1002*9880d681SAndroid Build Coastguard Worker                                  (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1003*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1004*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v8i16 (extract_subvector
1005*9880d681SAndroid Build Coastguard Worker                                  (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1006*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1007*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v16i8 (extract_subvector
1008*9880d681SAndroid Build Coastguard Worker                                  (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1009*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1010*9880d681SAndroid Build Coastguard Worker
1011*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2f64 (extract_subvector
1012*9880d681SAndroid Build Coastguard Worker                           (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1013*9880d681SAndroid Build Coastguard Worker            (VMOVUPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1014*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4f32 (extract_subvector
1015*9880d681SAndroid Build Coastguard Worker                           (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1016*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1017*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2i64 (extract_subvector
1018*9880d681SAndroid Build Coastguard Worker                           (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1019*9880d681SAndroid Build Coastguard Worker            (VMOVUPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1020*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i32 (extract_subvector
1021*9880d681SAndroid Build Coastguard Worker                           (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1022*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1023*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v8i16 (extract_subvector
1024*9880d681SAndroid Build Coastguard Worker                           (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1025*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1026*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v16i8 (extract_subvector
1027*9880d681SAndroid Build Coastguard Worker                           (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1028*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1029*9880d681SAndroid Build Coastguard Worker}
1030*9880d681SAndroid Build Coastguard Worker
1031*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
1032*9880d681SAndroid Build Coastguard Worker  // 128-bit load/store
1033*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1034*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, VR128:$src)>;
1035*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1036*9880d681SAndroid Build Coastguard Worker            (VMOVAPSmr addr:$dst, VR128:$src)>;
1037*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1038*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, VR128:$src)>;
1039*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1040*9880d681SAndroid Build Coastguard Worker            (VMOVUPSmr addr:$dst, VR128:$src)>;
1041*9880d681SAndroid Build Coastguard Worker
1042*9880d681SAndroid Build Coastguard Worker  // 256-bit load/store
1043*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
1044*9880d681SAndroid Build Coastguard Worker            (VMOVAPSYmr addr:$dst, VR256:$src)>;
1045*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
1046*9880d681SAndroid Build Coastguard Worker            (VMOVAPSYmr addr:$dst, VR256:$src)>;
1047*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v16i16 VR256:$src), addr:$dst),
1048*9880d681SAndroid Build Coastguard Worker            (VMOVUPSYmr addr:$dst, VR256:$src)>;
1049*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v32i8 VR256:$src), addr:$dst),
1050*9880d681SAndroid Build Coastguard Worker            (VMOVUPSYmr addr:$dst, VR256:$src)>;
1051*9880d681SAndroid Build Coastguard Worker}
1052*9880d681SAndroid Build Coastguard Worker
1053*9880d681SAndroid Build Coastguard Worker// Use movaps / movups for SSE integer load / store (one byte shorter).
1054*9880d681SAndroid Build Coastguard Worker// The instructions selected below are then converted to MOVDQA/MOVDQU
1055*9880d681SAndroid Build Coastguard Worker// during the SSE domain pass.
1056*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
1057*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedloadv2i64 addr:$src),
1058*9880d681SAndroid Build Coastguard Worker            (MOVAPSrm addr:$src)>;
1059*9880d681SAndroid Build Coastguard Worker  def : Pat<(loadv2i64 addr:$src),
1060*9880d681SAndroid Build Coastguard Worker            (MOVUPSrm addr:$src)>;
1061*9880d681SAndroid Build Coastguard Worker
1062*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1063*9880d681SAndroid Build Coastguard Worker            (MOVAPSmr addr:$dst, VR128:$src)>;
1064*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1065*9880d681SAndroid Build Coastguard Worker            (MOVAPSmr addr:$dst, VR128:$src)>;
1066*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1067*9880d681SAndroid Build Coastguard Worker            (MOVAPSmr addr:$dst, VR128:$src)>;
1068*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1069*9880d681SAndroid Build Coastguard Worker            (MOVAPSmr addr:$dst, VR128:$src)>;
1070*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1071*9880d681SAndroid Build Coastguard Worker            (MOVUPSmr addr:$dst, VR128:$src)>;
1072*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1073*9880d681SAndroid Build Coastguard Worker            (MOVUPSmr addr:$dst, VR128:$src)>;
1074*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1075*9880d681SAndroid Build Coastguard Worker            (MOVUPSmr addr:$dst, VR128:$src)>;
1076*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1077*9880d681SAndroid Build Coastguard Worker            (MOVUPSmr addr:$dst, VR128:$src)>;
1078*9880d681SAndroid Build Coastguard Worker}
1079*9880d681SAndroid Build Coastguard Worker
1080*9880d681SAndroid Build Coastguard Worker// Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
1081*9880d681SAndroid Build Coastguard Worker// bits are disregarded. FIXME: Set encoding to pseudo!
1082*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1083*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
1084*9880d681SAndroid Build Coastguard Worker  def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1085*9880d681SAndroid Build Coastguard Worker                         "movaps\t{$src, $dst|$dst, $src}",
1086*9880d681SAndroid Build Coastguard Worker                         [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1087*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVA_P_RM>, VEX;
1088*9880d681SAndroid Build Coastguard Worker  def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1089*9880d681SAndroid Build Coastguard Worker                         "movapd\t{$src, $dst|$dst, $src}",
1090*9880d681SAndroid Build Coastguard Worker                         [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1091*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVA_P_RM>, VEX;
1092*9880d681SAndroid Build Coastguard Worker  def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1093*9880d681SAndroid Build Coastguard Worker                       "movaps\t{$src, $dst|$dst, $src}",
1094*9880d681SAndroid Build Coastguard Worker                       [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1095*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_MOVA_P_RM>;
1096*9880d681SAndroid Build Coastguard Worker  def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1097*9880d681SAndroid Build Coastguard Worker                       "movapd\t{$src, $dst|$dst, $src}",
1098*9880d681SAndroid Build Coastguard Worker                       [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1099*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_MOVA_P_RM>;
1100*9880d681SAndroid Build Coastguard Worker}
1101*9880d681SAndroid Build Coastguard Worker}
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1104*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Move Low packed FP Instructions
1105*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Workermulticlass sse12_mov_hilo_packed_base<bits<8>opc, SDNode psnode, SDNode pdnode,
1108*9880d681SAndroid Build Coastguard Worker                                      string base_opc, string asm_opr,
1109*9880d681SAndroid Build Coastguard Worker                                      InstrItinClass itin> {
1110*9880d681SAndroid Build Coastguard Worker  def PSrm : PI<opc, MRMSrcMem,
1111*9880d681SAndroid Build Coastguard Worker         (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1112*9880d681SAndroid Build Coastguard Worker         !strconcat(base_opc, "s", asm_opr),
1113*9880d681SAndroid Build Coastguard Worker     [(set VR128:$dst,
1114*9880d681SAndroid Build Coastguard Worker       (psnode VR128:$src1,
1115*9880d681SAndroid Build Coastguard Worker              (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1116*9880d681SAndroid Build Coastguard Worker              itin, SSEPackedSingle>, PS,
1117*9880d681SAndroid Build Coastguard Worker     Sched<[WriteFShuffleLd, ReadAfterLd]>;
1118*9880d681SAndroid Build Coastguard Worker
1119*9880d681SAndroid Build Coastguard Worker  def PDrm : PI<opc, MRMSrcMem,
1120*9880d681SAndroid Build Coastguard Worker         (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1121*9880d681SAndroid Build Coastguard Worker         !strconcat(base_opc, "d", asm_opr),
1122*9880d681SAndroid Build Coastguard Worker     [(set VR128:$dst, (v2f64 (pdnode VR128:$src1,
1123*9880d681SAndroid Build Coastguard Worker                              (scalar_to_vector (loadf64 addr:$src2)))))],
1124*9880d681SAndroid Build Coastguard Worker              itin, SSEPackedDouble>, PD,
1125*9880d681SAndroid Build Coastguard Worker     Sched<[WriteFShuffleLd, ReadAfterLd]>;
1126*9880d681SAndroid Build Coastguard Worker
1127*9880d681SAndroid Build Coastguard Worker}
1128*9880d681SAndroid Build Coastguard Worker
1129*9880d681SAndroid Build Coastguard Workermulticlass sse12_mov_hilo_packed<bits<8>opc, SDNode psnode, SDNode pdnode,
1130*9880d681SAndroid Build Coastguard Worker                                 string base_opc, InstrItinClass itin> {
1131*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in
1132*9880d681SAndroid Build Coastguard Worker    defm V#NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1133*9880d681SAndroid Build Coastguard Worker                                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1134*9880d681SAndroid Build Coastguard Worker                                    itin>, VEX_4V;
1135*9880d681SAndroid Build Coastguard Worker
1136*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in
1137*9880d681SAndroid Build Coastguard Worker    defm NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1138*9880d681SAndroid Build Coastguard Worker                                    "\t{$src2, $dst|$dst, $src2}",
1139*9880d681SAndroid Build Coastguard Worker                                    itin>;
1140*9880d681SAndroid Build Coastguard Worker}
1141*9880d681SAndroid Build Coastguard Worker
1142*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {
1143*9880d681SAndroid Build Coastguard Worker  defm MOVL : sse12_mov_hilo_packed<0x12, X86Movlps, X86Movlpd, "movlp",
1144*9880d681SAndroid Build Coastguard Worker                                    IIC_SSE_MOV_LH>;
1145*9880d681SAndroid Build Coastguard Worker}
1146*9880d681SAndroid Build Coastguard Worker
1147*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteStore] in {
1148*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1149*9880d681SAndroid Build Coastguard Workerdef VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1150*9880d681SAndroid Build Coastguard Worker                   "movlps\t{$src, $dst|$dst, $src}",
1151*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
1152*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)],
1153*9880d681SAndroid Build Coastguard Worker                                 IIC_SSE_MOV_LH>, VEX;
1154*9880d681SAndroid Build Coastguard Workerdef VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1155*9880d681SAndroid Build Coastguard Worker                   "movlpd\t{$src, $dst|$dst, $src}",
1156*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt (v2f64 VR128:$src),
1157*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)],
1158*9880d681SAndroid Build Coastguard Worker                                 IIC_SSE_MOV_LH>, VEX;
1159*9880d681SAndroid Build Coastguard Worker}// UseAVX
1160*9880d681SAndroid Build Coastguard Workerdef MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1161*9880d681SAndroid Build Coastguard Worker                   "movlps\t{$src, $dst|$dst, $src}",
1162*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
1163*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)],
1164*9880d681SAndroid Build Coastguard Worker                                 IIC_SSE_MOV_LH>;
1165*9880d681SAndroid Build Coastguard Workerdef MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1166*9880d681SAndroid Build Coastguard Worker                   "movlpd\t{$src, $dst|$dst, $src}",
1167*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt (v2f64 VR128:$src),
1168*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)],
1169*9880d681SAndroid Build Coastguard Worker                                 IIC_SSE_MOV_LH>;
1170*9880d681SAndroid Build Coastguard Worker} // SchedRW
1171*9880d681SAndroid Build Coastguard Worker
1172*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1173*9880d681SAndroid Build Coastguard Worker  // Shuffle with VMOVLPS
1174*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1175*9880d681SAndroid Build Coastguard Worker            (VMOVLPSrm VR128:$src1, addr:$src2)>;
1176*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1177*9880d681SAndroid Build Coastguard Worker            (VMOVLPSrm VR128:$src1, addr:$src2)>;
1178*9880d681SAndroid Build Coastguard Worker
1179*9880d681SAndroid Build Coastguard Worker  // Shuffle with VMOVLPD
1180*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1181*9880d681SAndroid Build Coastguard Worker            (VMOVLPDrm VR128:$src1, addr:$src2)>;
1182*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1183*9880d681SAndroid Build Coastguard Worker            (VMOVLPDrm VR128:$src1, addr:$src2)>;
1184*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movsd VR128:$src1,
1185*9880d681SAndroid Build Coastguard Worker                             (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1186*9880d681SAndroid Build Coastguard Worker            (VMOVLPDrm VR128:$src1, addr:$src2)>;
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker  // Store patterns
1189*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1190*9880d681SAndroid Build Coastguard Worker                   addr:$src1),
1191*9880d681SAndroid Build Coastguard Worker            (VMOVLPSmr addr:$src1, VR128:$src2)>;
1192*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i32 (X86Movlps
1193*9880d681SAndroid Build Coastguard Worker                   (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1194*9880d681SAndroid Build Coastguard Worker            (VMOVLPSmr addr:$src1, VR128:$src2)>;
1195*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1196*9880d681SAndroid Build Coastguard Worker                   addr:$src1),
1197*9880d681SAndroid Build Coastguard Worker            (VMOVLPDmr addr:$src1, VR128:$src2)>;
1198*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1199*9880d681SAndroid Build Coastguard Worker                   addr:$src1),
1200*9880d681SAndroid Build Coastguard Worker            (VMOVLPDmr addr:$src1, VR128:$src2)>;
1201*9880d681SAndroid Build Coastguard Worker}
1202*9880d681SAndroid Build Coastguard Worker
1203*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
1204*9880d681SAndroid Build Coastguard Worker  // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1205*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (i64 (extractelt (bc_v2i64 (v4f32 VR128:$src2)),
1206*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$src1),
1207*9880d681SAndroid Build Coastguard Worker            (MOVLPSmr addr:$src1, VR128:$src2)>;
1208*9880d681SAndroid Build Coastguard Worker
1209*9880d681SAndroid Build Coastguard Worker  // Shuffle with MOVLPS
1210*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1211*9880d681SAndroid Build Coastguard Worker            (MOVLPSrm VR128:$src1, addr:$src2)>;
1212*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1213*9880d681SAndroid Build Coastguard Worker            (MOVLPSrm VR128:$src1, addr:$src2)>;
1214*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movlps VR128:$src1,
1215*9880d681SAndroid Build Coastguard Worker                      (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1216*9880d681SAndroid Build Coastguard Worker            (MOVLPSrm VR128:$src1, addr:$src2)>;
1217*9880d681SAndroid Build Coastguard Worker
1218*9880d681SAndroid Build Coastguard Worker  // Store patterns
1219*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1220*9880d681SAndroid Build Coastguard Worker                                      addr:$src1),
1221*9880d681SAndroid Build Coastguard Worker            (MOVLPSmr addr:$src1, VR128:$src2)>;
1222*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v4i32 (X86Movlps
1223*9880d681SAndroid Build Coastguard Worker                   (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1224*9880d681SAndroid Build Coastguard Worker                              addr:$src1),
1225*9880d681SAndroid Build Coastguard Worker            (MOVLPSmr addr:$src1, VR128:$src2)>;
1226*9880d681SAndroid Build Coastguard Worker}
1227*9880d681SAndroid Build Coastguard Worker
1228*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
1229*9880d681SAndroid Build Coastguard Worker  // Shuffle with MOVLPD
1230*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1231*9880d681SAndroid Build Coastguard Worker            (MOVLPDrm VR128:$src1, addr:$src2)>;
1232*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1233*9880d681SAndroid Build Coastguard Worker            (MOVLPDrm VR128:$src1, addr:$src2)>;
1234*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Movsd VR128:$src1,
1235*9880d681SAndroid Build Coastguard Worker                             (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1236*9880d681SAndroid Build Coastguard Worker            (MOVLPDrm VR128:$src1, addr:$src2)>;
1237*9880d681SAndroid Build Coastguard Worker
1238*9880d681SAndroid Build Coastguard Worker  // Store patterns
1239*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1240*9880d681SAndroid Build Coastguard Worker                           addr:$src1),
1241*9880d681SAndroid Build Coastguard Worker            (MOVLPDmr addr:$src1, VR128:$src2)>;
1242*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1243*9880d681SAndroid Build Coastguard Worker                           addr:$src1),
1244*9880d681SAndroid Build Coastguard Worker            (MOVLPDmr addr:$src1, VR128:$src2)>;
1245*9880d681SAndroid Build Coastguard Worker}
1246*9880d681SAndroid Build Coastguard Worker
1247*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1248*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Move Hi packed FP Instructions
1249*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1250*9880d681SAndroid Build Coastguard Worker
1251*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {
1252*9880d681SAndroid Build Coastguard Worker  defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Movlhpd, "movhp",
1253*9880d681SAndroid Build Coastguard Worker                                    IIC_SSE_MOV_LH>;
1254*9880d681SAndroid Build Coastguard Worker}
1255*9880d681SAndroid Build Coastguard Worker
1256*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteStore] in {
1257*9880d681SAndroid Build Coastguard Worker// v2f64 extract element 1 is always custom lowered to unpack high to low
1258*9880d681SAndroid Build Coastguard Worker// and extract element 0 so the non-store version isn't too horrible.
1259*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1260*9880d681SAndroid Build Coastguard Workerdef VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1261*9880d681SAndroid Build Coastguard Worker                   "movhps\t{$src, $dst|$dst, $src}",
1262*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt
1263*9880d681SAndroid Build Coastguard Worker                                 (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1264*9880d681SAndroid Build Coastguard Worker                                            (bc_v2f64 (v4f32 VR128:$src))),
1265*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1266*9880d681SAndroid Build Coastguard Workerdef VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1267*9880d681SAndroid Build Coastguard Worker                   "movhpd\t{$src, $dst|$dst, $src}",
1268*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt
1269*9880d681SAndroid Build Coastguard Worker                                 (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1270*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1271*9880d681SAndroid Build Coastguard Worker} // UseAVX
1272*9880d681SAndroid Build Coastguard Workerdef MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1273*9880d681SAndroid Build Coastguard Worker                   "movhps\t{$src, $dst|$dst, $src}",
1274*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt
1275*9880d681SAndroid Build Coastguard Worker                                 (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1276*9880d681SAndroid Build Coastguard Worker                                            (bc_v2f64 (v4f32 VR128:$src))),
1277*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1278*9880d681SAndroid Build Coastguard Workerdef MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1279*9880d681SAndroid Build Coastguard Worker                   "movhpd\t{$src, $dst|$dst, $src}",
1280*9880d681SAndroid Build Coastguard Worker                   [(store (f64 (extractelt
1281*9880d681SAndroid Build Coastguard Worker                                 (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1282*9880d681SAndroid Build Coastguard Worker                                 (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1283*9880d681SAndroid Build Coastguard Worker} // SchedRW
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1286*9880d681SAndroid Build Coastguard Worker  // VMOVHPS patterns
1287*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movlhps VR128:$src1,
1288*9880d681SAndroid Build Coastguard Worker                 (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1289*9880d681SAndroid Build Coastguard Worker            (VMOVHPSrm VR128:$src1, addr:$src2)>;
1290*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movlhps VR128:$src1,
1291*9880d681SAndroid Build Coastguard Worker                 (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1292*9880d681SAndroid Build Coastguard Worker            (VMOVHPSrm VR128:$src1, addr:$src2)>;
1293*9880d681SAndroid Build Coastguard Worker
1294*9880d681SAndroid Build Coastguard Worker  // VMOVHPD patterns
1295*9880d681SAndroid Build Coastguard Worker
1296*9880d681SAndroid Build Coastguard Worker  // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1297*9880d681SAndroid Build Coastguard Worker  // is during lowering, where it's not possible to recognize the load fold
1298*9880d681SAndroid Build Coastguard Worker  // cause it has two uses through a bitcast. One use disappears at isel time
1299*9880d681SAndroid Build Coastguard Worker  // and the fold opportunity reappears.
1300*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1301*9880d681SAndroid Build Coastguard Worker                      (scalar_to_vector (loadf64 addr:$src2)))),
1302*9880d681SAndroid Build Coastguard Worker            (VMOVHPDrm VR128:$src1, addr:$src2)>;
1303*9880d681SAndroid Build Coastguard Worker  // Also handle an i64 load because that may get selected as a faster way to
1304*9880d681SAndroid Build Coastguard Worker  // load the data.
1305*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1306*9880d681SAndroid Build Coastguard Worker                      (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1307*9880d681SAndroid Build Coastguard Worker            (VMOVHPDrm VR128:$src1, addr:$src2)>;
1308*9880d681SAndroid Build Coastguard Worker
1309*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (f64 (extractelt
1310*9880d681SAndroid Build Coastguard Worker                          (v2f64 (X86VPermilpi VR128:$src, (i8 1))),
1311*9880d681SAndroid Build Coastguard Worker                          (iPTR 0))), addr:$dst),
1312*9880d681SAndroid Build Coastguard Worker            (VMOVHPDmr addr:$dst, VR128:$src)>;
1313*9880d681SAndroid Build Coastguard Worker}
1314*9880d681SAndroid Build Coastguard Worker
1315*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
1316*9880d681SAndroid Build Coastguard Worker  // MOVHPS patterns
1317*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movlhps VR128:$src1,
1318*9880d681SAndroid Build Coastguard Worker                 (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1319*9880d681SAndroid Build Coastguard Worker            (MOVHPSrm VR128:$src1, addr:$src2)>;
1320*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movlhps VR128:$src1,
1321*9880d681SAndroid Build Coastguard Worker                 (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1322*9880d681SAndroid Build Coastguard Worker            (MOVHPSrm VR128:$src1, addr:$src2)>;
1323*9880d681SAndroid Build Coastguard Worker}
1324*9880d681SAndroid Build Coastguard Worker
1325*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
1326*9880d681SAndroid Build Coastguard Worker  // MOVHPD patterns
1327*9880d681SAndroid Build Coastguard Worker
1328*9880d681SAndroid Build Coastguard Worker  // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1329*9880d681SAndroid Build Coastguard Worker  // is during lowering, where it's not possible to recognize the load fold
1330*9880d681SAndroid Build Coastguard Worker  // cause it has two uses through a bitcast. One use disappears at isel time
1331*9880d681SAndroid Build Coastguard Worker  // and the fold opportunity reappears.
1332*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1333*9880d681SAndroid Build Coastguard Worker                      (scalar_to_vector (loadf64 addr:$src2)))),
1334*9880d681SAndroid Build Coastguard Worker            (MOVHPDrm VR128:$src1, addr:$src2)>;
1335*9880d681SAndroid Build Coastguard Worker  // Also handle an i64 load because that may get selected as a faster way to
1336*9880d681SAndroid Build Coastguard Worker  // load the data.
1337*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1338*9880d681SAndroid Build Coastguard Worker                      (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1339*9880d681SAndroid Build Coastguard Worker            (MOVHPDrm VR128:$src1, addr:$src2)>;
1340*9880d681SAndroid Build Coastguard Worker
1341*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (f64 (extractelt
1342*9880d681SAndroid Build Coastguard Worker                          (v2f64 (X86Shufp VR128:$src, VR128:$src, (i8 1))),
1343*9880d681SAndroid Build Coastguard Worker                          (iPTR 0))), addr:$dst),
1344*9880d681SAndroid Build Coastguard Worker            (MOVHPDmr addr:$dst, VR128:$src)>;
1345*9880d681SAndroid Build Coastguard Worker}
1346*9880d681SAndroid Build Coastguard Worker
1347*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1348*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1349*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1350*9880d681SAndroid Build Coastguard Worker
1351*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20, Predicates = [UseAVX] in {
1352*9880d681SAndroid Build Coastguard Worker  def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1353*9880d681SAndroid Build Coastguard Worker                                       (ins VR128:$src1, VR128:$src2),
1354*9880d681SAndroid Build Coastguard Worker                      "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1355*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
1356*9880d681SAndroid Build Coastguard Worker                        (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1357*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOV_LH>,
1358*9880d681SAndroid Build Coastguard Worker                      VEX_4V, Sched<[WriteFShuffle]>;
1359*9880d681SAndroid Build Coastguard Worker  def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1360*9880d681SAndroid Build Coastguard Worker                                       (ins VR128:$src1, VR128:$src2),
1361*9880d681SAndroid Build Coastguard Worker                      "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1362*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
1363*9880d681SAndroid Build Coastguard Worker                        (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1364*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOV_LH>,
1365*9880d681SAndroid Build Coastguard Worker                      VEX_4V, Sched<[WriteFShuffle]>;
1366*9880d681SAndroid Build Coastguard Worker}
1367*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1368*9880d681SAndroid Build Coastguard Worker  def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1369*9880d681SAndroid Build Coastguard Worker                                       (ins VR128:$src1, VR128:$src2),
1370*9880d681SAndroid Build Coastguard Worker                      "movlhps\t{$src2, $dst|$dst, $src2}",
1371*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
1372*9880d681SAndroid Build Coastguard Worker                        (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1373*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1374*9880d681SAndroid Build Coastguard Worker  def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1375*9880d681SAndroid Build Coastguard Worker                                       (ins VR128:$src1, VR128:$src2),
1376*9880d681SAndroid Build Coastguard Worker                      "movhlps\t{$src2, $dst|$dst, $src2}",
1377*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
1378*9880d681SAndroid Build Coastguard Worker                        (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1379*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1380*9880d681SAndroid Build Coastguard Worker}
1381*9880d681SAndroid Build Coastguard Worker
1382*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1383*9880d681SAndroid Build Coastguard Worker  // MOVLHPS patterns
1384*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1385*9880d681SAndroid Build Coastguard Worker            (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1386*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1387*9880d681SAndroid Build Coastguard Worker            (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1388*9880d681SAndroid Build Coastguard Worker
1389*9880d681SAndroid Build Coastguard Worker  // MOVHLPS patterns
1390*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1391*9880d681SAndroid Build Coastguard Worker            (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1392*9880d681SAndroid Build Coastguard Worker}
1393*9880d681SAndroid Build Coastguard Worker
1394*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
1395*9880d681SAndroid Build Coastguard Worker  // MOVLHPS patterns
1396*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1397*9880d681SAndroid Build Coastguard Worker            (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1398*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1399*9880d681SAndroid Build Coastguard Worker            (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1400*9880d681SAndroid Build Coastguard Worker
1401*9880d681SAndroid Build Coastguard Worker  // MOVHLPS patterns
1402*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1403*9880d681SAndroid Build Coastguard Worker            (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1404*9880d681SAndroid Build Coastguard Worker}
1405*9880d681SAndroid Build Coastguard Worker
1406*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1407*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Conversion Instructions
1408*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
1409*9880d681SAndroid Build Coastguard Worker
1410*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_PD : OpndItins<
1411*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_PD_RR, IIC_SSE_CVT_PD_RM
1412*9880d681SAndroid Build Coastguard Worker>;
1413*9880d681SAndroid Build Coastguard Worker
1414*9880d681SAndroid Build Coastguard Workerlet Sched = WriteCvtI2F in
1415*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_PS : OpndItins<
1416*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_PS_RR, IIC_SSE_CVT_PS_RM
1417*9880d681SAndroid Build Coastguard Worker>;
1418*9880d681SAndroid Build Coastguard Worker
1419*9880d681SAndroid Build Coastguard Workerlet Sched = WriteCvtI2F in
1420*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_Scalar : OpndItins<
1421*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_Scalar_RR, IIC_SSE_CVT_Scalar_RM
1422*9880d681SAndroid Build Coastguard Worker>;
1423*9880d681SAndroid Build Coastguard Worker
1424*9880d681SAndroid Build Coastguard Workerlet Sched = WriteCvtF2I in
1425*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_SS2SI_32 : OpndItins<
1426*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_SS2SI32_RR, IIC_SSE_CVT_SS2SI32_RM
1427*9880d681SAndroid Build Coastguard Worker>;
1428*9880d681SAndroid Build Coastguard Worker
1429*9880d681SAndroid Build Coastguard Workerlet Sched = WriteCvtF2I in
1430*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_SS2SI_64 : OpndItins<
1431*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_SS2SI64_RR, IIC_SSE_CVT_SS2SI64_RM
1432*9880d681SAndroid Build Coastguard Worker>;
1433*9880d681SAndroid Build Coastguard Worker
1434*9880d681SAndroid Build Coastguard Workerlet Sched = WriteCvtF2I in
1435*9880d681SAndroid Build Coastguard Workerdef SSE_CVT_SD2SI : OpndItins<
1436*9880d681SAndroid Build Coastguard Worker  IIC_SSE_CVT_SD2SI_RR, IIC_SSE_CVT_SD2SI_RM
1437*9880d681SAndroid Build Coastguard Worker>;
1438*9880d681SAndroid Build Coastguard Worker
1439*9880d681SAndroid Build Coastguard Worker// FIXME: We probably want to match the rm form only when optimizing for
1440*9880d681SAndroid Build Coastguard Worker// size, to avoid false depenendecies (see sse_fp_unop_s for details)
1441*9880d681SAndroid Build Coastguard Workermulticlass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1442*9880d681SAndroid Build Coastguard Worker                     SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1443*9880d681SAndroid Build Coastguard Worker                     string asm, OpndItins itins> {
1444*9880d681SAndroid Build Coastguard Worker  def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1445*9880d681SAndroid Build Coastguard Worker                        [(set DstRC:$dst, (OpNode SrcRC:$src))],
1446*9880d681SAndroid Build Coastguard Worker                        itins.rr>, Sched<[itins.Sched]>;
1447*9880d681SAndroid Build Coastguard Worker  def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1448*9880d681SAndroid Build Coastguard Worker                        [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1449*9880d681SAndroid Build Coastguard Worker                        itins.rm>, Sched<[itins.Sched.Folded]>;
1450*9880d681SAndroid Build Coastguard Worker}
1451*9880d681SAndroid Build Coastguard Worker
1452*9880d681SAndroid Build Coastguard Workermulticlass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1453*9880d681SAndroid Build Coastguard Worker                       X86MemOperand x86memop, string asm, Domain d,
1454*9880d681SAndroid Build Coastguard Worker                       OpndItins itins> {
1455*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in {
1456*9880d681SAndroid Build Coastguard Worker  def rr : I<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1457*9880d681SAndroid Build Coastguard Worker             [], itins.rr, d>, Sched<[itins.Sched]>;
1458*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
1459*9880d681SAndroid Build Coastguard Worker  def rm : I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1460*9880d681SAndroid Build Coastguard Worker             [], itins.rm, d>, Sched<[itins.Sched.Folded]>;
1461*9880d681SAndroid Build Coastguard Worker}
1462*9880d681SAndroid Build Coastguard Worker}
1463*9880d681SAndroid Build Coastguard Worker
1464*9880d681SAndroid Build Coastguard Worker// FIXME: We probably want to match the rm form only when optimizing for
1465*9880d681SAndroid Build Coastguard Worker// size, to avoid false depenendecies (see sse_fp_unop_s for details)
1466*9880d681SAndroid Build Coastguard Workermulticlass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1467*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, string asm> {
1468*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Predicates = [UseAVX] in {
1469*9880d681SAndroid Build Coastguard Worker  def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1470*9880d681SAndroid Build Coastguard Worker              !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1471*9880d681SAndroid Build Coastguard Worker           Sched<[WriteCvtI2F]>;
1472*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
1473*9880d681SAndroid Build Coastguard Worker  def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1474*9880d681SAndroid Build Coastguard Worker              (ins DstRC:$src1, x86memop:$src),
1475*9880d681SAndroid Build Coastguard Worker              !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1476*9880d681SAndroid Build Coastguard Worker           Sched<[WriteCvtI2FLd, ReadAfterLd]>;
1477*9880d681SAndroid Build Coastguard Worker} // hasSideEffects = 0
1478*9880d681SAndroid Build Coastguard Worker}
1479*9880d681SAndroid Build Coastguard Worker
1480*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1481*9880d681SAndroid Build Coastguard Workerdefm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1482*9880d681SAndroid Build Coastguard Worker                                "cvttss2si\t{$src, $dst|$dst, $src}",
1483*9880d681SAndroid Build Coastguard Worker                                SSE_CVT_SS2SI_32>,
1484*9880d681SAndroid Build Coastguard Worker                                XS, VEX, VEX_LIG;
1485*9880d681SAndroid Build Coastguard Workerdefm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1486*9880d681SAndroid Build Coastguard Worker                                "cvttss2si\t{$src, $dst|$dst, $src}",
1487*9880d681SAndroid Build Coastguard Worker                                SSE_CVT_SS2SI_64>,
1488*9880d681SAndroid Build Coastguard Worker                                XS, VEX, VEX_W, VEX_LIG;
1489*9880d681SAndroid Build Coastguard Workerdefm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1490*9880d681SAndroid Build Coastguard Worker                                "cvttsd2si\t{$src, $dst|$dst, $src}",
1491*9880d681SAndroid Build Coastguard Worker                                SSE_CVT_SD2SI>,
1492*9880d681SAndroid Build Coastguard Worker                                XD, VEX, VEX_LIG;
1493*9880d681SAndroid Build Coastguard Workerdefm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1494*9880d681SAndroid Build Coastguard Worker                                "cvttsd2si\t{$src, $dst|$dst, $src}",
1495*9880d681SAndroid Build Coastguard Worker                                SSE_CVT_SD2SI>,
1496*9880d681SAndroid Build Coastguard Worker                                XD, VEX, VEX_W, VEX_LIG;
1497*9880d681SAndroid Build Coastguard Worker
1498*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1499*9880d681SAndroid Build Coastguard Worker                (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1500*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1501*9880d681SAndroid Build Coastguard Worker                (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1502*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1503*9880d681SAndroid Build Coastguard Worker                (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1504*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1505*9880d681SAndroid Build Coastguard Worker                (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1506*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1507*9880d681SAndroid Build Coastguard Worker                (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1508*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1509*9880d681SAndroid Build Coastguard Worker                (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1510*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1511*9880d681SAndroid Build Coastguard Worker                (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1512*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1513*9880d681SAndroid Build Coastguard Worker                (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1514*9880d681SAndroid Build Coastguard Worker}
1515*9880d681SAndroid Build Coastguard Worker// The assembler can recognize rr 64-bit instructions by seeing a rxx
1516*9880d681SAndroid Build Coastguard Worker// register, but the same isn't true when only using memory operands,
1517*9880d681SAndroid Build Coastguard Worker// provide other assembly "l" and "q" forms to address this explicitly
1518*9880d681SAndroid Build Coastguard Worker// where appropriate to do so.
1519*9880d681SAndroid Build Coastguard Workerdefm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}">,
1520*9880d681SAndroid Build Coastguard Worker                                  XS, VEX_4V, VEX_LIG;
1521*9880d681SAndroid Build Coastguard Workerdefm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">,
1522*9880d681SAndroid Build Coastguard Worker                                  XS, VEX_4V, VEX_W, VEX_LIG;
1523*9880d681SAndroid Build Coastguard Workerdefm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">,
1524*9880d681SAndroid Build Coastguard Worker                                  XD, VEX_4V, VEX_LIG;
1525*9880d681SAndroid Build Coastguard Workerdefm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
1526*9880d681SAndroid Build Coastguard Worker                                  XD, VEX_4V, VEX_W, VEX_LIG;
1527*9880d681SAndroid Build Coastguard Worker
1528*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1529*9880d681SAndroid Build Coastguard Worker  def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1530*9880d681SAndroid Build Coastguard Worker                (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1531*9880d681SAndroid Build Coastguard Worker  def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1532*9880d681SAndroid Build Coastguard Worker                (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1533*9880d681SAndroid Build Coastguard Worker
1534*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1535*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1536*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1537*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1538*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1539*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1540*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1541*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1542*9880d681SAndroid Build Coastguard Worker
1543*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (sint_to_fp GR32:$src)),
1544*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1545*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (sint_to_fp GR64:$src)),
1546*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1547*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (sint_to_fp GR32:$src)),
1548*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1549*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (sint_to_fp GR64:$src)),
1550*9880d681SAndroid Build Coastguard Worker            (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1551*9880d681SAndroid Build Coastguard Worker}
1552*9880d681SAndroid Build Coastguard Worker
1553*9880d681SAndroid Build Coastguard Workerdefm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1554*9880d681SAndroid Build Coastguard Worker                      "cvttss2si\t{$src, $dst|$dst, $src}",
1555*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_SS2SI_32>, XS;
1556*9880d681SAndroid Build Coastguard Workerdefm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1557*9880d681SAndroid Build Coastguard Worker                      "cvttss2si\t{$src, $dst|$dst, $src}",
1558*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_SS2SI_64>, XS, REX_W;
1559*9880d681SAndroid Build Coastguard Workerdefm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1560*9880d681SAndroid Build Coastguard Worker                      "cvttsd2si\t{$src, $dst|$dst, $src}",
1561*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_SD2SI>, XD;
1562*9880d681SAndroid Build Coastguard Workerdefm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1563*9880d681SAndroid Build Coastguard Worker                      "cvttsd2si\t{$src, $dst|$dst, $src}",
1564*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_SD2SI>, XD, REX_W;
1565*9880d681SAndroid Build Coastguard Workerdefm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1566*9880d681SAndroid Build Coastguard Worker                      "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
1567*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_Scalar>, XS;
1568*9880d681SAndroid Build Coastguard Workerdefm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1569*9880d681SAndroid Build Coastguard Worker                      "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1570*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_Scalar>, XS, REX_W;
1571*9880d681SAndroid Build Coastguard Workerdefm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1572*9880d681SAndroid Build Coastguard Worker                      "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
1573*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_Scalar>, XD;
1574*9880d681SAndroid Build Coastguard Workerdefm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1575*9880d681SAndroid Build Coastguard Worker                      "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1576*9880d681SAndroid Build Coastguard Worker                      SSE_CVT_Scalar>, XD, REX_W;
1577*9880d681SAndroid Build Coastguard Worker
1578*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1579*9880d681SAndroid Build Coastguard Worker                (CVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1580*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1581*9880d681SAndroid Build Coastguard Worker                (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1582*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1583*9880d681SAndroid Build Coastguard Worker                (CVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1584*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1585*9880d681SAndroid Build Coastguard Worker                (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1586*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1587*9880d681SAndroid Build Coastguard Worker                (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1588*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1589*9880d681SAndroid Build Coastguard Worker                (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1590*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1591*9880d681SAndroid Build Coastguard Worker                (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1592*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1593*9880d681SAndroid Build Coastguard Worker                (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1594*9880d681SAndroid Build Coastguard Worker
1595*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
1596*9880d681SAndroid Build Coastguard Worker                (CVTSI2SSrm FR64:$dst, i32mem:$src), 0>;
1597*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1598*9880d681SAndroid Build Coastguard Worker                (CVTSI2SDrm FR64:$dst, i32mem:$src), 0>;
1599*9880d681SAndroid Build Coastguard Worker
1600*9880d681SAndroid Build Coastguard Worker// Conversion Instructions Intrinsics - Match intrinsics which expect MM
1601*9880d681SAndroid Build Coastguard Worker// and/or XMM operand(s).
1602*9880d681SAndroid Build Coastguard Worker
1603*9880d681SAndroid Build Coastguard Worker// FIXME: We probably want to match the rm form only when optimizing for
1604*9880d681SAndroid Build Coastguard Worker// size, to avoid false depenendecies (see sse_fp_unop_s for details)
1605*9880d681SAndroid Build Coastguard Workermulticlass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1606*9880d681SAndroid Build Coastguard Worker                         Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1607*9880d681SAndroid Build Coastguard Worker                         string asm, OpndItins itins> {
1608*9880d681SAndroid Build Coastguard Worker  def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1609*9880d681SAndroid Build Coastguard Worker              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1610*9880d681SAndroid Build Coastguard Worker              [(set DstRC:$dst, (Int SrcRC:$src))], itins.rr>,
1611*9880d681SAndroid Build Coastguard Worker           Sched<[itins.Sched]>;
1612*9880d681SAndroid Build Coastguard Worker  def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1613*9880d681SAndroid Build Coastguard Worker              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1614*9880d681SAndroid Build Coastguard Worker              [(set DstRC:$dst, (Int mem_cpat:$src))], itins.rm>,
1615*9880d681SAndroid Build Coastguard Worker           Sched<[itins.Sched.Folded]>;
1616*9880d681SAndroid Build Coastguard Worker}
1617*9880d681SAndroid Build Coastguard Worker
1618*9880d681SAndroid Build Coastguard Workermulticlass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1619*9880d681SAndroid Build Coastguard Worker                    RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1620*9880d681SAndroid Build Coastguard Worker                    PatFrag ld_frag, string asm, OpndItins itins,
1621*9880d681SAndroid Build Coastguard Worker                    bit Is2Addr = 1> {
1622*9880d681SAndroid Build Coastguard Worker  def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1623*9880d681SAndroid Build Coastguard Worker              !if(Is2Addr,
1624*9880d681SAndroid Build Coastguard Worker                  !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1625*9880d681SAndroid Build Coastguard Worker                  !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1626*9880d681SAndroid Build Coastguard Worker              [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))],
1627*9880d681SAndroid Build Coastguard Worker              itins.rr>, Sched<[itins.Sched]>;
1628*9880d681SAndroid Build Coastguard Worker  def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1629*9880d681SAndroid Build Coastguard Worker              (ins DstRC:$src1, x86memop:$src2),
1630*9880d681SAndroid Build Coastguard Worker              !if(Is2Addr,
1631*9880d681SAndroid Build Coastguard Worker                  !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1632*9880d681SAndroid Build Coastguard Worker                  !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1633*9880d681SAndroid Build Coastguard Worker              [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))],
1634*9880d681SAndroid Build Coastguard Worker              itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
1635*9880d681SAndroid Build Coastguard Worker}
1636*9880d681SAndroid Build Coastguard Worker
1637*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1638*9880d681SAndroid Build Coastguard Workerdefm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1639*9880d681SAndroid Build Coastguard Worker                  int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1640*9880d681SAndroid Build Coastguard Worker                  SSE_CVT_SD2SI>, XD, VEX, VEX_LIG;
1641*9880d681SAndroid Build Coastguard Workerdefm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1642*9880d681SAndroid Build Coastguard Worker                    int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1643*9880d681SAndroid Build Coastguard Worker                    SSE_CVT_SD2SI>, XD, VEX, VEX_W, VEX_LIG;
1644*9880d681SAndroid Build Coastguard Worker}
1645*9880d681SAndroid Build Coastguard Workerdefm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1646*9880d681SAndroid Build Coastguard Worker                 sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD;
1647*9880d681SAndroid Build Coastguard Workerdefm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1648*9880d681SAndroid Build Coastguard Worker                   sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1649*9880d681SAndroid Build Coastguard Worker
1650*9880d681SAndroid Build Coastguard Worker
1651*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
1652*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in {
1653*9880d681SAndroid Build Coastguard Worker  defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1654*9880d681SAndroid Build Coastguard Worker            int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
1655*9880d681SAndroid Build Coastguard Worker            SSE_CVT_Scalar, 0>, XS, VEX_4V;
1656*9880d681SAndroid Build Coastguard Worker  defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1657*9880d681SAndroid Build Coastguard Worker            int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
1658*9880d681SAndroid Build Coastguard Worker            SSE_CVT_Scalar, 0>, XS, VEX_4V,
1659*9880d681SAndroid Build Coastguard Worker            VEX_W;
1660*9880d681SAndroid Build Coastguard Worker  defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1661*9880d681SAndroid Build Coastguard Worker            int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
1662*9880d681SAndroid Build Coastguard Worker            SSE_CVT_Scalar, 0>, XD, VEX_4V;
1663*9880d681SAndroid Build Coastguard Worker  defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1664*9880d681SAndroid Build Coastguard Worker            int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
1665*9880d681SAndroid Build Coastguard Worker            SSE_CVT_Scalar, 0>, XD,
1666*9880d681SAndroid Build Coastguard Worker            VEX_4V, VEX_W;
1667*9880d681SAndroid Build Coastguard Worker  }
1668*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
1669*9880d681SAndroid Build Coastguard Worker    defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1670*9880d681SAndroid Build Coastguard Worker                          int_x86_sse_cvtsi2ss, i32mem, loadi32,
1671*9880d681SAndroid Build Coastguard Worker                          "cvtsi2ss{l}", SSE_CVT_Scalar>, XS;
1672*9880d681SAndroid Build Coastguard Worker    defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1673*9880d681SAndroid Build Coastguard Worker                          int_x86_sse_cvtsi642ss, i64mem, loadi64,
1674*9880d681SAndroid Build Coastguard Worker                          "cvtsi2ss{q}", SSE_CVT_Scalar>, XS, REX_W;
1675*9880d681SAndroid Build Coastguard Worker    defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1676*9880d681SAndroid Build Coastguard Worker                          int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1677*9880d681SAndroid Build Coastguard Worker                          "cvtsi2sd{l}", SSE_CVT_Scalar>, XD;
1678*9880d681SAndroid Build Coastguard Worker    defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1679*9880d681SAndroid Build Coastguard Worker                          int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1680*9880d681SAndroid Build Coastguard Worker                          "cvtsi2sd{q}", SSE_CVT_Scalar>, XD, REX_W;
1681*9880d681SAndroid Build Coastguard Worker  }
1682*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly = 1
1683*9880d681SAndroid Build Coastguard Worker
1684*9880d681SAndroid Build Coastguard Worker/// SSE 1 Only
1685*9880d681SAndroid Build Coastguard Worker
1686*9880d681SAndroid Build Coastguard Worker// Aliases for intrinsics
1687*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
1688*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1689*9880d681SAndroid Build Coastguard Workerdefm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1690*9880d681SAndroid Build Coastguard Worker                                    ssmem, sse_load_f32, "cvttss2si",
1691*9880d681SAndroid Build Coastguard Worker                                    SSE_CVT_SS2SI_32>, XS, VEX;
1692*9880d681SAndroid Build Coastguard Workerdefm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1693*9880d681SAndroid Build Coastguard Worker                                   int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1694*9880d681SAndroid Build Coastguard Worker                                   "cvttss2si", SSE_CVT_SS2SI_64>,
1695*9880d681SAndroid Build Coastguard Worker                                   XS, VEX, VEX_W;
1696*9880d681SAndroid Build Coastguard Workerdefm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1697*9880d681SAndroid Build Coastguard Worker                                    sdmem, sse_load_f64, "cvttsd2si",
1698*9880d681SAndroid Build Coastguard Worker                                    SSE_CVT_SD2SI>, XD, VEX;
1699*9880d681SAndroid Build Coastguard Workerdefm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1700*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1701*9880d681SAndroid Build Coastguard Worker                                  "cvttsd2si", SSE_CVT_SD2SI>,
1702*9880d681SAndroid Build Coastguard Worker                                  XD, VEX, VEX_W;
1703*9880d681SAndroid Build Coastguard Worker}
1704*9880d681SAndroid Build Coastguard Workerdefm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1705*9880d681SAndroid Build Coastguard Worker                                    ssmem, sse_load_f32, "cvttss2si",
1706*9880d681SAndroid Build Coastguard Worker                                    SSE_CVT_SS2SI_32>, XS;
1707*9880d681SAndroid Build Coastguard Workerdefm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1708*9880d681SAndroid Build Coastguard Worker                                   int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1709*9880d681SAndroid Build Coastguard Worker                                   "cvttss2si", SSE_CVT_SS2SI_64>, XS, REX_W;
1710*9880d681SAndroid Build Coastguard Workerdefm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1711*9880d681SAndroid Build Coastguard Worker                                    sdmem, sse_load_f64, "cvttsd2si",
1712*9880d681SAndroid Build Coastguard Worker                                    SSE_CVT_SD2SI>, XD;
1713*9880d681SAndroid Build Coastguard Workerdefm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1714*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1715*9880d681SAndroid Build Coastguard Worker                                  "cvttsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1716*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly = 1
1717*9880d681SAndroid Build Coastguard Worker
1718*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1719*9880d681SAndroid Build Coastguard Workerdefm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1720*9880d681SAndroid Build Coastguard Worker                                  ssmem, sse_load_f32, "cvtss2si",
1721*9880d681SAndroid Build Coastguard Worker                                  SSE_CVT_SS2SI_32>, XS, VEX, VEX_LIG;
1722*9880d681SAndroid Build Coastguard Workerdefm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1723*9880d681SAndroid Build Coastguard Worker                                  ssmem, sse_load_f32, "cvtss2si",
1724*9880d681SAndroid Build Coastguard Worker                                  SSE_CVT_SS2SI_64>, XS, VEX, VEX_W, VEX_LIG;
1725*9880d681SAndroid Build Coastguard Worker}
1726*9880d681SAndroid Build Coastguard Workerdefm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1727*9880d681SAndroid Build Coastguard Worker                               ssmem, sse_load_f32, "cvtss2si",
1728*9880d681SAndroid Build Coastguard Worker                               SSE_CVT_SS2SI_32>, XS;
1729*9880d681SAndroid Build Coastguard Workerdefm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1730*9880d681SAndroid Build Coastguard Worker                                 ssmem, sse_load_f32, "cvtss2si",
1731*9880d681SAndroid Build Coastguard Worker                                 SSE_CVT_SS2SI_64>, XS, REX_W;
1732*9880d681SAndroid Build Coastguard Worker
1733*9880d681SAndroid Build Coastguard Workerdefm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1734*9880d681SAndroid Build Coastguard Worker                               "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1735*9880d681SAndroid Build Coastguard Worker                               SSEPackedSingle, SSE_CVT_PS>,
1736*9880d681SAndroid Build Coastguard Worker                               PS, VEX, Requires<[HasAVX]>;
1737*9880d681SAndroid Build Coastguard Workerdefm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, i256mem,
1738*9880d681SAndroid Build Coastguard Worker                               "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1739*9880d681SAndroid Build Coastguard Worker                               SSEPackedSingle, SSE_CVT_PS>,
1740*9880d681SAndroid Build Coastguard Worker                               PS, VEX, VEX_L, Requires<[HasAVX]>;
1741*9880d681SAndroid Build Coastguard Worker
1742*9880d681SAndroid Build Coastguard Workerdefm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1743*9880d681SAndroid Build Coastguard Worker                            "cvtdq2ps\t{$src, $dst|$dst, $src}",
1744*9880d681SAndroid Build Coastguard Worker                            SSEPackedSingle, SSE_CVT_PS>,
1745*9880d681SAndroid Build Coastguard Worker                            PS, Requires<[UseSSE2]>;
1746*9880d681SAndroid Build Coastguard Worker
1747*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
1748*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1749*9880d681SAndroid Build Coastguard Worker                (VCVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1750*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1751*9880d681SAndroid Build Coastguard Worker                (VCVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1752*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1753*9880d681SAndroid Build Coastguard Worker                (VCVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1754*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1755*9880d681SAndroid Build Coastguard Worker                (VCVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1756*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1757*9880d681SAndroid Build Coastguard Worker                (VCVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1758*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1759*9880d681SAndroid Build Coastguard Worker                (VCVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1760*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1761*9880d681SAndroid Build Coastguard Worker                (VCVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1762*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1763*9880d681SAndroid Build Coastguard Worker                (VCVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1764*9880d681SAndroid Build Coastguard Worker}
1765*9880d681SAndroid Build Coastguard Worker
1766*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1767*9880d681SAndroid Build Coastguard Worker                (CVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1768*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1769*9880d681SAndroid Build Coastguard Worker                (CVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1770*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1771*9880d681SAndroid Build Coastguard Worker                (CVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1772*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1773*9880d681SAndroid Build Coastguard Worker                (CVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1774*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1775*9880d681SAndroid Build Coastguard Worker                (CVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1776*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1777*9880d681SAndroid Build Coastguard Worker                (CVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1778*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1779*9880d681SAndroid Build Coastguard Worker                (CVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1780*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1781*9880d681SAndroid Build Coastguard Worker                (CVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1782*9880d681SAndroid Build Coastguard Worker
1783*9880d681SAndroid Build Coastguard Worker/// SSE 2 Only
1784*9880d681SAndroid Build Coastguard Worker
1785*9880d681SAndroid Build Coastguard Worker// Convert scalar double to scalar single
1786*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Predicates = [UseAVX] in {
1787*9880d681SAndroid Build Coastguard Workerdef VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1788*9880d681SAndroid Build Coastguard Worker                       (ins FR64:$src1, FR64:$src2),
1789*9880d681SAndroid Build Coastguard Worker                      "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
1790*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_Scalar_RR>, VEX_4V, VEX_LIG,
1791*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteCvtF2F]>;
1792*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
1793*9880d681SAndroid Build Coastguard Workerdef VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1794*9880d681SAndroid Build Coastguard Worker                       (ins FR64:$src1, f64mem:$src2),
1795*9880d681SAndroid Build Coastguard Worker                      "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1796*9880d681SAndroid Build Coastguard Worker                      [], IIC_SSE_CVT_Scalar_RM>,
1797*9880d681SAndroid Build Coastguard Worker                      XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG,
1798*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1799*9880d681SAndroid Build Coastguard Worker}
1800*9880d681SAndroid Build Coastguard Worker
1801*9880d681SAndroid Build Coastguard Workerdef : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1802*9880d681SAndroid Build Coastguard Worker          Requires<[UseAVX]>;
1803*9880d681SAndroid Build Coastguard Worker
1804*9880d681SAndroid Build Coastguard Workerdef CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1805*9880d681SAndroid Build Coastguard Worker                      "cvtsd2ss\t{$src, $dst|$dst, $src}",
1806*9880d681SAndroid Build Coastguard Worker                      [(set FR32:$dst, (fround FR64:$src))],
1807*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>;
1808*9880d681SAndroid Build Coastguard Workerdef CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1809*9880d681SAndroid Build Coastguard Worker                      "cvtsd2ss\t{$src, $dst|$dst, $src}",
1810*9880d681SAndroid Build Coastguard Worker                      [(set FR32:$dst, (fround (loadf64 addr:$src)))],
1811*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_Scalar_RM>,
1812*9880d681SAndroid Build Coastguard Worker                      XD,
1813*9880d681SAndroid Build Coastguard Worker                  Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1814*9880d681SAndroid Build Coastguard Worker
1815*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
1816*9880d681SAndroid Build Coastguard Workerdef Int_VCVTSD2SSrr: I<0x5A, MRMSrcReg,
1817*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1818*9880d681SAndroid Build Coastguard Worker                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1819*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1820*9880d681SAndroid Build Coastguard Worker                         (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1821*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_Scalar_RR>, XD, VEX_4V, Requires<[HasAVX]>,
1822*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2F]>;
1823*9880d681SAndroid Build Coastguard Workerdef Int_VCVTSD2SSrm: I<0x5A, MRMSrcReg,
1824*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1825*9880d681SAndroid Build Coastguard Worker                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1826*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1827*9880d681SAndroid Build Coastguard Worker                                          VR128:$src1, sse_load_f64:$src2))],
1828*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_Scalar_RM>, XD, VEX_4V, Requires<[HasAVX]>,
1829*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1830*9880d681SAndroid Build Coastguard Worker
1831*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
1832*9880d681SAndroid Build Coastguard Workerdef Int_CVTSD2SSrr: I<0x5A, MRMSrcReg,
1833*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1834*9880d681SAndroid Build Coastguard Worker                       "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1835*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1836*9880d681SAndroid Build Coastguard Worker                         (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1837*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_Scalar_RR>, XD, Requires<[UseSSE2]>,
1838*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2F]>;
1839*9880d681SAndroid Build Coastguard Workerdef Int_CVTSD2SSrm: I<0x5A, MRMSrcReg,
1840*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1841*9880d681SAndroid Build Coastguard Worker                       "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1842*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1843*9880d681SAndroid Build Coastguard Worker                                          VR128:$src1, sse_load_f64:$src2))],
1844*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_Scalar_RM>, XD, Requires<[UseSSE2]>,
1845*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1846*9880d681SAndroid Build Coastguard Worker}
1847*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly = 1
1848*9880d681SAndroid Build Coastguard Worker
1849*9880d681SAndroid Build Coastguard Worker// Convert scalar single to scalar double
1850*9880d681SAndroid Build Coastguard Worker// SSE2 instructions with XS prefix
1851*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Predicates = [UseAVX] in {
1852*9880d681SAndroid Build Coastguard Workerdef VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1853*9880d681SAndroid Build Coastguard Worker                    (ins FR32:$src1, FR32:$src2),
1854*9880d681SAndroid Build Coastguard Worker                    "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1855*9880d681SAndroid Build Coastguard Worker                    [], IIC_SSE_CVT_Scalar_RR>,
1856*9880d681SAndroid Build Coastguard Worker                    XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG,
1857*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2F]>;
1858*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
1859*9880d681SAndroid Build Coastguard Workerdef VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1860*9880d681SAndroid Build Coastguard Worker                    (ins FR32:$src1, f32mem:$src2),
1861*9880d681SAndroid Build Coastguard Worker                    "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1862*9880d681SAndroid Build Coastguard Worker                    [], IIC_SSE_CVT_Scalar_RM>,
1863*9880d681SAndroid Build Coastguard Worker                    XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>,
1864*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1865*9880d681SAndroid Build Coastguard Worker}
1866*9880d681SAndroid Build Coastguard Worker
1867*9880d681SAndroid Build Coastguard Workerdef : Pat<(f64 (fextend FR32:$src)),
1868*9880d681SAndroid Build Coastguard Worker    (VCVTSS2SDrr FR32:$src, FR32:$src)>, Requires<[UseAVX]>;
1869*9880d681SAndroid Build Coastguard Workerdef : Pat<(fextend (loadf32 addr:$src)),
1870*9880d681SAndroid Build Coastguard Worker    (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>;
1871*9880d681SAndroid Build Coastguard Worker
1872*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadf32 addr:$src),
1873*9880d681SAndroid Build Coastguard Worker    (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>,
1874*9880d681SAndroid Build Coastguard Worker    Requires<[UseAVX, OptForSize]>;
1875*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadf32 addr:$src),
1876*9880d681SAndroid Build Coastguard Worker    (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1877*9880d681SAndroid Build Coastguard Worker    Requires<[UseAVX, OptForSpeed]>;
1878*9880d681SAndroid Build Coastguard Worker
1879*9880d681SAndroid Build Coastguard Workerdef CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1880*9880d681SAndroid Build Coastguard Worker                   "cvtss2sd\t{$src, $dst|$dst, $src}",
1881*9880d681SAndroid Build Coastguard Worker                   [(set FR64:$dst, (fextend FR32:$src))],
1882*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_CVT_Scalar_RR>, XS,
1883*9880d681SAndroid Build Coastguard Worker                 Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>;
1884*9880d681SAndroid Build Coastguard Workerdef CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1885*9880d681SAndroid Build Coastguard Worker                   "cvtss2sd\t{$src, $dst|$dst, $src}",
1886*9880d681SAndroid Build Coastguard Worker                   [(set FR64:$dst, (extloadf32 addr:$src))],
1887*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_CVT_Scalar_RM>, XS,
1888*9880d681SAndroid Build Coastguard Worker                 Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1889*9880d681SAndroid Build Coastguard Worker
1890*9880d681SAndroid Build Coastguard Worker// extload f32 -> f64.  This matches load+fextend because we have a hack in
1891*9880d681SAndroid Build Coastguard Worker// the isel (PreprocessForFPConvert) that can introduce loads after dag
1892*9880d681SAndroid Build Coastguard Worker// combine.
1893*9880d681SAndroid Build Coastguard Worker// Since these loads aren't folded into the fextend, we have to match it
1894*9880d681SAndroid Build Coastguard Worker// explicitly here.
1895*9880d681SAndroid Build Coastguard Workerdef : Pat<(fextend (loadf32 addr:$src)),
1896*9880d681SAndroid Build Coastguard Worker          (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>;
1897*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadf32 addr:$src),
1898*9880d681SAndroid Build Coastguard Worker          (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1899*9880d681SAndroid Build Coastguard Worker
1900*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
1901*9880d681SAndroid Build Coastguard Workerdef Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1902*9880d681SAndroid Build Coastguard Worker                      (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1903*9880d681SAndroid Build Coastguard Worker                    "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1904*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
1905*9880d681SAndroid Build Coastguard Worker                      (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1906*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_CVT_Scalar_RR>, XS, VEX_4V, Requires<[HasAVX]>,
1907*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2F]>;
1908*9880d681SAndroid Build Coastguard Workerdef Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1909*9880d681SAndroid Build Coastguard Worker                      (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1910*9880d681SAndroid Build Coastguard Worker                    "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1911*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
1912*9880d681SAndroid Build Coastguard Worker                      (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1913*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_CVT_Scalar_RM>, XS, VEX_4V, Requires<[HasAVX]>,
1914*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1915*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1916*9880d681SAndroid Build Coastguard Workerdef Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1917*9880d681SAndroid Build Coastguard Worker                      (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1918*9880d681SAndroid Build Coastguard Worker                    "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1919*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
1920*9880d681SAndroid Build Coastguard Worker                      (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1921*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_CVT_Scalar_RR>, XS, Requires<[UseSSE2]>,
1922*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2F]>;
1923*9880d681SAndroid Build Coastguard Workerdef Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1924*9880d681SAndroid Build Coastguard Worker                      (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1925*9880d681SAndroid Build Coastguard Worker                    "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1926*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
1927*9880d681SAndroid Build Coastguard Worker                      (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1928*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_CVT_Scalar_RM>, XS, Requires<[UseSSE2]>,
1929*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1930*9880d681SAndroid Build Coastguard Worker}
1931*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly = 1
1932*9880d681SAndroid Build Coastguard Worker
1933*9880d681SAndroid Build Coastguard Worker// Convert packed single/double fp to doubleword
1934*9880d681SAndroid Build Coastguard Workerdef VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1935*9880d681SAndroid Build Coastguard Worker                       "cvtps2dq\t{$src, $dst|$dst, $src}",
1936*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1937*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
1938*9880d681SAndroid Build Coastguard Workerdef VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1939*9880d681SAndroid Build Coastguard Worker                       "cvtps2dq\t{$src, $dst|$dst, $src}",
1940*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1941*9880d681SAndroid Build Coastguard Worker                         (int_x86_sse2_cvtps2dq (loadv4f32 addr:$src)))],
1942*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
1943*9880d681SAndroid Build Coastguard Workerdef VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1944*9880d681SAndroid Build Coastguard Worker                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1945*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst,
1946*9880d681SAndroid Build Coastguard Worker                          (int_x86_avx_cvt_ps2dq_256 VR256:$src))],
1947*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
1948*9880d681SAndroid Build Coastguard Workerdef VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1949*9880d681SAndroid Build Coastguard Worker                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1950*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst,
1951*9880d681SAndroid Build Coastguard Worker                          (int_x86_avx_cvt_ps2dq_256 (loadv8f32 addr:$src)))],
1952*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_CVT_PS_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
1953*9880d681SAndroid Build Coastguard Workerdef CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1954*9880d681SAndroid Build Coastguard Worker                     "cvtps2dq\t{$src, $dst|$dst, $src}",
1955*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1956*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
1957*9880d681SAndroid Build Coastguard Workerdef CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1958*9880d681SAndroid Build Coastguard Worker                     "cvtps2dq\t{$src, $dst|$dst, $src}",
1959*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
1960*9880d681SAndroid Build Coastguard Worker                       (int_x86_sse2_cvtps2dq (memopv4f32 addr:$src)))],
1961*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
1962*9880d681SAndroid Build Coastguard Worker
1963*9880d681SAndroid Build Coastguard Worker
1964*9880d681SAndroid Build Coastguard Worker// Convert Packed Double FP to Packed DW Integers
1965*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
1966*9880d681SAndroid Build Coastguard Worker// The assembler can recognize rr 256-bit instructions by seeing a ymm
1967*9880d681SAndroid Build Coastguard Worker// register, but the same isn't true when using memory operands instead.
1968*9880d681SAndroid Build Coastguard Worker// Provide other assembly rr and rm forms to address this explicitly.
1969*9880d681SAndroid Build Coastguard Workerdef VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1970*9880d681SAndroid Build Coastguard Worker                       "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1971*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1972*9880d681SAndroid Build Coastguard Worker                       VEX, Sched<[WriteCvtF2I]>;
1973*9880d681SAndroid Build Coastguard Worker
1974*9880d681SAndroid Build Coastguard Worker// XMM only
1975*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1976*9880d681SAndroid Build Coastguard Worker                (VCVTPD2DQrr VR128:$dst, VR128:$src), 0>;
1977*9880d681SAndroid Build Coastguard Workerdef VCVTPD2DQXrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1978*9880d681SAndroid Build Coastguard Worker                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1979*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1980*9880d681SAndroid Build Coastguard Worker                         (int_x86_sse2_cvtpd2dq (loadv2f64 addr:$src)))]>, VEX,
1981*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2ILd]>;
1982*9880d681SAndroid Build Coastguard Worker
1983*9880d681SAndroid Build Coastguard Worker// YMM only
1984*9880d681SAndroid Build Coastguard Workerdef VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1985*9880d681SAndroid Build Coastguard Worker                       "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
1986*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1987*9880d681SAndroid Build Coastguard Worker                         (int_x86_avx_cvt_pd2dq_256 VR256:$src))]>, VEX, VEX_L,
1988*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteCvtF2I]>;
1989*9880d681SAndroid Build Coastguard Workerdef VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1990*9880d681SAndroid Build Coastguard Worker                       "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
1991*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
1992*9880d681SAndroid Build Coastguard Worker                         (int_x86_avx_cvt_pd2dq_256 (loadv4f64 addr:$src)))]>,
1993*9880d681SAndroid Build Coastguard Worker                       VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
1994*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtpd2dq\t{$src, $dst|$dst, $src}",
1995*9880d681SAndroid Build Coastguard Worker                (VCVTPD2DQYrr VR128:$dst, VR256:$src), 0>;
1996*9880d681SAndroid Build Coastguard Worker}
1997*9880d681SAndroid Build Coastguard Worker
1998*9880d681SAndroid Build Coastguard Workerdef CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1999*9880d681SAndroid Build Coastguard Worker                      "cvtpd2dq\t{$src, $dst|$dst, $src}",
2000*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
2001*9880d681SAndroid Build Coastguard Worker                        (int_x86_sse2_cvtpd2dq (memopv2f64 addr:$src)))],
2002*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
2003*9880d681SAndroid Build Coastguard Workerdef CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2004*9880d681SAndroid Build Coastguard Worker                      "cvtpd2dq\t{$src, $dst|$dst, $src}",
2005*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))],
2006*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2007*9880d681SAndroid Build Coastguard Worker
2008*9880d681SAndroid Build Coastguard Worker// Convert with truncation packed single/double fp to doubleword
2009*9880d681SAndroid Build Coastguard Worker// SSE2 packed instructions with XS prefix
2010*9880d681SAndroid Build Coastguard Workerdef VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2011*9880d681SAndroid Build Coastguard Worker                         "cvttps2dq\t{$src, $dst|$dst, $src}",
2012*9880d681SAndroid Build Coastguard Worker                         [], IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
2013*9880d681SAndroid Build Coastguard Workerdef VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2014*9880d681SAndroid Build Coastguard Worker                         "cvttps2dq\t{$src, $dst|$dst, $src}",
2015*9880d681SAndroid Build Coastguard Worker                         [], IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2016*9880d681SAndroid Build Coastguard Workerdef VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2017*9880d681SAndroid Build Coastguard Worker                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2018*9880d681SAndroid Build Coastguard Worker                          [], IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2019*9880d681SAndroid Build Coastguard Workerdef VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2020*9880d681SAndroid Build Coastguard Worker                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2021*9880d681SAndroid Build Coastguard Worker                          [], IIC_SSE_CVT_PS_RM>, VEX, VEX_L,
2022*9880d681SAndroid Build Coastguard Worker                          Sched<[WriteCvtF2ILd]>;
2023*9880d681SAndroid Build Coastguard Worker
2024*9880d681SAndroid Build Coastguard Workerdef CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2025*9880d681SAndroid Build Coastguard Worker                       "cvttps2dq\t{$src, $dst|$dst, $src}",
2026*9880d681SAndroid Build Coastguard Worker                       [], IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2027*9880d681SAndroid Build Coastguard Workerdef CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2028*9880d681SAndroid Build Coastguard Worker                       "cvttps2dq\t{$src, $dst|$dst, $src}",
2029*9880d681SAndroid Build Coastguard Worker                       [], IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2030*9880d681SAndroid Build Coastguard Worker
2031*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2032*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2033*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSrr VR128:$src)>;
2034*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (loadv2i64 addr:$src))),
2035*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSrm addr:$src)>;
2036*9880d681SAndroid Build Coastguard Worker}
2037*9880d681SAndroid Build Coastguard Worker
2038*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2039*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2040*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSrr VR128:$src)>;
2041*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2042*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSrm addr:$src)>;
2043*9880d681SAndroid Build Coastguard Worker
2044*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2045*9880d681SAndroid Build Coastguard Worker            (VCVTTPS2DQrr VR128:$src)>;
2046*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (loadv4f32 addr:$src))),
2047*9880d681SAndroid Build Coastguard Worker            (VCVTTPS2DQrm addr:$src)>;
2048*9880d681SAndroid Build Coastguard Worker
2049*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
2050*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSYrr VR256:$src)>;
2051*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (loadv4i64 addr:$src)))),
2052*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSYrm addr:$src)>;
2053*9880d681SAndroid Build Coastguard Worker
2054*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
2055*9880d681SAndroid Build Coastguard Worker            (VCVTTPS2DQYrr VR256:$src)>;
2056*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (fp_to_sint (loadv8f32 addr:$src))),
2057*9880d681SAndroid Build Coastguard Worker            (VCVTTPS2DQYrm addr:$src)>;
2058*9880d681SAndroid Build Coastguard Worker}
2059*9880d681SAndroid Build Coastguard Worker
2060*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
2061*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2062*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PSrr VR128:$src)>;
2063*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
2064*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PSrm addr:$src)>;
2065*9880d681SAndroid Build Coastguard Worker
2066*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2067*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PSrr VR128:$src)>;
2068*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (memopv2i64 addr:$src))),
2069*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PSrm addr:$src)>;
2070*9880d681SAndroid Build Coastguard Worker
2071*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2072*9880d681SAndroid Build Coastguard Worker            (CVTTPS2DQrr VR128:$src)>;
2073*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
2074*9880d681SAndroid Build Coastguard Worker            (CVTTPS2DQrm addr:$src)>;
2075*9880d681SAndroid Build Coastguard Worker}
2076*9880d681SAndroid Build Coastguard Worker
2077*9880d681SAndroid Build Coastguard Workerdef VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2078*9880d681SAndroid Build Coastguard Worker                        "cvttpd2dq\t{$src, $dst|$dst, $src}",
2079*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
2080*9880d681SAndroid Build Coastguard Worker                              (int_x86_sse2_cvttpd2dq VR128:$src))],
2081*9880d681SAndroid Build Coastguard Worker                              IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2I]>;
2082*9880d681SAndroid Build Coastguard Worker
2083*9880d681SAndroid Build Coastguard Worker// The assembler can recognize rr 256-bit instructions by seeing a ymm
2084*9880d681SAndroid Build Coastguard Worker// register, but the same isn't true when using memory operands instead.
2085*9880d681SAndroid Build Coastguard Worker// Provide other assembly rr and rm forms to address this explicitly.
2086*9880d681SAndroid Build Coastguard Worker
2087*9880d681SAndroid Build Coastguard Worker// XMM only
2088*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2089*9880d681SAndroid Build Coastguard Worker                (VCVTTPD2DQrr VR128:$dst, VR128:$src), 0>;
2090*9880d681SAndroid Build Coastguard Workerdef VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2091*9880d681SAndroid Build Coastguard Worker                         "cvttpd2dqx\t{$src, $dst|$dst, $src}",
2092*9880d681SAndroid Build Coastguard Worker                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2093*9880d681SAndroid Build Coastguard Worker                                            (loadv2f64 addr:$src)))],
2094*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2095*9880d681SAndroid Build Coastguard Worker
2096*9880d681SAndroid Build Coastguard Worker// YMM only
2097*9880d681SAndroid Build Coastguard Workerdef VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2098*9880d681SAndroid Build Coastguard Worker                         "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2099*9880d681SAndroid Build Coastguard Worker                         [], IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2100*9880d681SAndroid Build Coastguard Workerdef VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2101*9880d681SAndroid Build Coastguard Worker                         "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2102*9880d681SAndroid Build Coastguard Worker                         [], IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2103*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvttpd2dq\t{$src, $dst|$dst, $src}",
2104*9880d681SAndroid Build Coastguard Worker                (VCVTTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2105*9880d681SAndroid Build Coastguard Worker
2106*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2107*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
2108*9880d681SAndroid Build Coastguard Worker            (VCVTTPD2DQYrr VR256:$src)>;
2109*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (fp_to_sint (loadv4f64 addr:$src))),
2110*9880d681SAndroid Build Coastguard Worker            (VCVTTPD2DQYrm addr:$src)>;
2111*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX]
2112*9880d681SAndroid Build Coastguard Worker
2113*9880d681SAndroid Build Coastguard Workerdef CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2114*9880d681SAndroid Build Coastguard Worker                      "cvttpd2dq\t{$src, $dst|$dst, $src}",
2115*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))],
2116*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2117*9880d681SAndroid Build Coastguard Workerdef CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
2118*9880d681SAndroid Build Coastguard Worker                      "cvttpd2dq\t{$src, $dst|$dst, $src}",
2119*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2120*9880d681SAndroid Build Coastguard Worker                                        (memopv2f64 addr:$src)))],
2121*9880d681SAndroid Build Coastguard Worker                                        IIC_SSE_CVT_PD_RM>,
2122*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteCvtF2ILd]>;
2123*9880d681SAndroid Build Coastguard Worker
2124*9880d681SAndroid Build Coastguard Worker// Convert packed single to packed double
2125*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2126*9880d681SAndroid Build Coastguard Worker                  // SSE2 instructions without OpSize prefix
2127*9880d681SAndroid Build Coastguard Workerdef VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2128*9880d681SAndroid Build Coastguard Worker                    "vcvtps2pd\t{$src, $dst|$dst, $src}",
2129*9880d681SAndroid Build Coastguard Worker                    [], IIC_SSE_CVT_PD_RR>, PS, VEX, Sched<[WriteCvtF2F]>;
2130*9880d681SAndroid Build Coastguard Workerdef VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2131*9880d681SAndroid Build Coastguard Worker                    "vcvtps2pd\t{$src, $dst|$dst, $src}",
2132*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2133*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_CVT_PD_RM>, PS, VEX, Sched<[WriteCvtF2FLd]>;
2134*9880d681SAndroid Build Coastguard Workerdef VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2135*9880d681SAndroid Build Coastguard Worker                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2136*9880d681SAndroid Build Coastguard Worker                     [], IIC_SSE_CVT_PD_RR>, PS, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2137*9880d681SAndroid Build Coastguard Workerdef VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
2138*9880d681SAndroid Build Coastguard Worker                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2139*9880d681SAndroid Build Coastguard Worker                     [], IIC_SSE_CVT_PD_RM>, PS, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2140*9880d681SAndroid Build Coastguard Worker}
2141*9880d681SAndroid Build Coastguard Worker
2142*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
2143*9880d681SAndroid Build Coastguard Workerdef CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2144*9880d681SAndroid Build Coastguard Worker                   "cvtps2pd\t{$src, $dst|$dst, $src}",
2145*9880d681SAndroid Build Coastguard Worker                   [], IIC_SSE_CVT_PD_RR>, PS, Sched<[WriteCvtF2F]>;
2146*9880d681SAndroid Build Coastguard Workerdef CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2147*9880d681SAndroid Build Coastguard Worker                   "cvtps2pd\t{$src, $dst|$dst, $src}",
2148*9880d681SAndroid Build Coastguard Worker                   [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2149*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_CVT_PD_RM>, PS, Sched<[WriteCvtF2FLd]>;
2150*9880d681SAndroid Build Coastguard Worker}
2151*9880d681SAndroid Build Coastguard Worker
2152*9880d681SAndroid Build Coastguard Worker// Convert Packed DW Integers to Packed Double FP
2153*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2154*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, mayLoad = 1 in
2155*9880d681SAndroid Build Coastguard Workerdef VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2156*9880d681SAndroid Build Coastguard Worker                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2157*9880d681SAndroid Build Coastguard Worker                        []>, VEX, Sched<[WriteCvtI2FLd]>;
2158*9880d681SAndroid Build Coastguard Workerdef VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2159*9880d681SAndroid Build Coastguard Worker                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2160*9880d681SAndroid Build Coastguard Worker                        []>, VEX, Sched<[WriteCvtI2F]>;
2161*9880d681SAndroid Build Coastguard Workerdef VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
2162*9880d681SAndroid Build Coastguard Worker                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2163*9880d681SAndroid Build Coastguard Worker                         []>, VEX, VEX_L, Sched<[WriteCvtI2FLd]>;
2164*9880d681SAndroid Build Coastguard Workerdef VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2165*9880d681SAndroid Build Coastguard Worker                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2166*9880d681SAndroid Build Coastguard Worker                         []>, VEX, VEX_L, Sched<[WriteCvtI2F]>;
2167*9880d681SAndroid Build Coastguard Worker}
2168*9880d681SAndroid Build Coastguard Worker
2169*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, mayLoad = 1 in
2170*9880d681SAndroid Build Coastguard Workerdef CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2171*9880d681SAndroid Build Coastguard Worker                       "cvtdq2pd\t{$src, $dst|$dst, $src}", [],
2172*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtI2FLd]>;
2173*9880d681SAndroid Build Coastguard Workerdef CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2174*9880d681SAndroid Build Coastguard Worker                       "cvtdq2pd\t{$src, $dst|$dst, $src}", [],
2175*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtI2F]>;
2176*9880d681SAndroid Build Coastguard Worker
2177*9880d681SAndroid Build Coastguard Worker// AVX register conversion intrinsics
2178*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2179*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (v4i32 VR128:$src))),
2180*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PDrr VR128:$src)>;
2181*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (bc_v4i32 (loadv2i64 addr:$src)))),
2182*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PDrm addr:$src)>;
2183*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
2184*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PDrm addr:$src)>;
2185*9880d681SAndroid Build Coastguard Worker
2186*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
2187*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PDYrr VR128:$src)>;
2188*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2189*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PDYrm addr:$src)>;
2190*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX]
2191*9880d681SAndroid Build Coastguard Worker
2192*9880d681SAndroid Build Coastguard Worker// SSE2 register conversion intrinsics
2193*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasSSE2] in {
2194*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (v4i32 VR128:$src))),
2195*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PDrr VR128:$src)>;
2196*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (bc_v4i32 (loadv2i64 addr:$src)))),
2197*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PDrm addr:$src)>;
2198*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86cvtdq2pd (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
2199*9880d681SAndroid Build Coastguard Worker            (CVTDQ2PDrm addr:$src)>;
2200*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasSSE2]
2201*9880d681SAndroid Build Coastguard Worker
2202*9880d681SAndroid Build Coastguard Worker// Convert packed double to packed single
2203*9880d681SAndroid Build Coastguard Worker// The assembler can recognize rr 256-bit instructions by seeing a ymm
2204*9880d681SAndroid Build Coastguard Worker// register, but the same isn't true when using memory operands instead.
2205*9880d681SAndroid Build Coastguard Worker// Provide other assembly rr and rm forms to address this explicitly.
2206*9880d681SAndroid Build Coastguard Workerdef VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2207*9880d681SAndroid Build Coastguard Worker                       "cvtpd2ps\t{$src, $dst|$dst, $src}",
2208*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2209*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2F]>;
2210*9880d681SAndroid Build Coastguard Worker
2211*9880d681SAndroid Build Coastguard Worker// XMM only
2212*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2213*9880d681SAndroid Build Coastguard Worker                (VCVTPD2PSrr VR128:$dst, VR128:$src), 0>;
2214*9880d681SAndroid Build Coastguard Workerdef VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2215*9880d681SAndroid Build Coastguard Worker                        "cvtpd2psx\t{$src, $dst|$dst, $src}",
2216*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
2217*9880d681SAndroid Build Coastguard Worker                          (int_x86_sse2_cvtpd2ps (loadv2f64 addr:$src)))],
2218*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2FLd]>;
2219*9880d681SAndroid Build Coastguard Worker
2220*9880d681SAndroid Build Coastguard Worker// YMM only
2221*9880d681SAndroid Build Coastguard Workerdef VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2222*9880d681SAndroid Build Coastguard Worker                        "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2223*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
2224*9880d681SAndroid Build Coastguard Worker                          (int_x86_avx_cvt_pd2_ps_256 VR256:$src))],
2225*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2226*9880d681SAndroid Build Coastguard Workerdef VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2227*9880d681SAndroid Build Coastguard Worker                        "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2228*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
2229*9880d681SAndroid Build Coastguard Worker                          (int_x86_avx_cvt_pd2_ps_256 (loadv4f64 addr:$src)))],
2230*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2231*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vcvtpd2ps\t{$src, $dst|$dst, $src}",
2232*9880d681SAndroid Build Coastguard Worker                (VCVTPD2PSYrr VR128:$dst, VR256:$src), 0>;
2233*9880d681SAndroid Build Coastguard Worker
2234*9880d681SAndroid Build Coastguard Workerdef CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2235*9880d681SAndroid Build Coastguard Worker                     "cvtpd2ps\t{$src, $dst|$dst, $src}",
2236*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2237*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2F]>;
2238*9880d681SAndroid Build Coastguard Workerdef CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2239*9880d681SAndroid Build Coastguard Worker                     "cvtpd2ps\t{$src, $dst|$dst, $src}",
2240*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
2241*9880d681SAndroid Build Coastguard Worker                       (int_x86_sse2_cvtpd2ps (memopv2f64 addr:$src)))],
2242*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2FLd]>;
2243*9880d681SAndroid Build Coastguard Worker
2244*9880d681SAndroid Build Coastguard Worker
2245*9880d681SAndroid Build Coastguard Worker// AVX 256-bit register conversion intrinsics
2246*9880d681SAndroid Build Coastguard Worker// FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2247*9880d681SAndroid Build Coastguard Worker// whenever possible to avoid declaring two versions of each one.
2248*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2249*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2250*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSYrr VR256:$src)>;
2251*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (loadv4i64 addr:$src))),
2252*9880d681SAndroid Build Coastguard Worker            (VCVTDQ2PSYrm addr:$src)>;
2253*9880d681SAndroid Build Coastguard Worker}
2254*9880d681SAndroid Build Coastguard Worker
2255*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2256*9880d681SAndroid Build Coastguard Worker  // Match fround and fextend for 128/256-bit conversions
2257*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2258*9880d681SAndroid Build Coastguard Worker            (VCVTPD2PSrr VR128:$src)>;
2259*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vfpround (loadv2f64 addr:$src))),
2260*9880d681SAndroid Build Coastguard Worker            (VCVTPD2PSXrm addr:$src)>;
2261*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2262*9880d681SAndroid Build Coastguard Worker            (VCVTPD2PSYrr VR256:$src)>;
2263*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2264*9880d681SAndroid Build Coastguard Worker            (VCVTPD2PSYrm addr:$src)>;
2265*9880d681SAndroid Build Coastguard Worker
2266*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2267*9880d681SAndroid Build Coastguard Worker            (VCVTPS2PDrr VR128:$src)>;
2268*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2269*9880d681SAndroid Build Coastguard Worker            (VCVTPS2PDYrr VR128:$src)>;
2270*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (extloadv4f32 addr:$src)),
2271*9880d681SAndroid Build Coastguard Worker            (VCVTPS2PDYrm addr:$src)>;
2272*9880d681SAndroid Build Coastguard Worker}
2273*9880d681SAndroid Build Coastguard Worker
2274*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
2275*9880d681SAndroid Build Coastguard Worker  // Match fround and fextend for 128 conversions
2276*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2277*9880d681SAndroid Build Coastguard Worker            (CVTPD2PSrr VR128:$src)>;
2278*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vfpround (memopv2f64 addr:$src))),
2279*9880d681SAndroid Build Coastguard Worker            (CVTPD2PSrm addr:$src)>;
2280*9880d681SAndroid Build Coastguard Worker
2281*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2282*9880d681SAndroid Build Coastguard Worker            (CVTPS2PDrr VR128:$src)>;
2283*9880d681SAndroid Build Coastguard Worker}
2284*9880d681SAndroid Build Coastguard Worker
2285*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2286*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Compare Instructions
2287*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2288*9880d681SAndroid Build Coastguard Worker
2289*9880d681SAndroid Build Coastguard Worker// sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2290*9880d681SAndroid Build Coastguard Workermulticlass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2291*9880d681SAndroid Build Coastguard Worker                            Operand CC, SDNode OpNode, ValueType VT,
2292*9880d681SAndroid Build Coastguard Worker                            PatFrag ld_frag, string asm, string asm_alt,
2293*9880d681SAndroid Build Coastguard Worker                            OpndItins itins, ImmLeaf immLeaf> {
2294*9880d681SAndroid Build Coastguard Worker  def rr : SIi8<0xC2, MRMSrcReg,
2295*9880d681SAndroid Build Coastguard Worker                (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2296*9880d681SAndroid Build Coastguard Worker                [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, immLeaf:$cc))],
2297*9880d681SAndroid Build Coastguard Worker                itins.rr>, Sched<[itins.Sched]>;
2298*9880d681SAndroid Build Coastguard Worker  def rm : SIi8<0xC2, MRMSrcMem,
2299*9880d681SAndroid Build Coastguard Worker                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2300*9880d681SAndroid Build Coastguard Worker                [(set RC:$dst, (OpNode (VT RC:$src1),
2301*9880d681SAndroid Build Coastguard Worker                                         (ld_frag addr:$src2), immLeaf:$cc))],
2302*9880d681SAndroid Build Coastguard Worker                                         itins.rm>,
2303*9880d681SAndroid Build Coastguard Worker           Sched<[itins.Sched.Folded, ReadAfterLd]>;
2304*9880d681SAndroid Build Coastguard Worker
2305*9880d681SAndroid Build Coastguard Worker  // Accept explicit immediate argument form instead of comparison code.
2306*9880d681SAndroid Build Coastguard Worker  let isAsmParserOnly = 1, hasSideEffects = 0 in {
2307*9880d681SAndroid Build Coastguard Worker    def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2308*9880d681SAndroid Build Coastguard Worker                      (ins RC:$src1, RC:$src2, u8imm:$cc), asm_alt, [],
2309*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
2310*9880d681SAndroid Build Coastguard Worker    let mayLoad = 1 in
2311*9880d681SAndroid Build Coastguard Worker    def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2312*9880d681SAndroid Build Coastguard Worker                      (ins RC:$src1, x86memop:$src2, u8imm:$cc), asm_alt, [],
2313*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_ALU_F32S_RM>,
2314*9880d681SAndroid Build Coastguard Worker                      Sched<[itins.Sched.Folded, ReadAfterLd]>;
2315*9880d681SAndroid Build Coastguard Worker  }
2316*9880d681SAndroid Build Coastguard Worker}
2317*9880d681SAndroid Build Coastguard Worker
2318*9880d681SAndroid Build Coastguard Workerdefm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
2319*9880d681SAndroid Build Coastguard Worker                 "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2320*9880d681SAndroid Build Coastguard Worker                 "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2321*9880d681SAndroid Build Coastguard Worker                 SSE_ALU_F32S, i8immZExt5>, XS, VEX_4V, VEX_LIG;
2322*9880d681SAndroid Build Coastguard Workerdefm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
2323*9880d681SAndroid Build Coastguard Worker                 "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2324*9880d681SAndroid Build Coastguard Worker                 "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2325*9880d681SAndroid Build Coastguard Worker                 SSE_ALU_F32S, i8immZExt5>, // same latency as 32 bit compare
2326*9880d681SAndroid Build Coastguard Worker                 XD, VEX_4V, VEX_LIG;
2327*9880d681SAndroid Build Coastguard Worker
2328*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
2329*9880d681SAndroid Build Coastguard Worker  defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
2330*9880d681SAndroid Build Coastguard Worker                  "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2331*9880d681SAndroid Build Coastguard Worker                  "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S,
2332*9880d681SAndroid Build Coastguard Worker                  i8immZExt3>, XS;
2333*9880d681SAndroid Build Coastguard Worker  defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
2334*9880d681SAndroid Build Coastguard Worker                  "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2335*9880d681SAndroid Build Coastguard Worker                  "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2336*9880d681SAndroid Build Coastguard Worker                  SSE_ALU_F64S, i8immZExt3>, XD;
2337*9880d681SAndroid Build Coastguard Worker}
2338*9880d681SAndroid Build Coastguard Worker
2339*9880d681SAndroid Build Coastguard Workermulticlass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,
2340*9880d681SAndroid Build Coastguard Worker                         Intrinsic Int, string asm, OpndItins itins,
2341*9880d681SAndroid Build Coastguard Worker                         ImmLeaf immLeaf> {
2342*9880d681SAndroid Build Coastguard Worker  def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2343*9880d681SAndroid Build Coastguard Worker                      (ins VR128:$src1, VR128:$src, CC:$cc), asm,
2344*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst, (Int VR128:$src1,
2345*9880d681SAndroid Build Coastguard Worker                                               VR128:$src, immLeaf:$cc))],
2346*9880d681SAndroid Build Coastguard Worker                                               itins.rr>,
2347*9880d681SAndroid Build Coastguard Worker           Sched<[itins.Sched]>;
2348*9880d681SAndroid Build Coastguard Worker  def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2349*9880d681SAndroid Build Coastguard Worker                      (ins VR128:$src1, x86memop:$src, CC:$cc), asm,
2350*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst, (Int VR128:$src1,
2351*9880d681SAndroid Build Coastguard Worker                                               (load addr:$src), immLeaf:$cc))],
2352*9880d681SAndroid Build Coastguard Worker                                               itins.rm>,
2353*9880d681SAndroid Build Coastguard Worker           Sched<[itins.Sched.Folded, ReadAfterLd]>;
2354*9880d681SAndroid Build Coastguard Worker}
2355*9880d681SAndroid Build Coastguard Worker
2356*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
2357*9880d681SAndroid Build Coastguard Worker  // Aliases to match intrinsics which expect XMM operand(s).
2358*9880d681SAndroid Build Coastguard Worker  defm Int_VCMPSS  : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,
2359*9880d681SAndroid Build Coastguard Worker                       "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
2360*9880d681SAndroid Build Coastguard Worker                       SSE_ALU_F32S, i8immZExt5>,
2361*9880d681SAndroid Build Coastguard Worker                       XS, VEX_4V;
2362*9880d681SAndroid Build Coastguard Worker  defm Int_VCMPSD  : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,
2363*9880d681SAndroid Build Coastguard Worker                       "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
2364*9880d681SAndroid Build Coastguard Worker                       SSE_ALU_F32S, i8immZExt5>, // same latency as f32
2365*9880d681SAndroid Build Coastguard Worker                       XD, VEX_4V;
2366*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
2367*9880d681SAndroid Build Coastguard Worker    defm Int_CMPSS  : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,
2368*9880d681SAndroid Build Coastguard Worker                         "cmp${cc}ss\t{$src, $dst|$dst, $src}",
2369*9880d681SAndroid Build Coastguard Worker                         SSE_ALU_F32S, i8immZExt3>, XS;
2370*9880d681SAndroid Build Coastguard Worker    defm Int_CMPSD  : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,
2371*9880d681SAndroid Build Coastguard Worker                         "cmp${cc}sd\t{$src, $dst|$dst, $src}",
2372*9880d681SAndroid Build Coastguard Worker                         SSE_ALU_F64S, i8immZExt3>,
2373*9880d681SAndroid Build Coastguard Worker                         XD;
2374*9880d681SAndroid Build Coastguard Worker}
2375*9880d681SAndroid Build Coastguard Worker}
2376*9880d681SAndroid Build Coastguard Worker
2377*9880d681SAndroid Build Coastguard Worker
2378*9880d681SAndroid Build Coastguard Worker// sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2379*9880d681SAndroid Build Coastguard Workermulticlass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2380*9880d681SAndroid Build Coastguard Worker                            ValueType vt, X86MemOperand x86memop,
2381*9880d681SAndroid Build Coastguard Worker                            PatFrag ld_frag, string OpcodeStr> {
2382*9880d681SAndroid Build Coastguard Worker  def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2383*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2384*9880d681SAndroid Build Coastguard Worker                     [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2385*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_COMIS_RR>,
2386*9880d681SAndroid Build Coastguard Worker          Sched<[WriteFAdd]>;
2387*9880d681SAndroid Build Coastguard Worker  def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2388*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2389*9880d681SAndroid Build Coastguard Worker                     [(set EFLAGS, (OpNode (vt RC:$src1),
2390*9880d681SAndroid Build Coastguard Worker                                           (ld_frag addr:$src2)))],
2391*9880d681SAndroid Build Coastguard Worker                                           IIC_SSE_COMIS_RM>,
2392*9880d681SAndroid Build Coastguard Worker          Sched<[WriteFAddLd, ReadAfterLd]>;
2393*9880d681SAndroid Build Coastguard Worker}
2394*9880d681SAndroid Build Coastguard Worker
2395*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in {
2396*9880d681SAndroid Build Coastguard Worker  defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2397*9880d681SAndroid Build Coastguard Worker                                  "ucomiss">, PS, VEX, VEX_LIG;
2398*9880d681SAndroid Build Coastguard Worker  defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2399*9880d681SAndroid Build Coastguard Worker                                  "ucomisd">, PD, VEX, VEX_LIG;
2400*9880d681SAndroid Build Coastguard Worker  let Pattern = []<dag> in {
2401*9880d681SAndroid Build Coastguard Worker    defm VCOMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
2402*9880d681SAndroid Build Coastguard Worker                                    "comiss">, PS, VEX, VEX_LIG;
2403*9880d681SAndroid Build Coastguard Worker    defm VCOMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
2404*9880d681SAndroid Build Coastguard Worker                                    "comisd">, PD, VEX, VEX_LIG;
2405*9880d681SAndroid Build Coastguard Worker  }
2406*9880d681SAndroid Build Coastguard Worker
2407*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in {
2408*9880d681SAndroid Build Coastguard Worker    defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2409*9880d681SAndroid Build Coastguard Worker                              load, "ucomiss">, PS, VEX;
2410*9880d681SAndroid Build Coastguard Worker    defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2411*9880d681SAndroid Build Coastguard Worker                              load, "ucomisd">, PD, VEX;
2412*9880d681SAndroid Build Coastguard Worker
2413*9880d681SAndroid Build Coastguard Worker    defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2414*9880d681SAndroid Build Coastguard Worker                              load, "comiss">, PS, VEX;
2415*9880d681SAndroid Build Coastguard Worker    defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2416*9880d681SAndroid Build Coastguard Worker                              load, "comisd">, PD, VEX;
2417*9880d681SAndroid Build Coastguard Worker  }
2418*9880d681SAndroid Build Coastguard Worker  defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2419*9880d681SAndroid Build Coastguard Worker                                  "ucomiss">, PS;
2420*9880d681SAndroid Build Coastguard Worker  defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2421*9880d681SAndroid Build Coastguard Worker                                  "ucomisd">, PD;
2422*9880d681SAndroid Build Coastguard Worker
2423*9880d681SAndroid Build Coastguard Worker  let Pattern = []<dag> in {
2424*9880d681SAndroid Build Coastguard Worker    defm COMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
2425*9880d681SAndroid Build Coastguard Worker                                    "comiss">, PS;
2426*9880d681SAndroid Build Coastguard Worker    defm COMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
2427*9880d681SAndroid Build Coastguard Worker                                    "comisd">, PD;
2428*9880d681SAndroid Build Coastguard Worker  }
2429*9880d681SAndroid Build Coastguard Worker
2430*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in {
2431*9880d681SAndroid Build Coastguard Worker    defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2432*9880d681SAndroid Build Coastguard Worker                                load, "ucomiss">, PS;
2433*9880d681SAndroid Build Coastguard Worker    defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2434*9880d681SAndroid Build Coastguard Worker                                load, "ucomisd">, PD;
2435*9880d681SAndroid Build Coastguard Worker
2436*9880d681SAndroid Build Coastguard Worker    defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2437*9880d681SAndroid Build Coastguard Worker                                    "comiss">, PS;
2438*9880d681SAndroid Build Coastguard Worker    defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2439*9880d681SAndroid Build Coastguard Worker                                    "comisd">, PD;
2440*9880d681SAndroid Build Coastguard Worker  }
2441*9880d681SAndroid Build Coastguard Worker} // Defs = [EFLAGS]
2442*9880d681SAndroid Build Coastguard Worker
2443*9880d681SAndroid Build Coastguard Worker// sse12_cmp_packed - sse 1 & 2 compare packed instructions
2444*9880d681SAndroid Build Coastguard Workermulticlass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2445*9880d681SAndroid Build Coastguard Worker                            Operand CC, Intrinsic Int, string asm,
2446*9880d681SAndroid Build Coastguard Worker                            string asm_alt, Domain d, ImmLeaf immLeaf,
2447*9880d681SAndroid Build Coastguard Worker                            PatFrag ld_frag, OpndItins itins = SSE_ALU_F32P> {
2448*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
2449*9880d681SAndroid Build Coastguard Worker  def rri : PIi8<0xC2, MRMSrcReg,
2450*9880d681SAndroid Build Coastguard Worker             (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2451*9880d681SAndroid Build Coastguard Worker             [(set RC:$dst, (Int RC:$src1, RC:$src2, immLeaf:$cc))],
2452*9880d681SAndroid Build Coastguard Worker             itins.rr, d>,
2453*9880d681SAndroid Build Coastguard Worker            Sched<[WriteFAdd]>;
2454*9880d681SAndroid Build Coastguard Worker  def rmi : PIi8<0xC2, MRMSrcMem,
2455*9880d681SAndroid Build Coastguard Worker             (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2456*9880d681SAndroid Build Coastguard Worker             [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2), immLeaf:$cc))],
2457*9880d681SAndroid Build Coastguard Worker             itins.rm, d>,
2458*9880d681SAndroid Build Coastguard Worker            Sched<[WriteFAddLd, ReadAfterLd]>;
2459*9880d681SAndroid Build Coastguard Worker
2460*9880d681SAndroid Build Coastguard Worker  // Accept explicit immediate argument form instead of comparison code.
2461*9880d681SAndroid Build Coastguard Worker  let isAsmParserOnly = 1, hasSideEffects = 0 in {
2462*9880d681SAndroid Build Coastguard Worker    def rri_alt : PIi8<0xC2, MRMSrcReg,
2463*9880d681SAndroid Build Coastguard Worker               (outs RC:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
2464*9880d681SAndroid Build Coastguard Worker               asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
2465*9880d681SAndroid Build Coastguard Worker    let mayLoad = 1 in
2466*9880d681SAndroid Build Coastguard Worker    def rmi_alt : PIi8<0xC2, MRMSrcMem,
2467*9880d681SAndroid Build Coastguard Worker               (outs RC:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
2468*9880d681SAndroid Build Coastguard Worker               asm_alt, [], itins.rm, d>,
2469*9880d681SAndroid Build Coastguard Worker               Sched<[WriteFAddLd, ReadAfterLd]>;
2470*9880d681SAndroid Build Coastguard Worker  }
2471*9880d681SAndroid Build Coastguard Worker}
2472*9880d681SAndroid Build Coastguard Worker
2473*9880d681SAndroid Build Coastguard Workerdefm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,
2474*9880d681SAndroid Build Coastguard Worker               "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2475*9880d681SAndroid Build Coastguard Worker               "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2476*9880d681SAndroid Build Coastguard Worker               SSEPackedSingle, i8immZExt5, loadv4f32>, PS, VEX_4V;
2477*9880d681SAndroid Build Coastguard Workerdefm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,
2478*9880d681SAndroid Build Coastguard Worker               "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2479*9880d681SAndroid Build Coastguard Worker               "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2480*9880d681SAndroid Build Coastguard Worker               SSEPackedDouble, i8immZExt5, loadv2f64>, PD, VEX_4V;
2481*9880d681SAndroid Build Coastguard Workerdefm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,
2482*9880d681SAndroid Build Coastguard Worker               "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2483*9880d681SAndroid Build Coastguard Worker               "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2484*9880d681SAndroid Build Coastguard Worker               SSEPackedSingle, i8immZExt5, loadv8f32>, PS, VEX_4V, VEX_L;
2485*9880d681SAndroid Build Coastguard Workerdefm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,
2486*9880d681SAndroid Build Coastguard Worker               "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2487*9880d681SAndroid Build Coastguard Worker               "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2488*9880d681SAndroid Build Coastguard Worker               SSEPackedDouble, i8immZExt5, loadv4f64>, PD, VEX_4V, VEX_L;
2489*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
2490*9880d681SAndroid Build Coastguard Worker  defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,
2491*9880d681SAndroid Build Coastguard Worker                 "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2492*9880d681SAndroid Build Coastguard Worker                 "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2493*9880d681SAndroid Build Coastguard Worker                 SSEPackedSingle, i8immZExt5, memopv4f32, SSE_ALU_F32P>, PS;
2494*9880d681SAndroid Build Coastguard Worker  defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,
2495*9880d681SAndroid Build Coastguard Worker                 "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2496*9880d681SAndroid Build Coastguard Worker                 "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2497*9880d681SAndroid Build Coastguard Worker                 SSEPackedDouble, i8immZExt5, memopv2f64, SSE_ALU_F64P>, PD;
2498*9880d681SAndroid Build Coastguard Worker}
2499*9880d681SAndroid Build Coastguard Worker
2500*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2501*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2502*9880d681SAndroid Build Coastguard Worker          (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2503*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86cmpp (v4f32 VR128:$src1), (loadv4f32 addr:$src2), imm:$cc)),
2504*9880d681SAndroid Build Coastguard Worker          (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2505*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2506*9880d681SAndroid Build Coastguard Worker          (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2507*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86cmpp (v2f64 VR128:$src1), (loadv2f64 addr:$src2), imm:$cc)),
2508*9880d681SAndroid Build Coastguard Worker          (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2509*9880d681SAndroid Build Coastguard Worker
2510*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2511*9880d681SAndroid Build Coastguard Worker          (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2512*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (X86cmpp (v8f32 VR256:$src1), (loadv8f32 addr:$src2), imm:$cc)),
2513*9880d681SAndroid Build Coastguard Worker          (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2514*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2515*9880d681SAndroid Build Coastguard Worker          (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2516*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86cmpp (v4f64 VR256:$src1), (loadv4f64 addr:$src2), imm:$cc)),
2517*9880d681SAndroid Build Coastguard Worker          (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2518*9880d681SAndroid Build Coastguard Worker}
2519*9880d681SAndroid Build Coastguard Worker
2520*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
2521*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2522*9880d681SAndroid Build Coastguard Worker          (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2523*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86cmpp (v4f32 VR128:$src1), (memopv4f32 addr:$src2), imm:$cc)),
2524*9880d681SAndroid Build Coastguard Worker          (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2525*9880d681SAndroid Build Coastguard Worker}
2526*9880d681SAndroid Build Coastguard Worker
2527*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
2528*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2529*9880d681SAndroid Build Coastguard Worker          (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2530*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86cmpp (v2f64 VR128:$src1), (memopv2f64 addr:$src2), imm:$cc)),
2531*9880d681SAndroid Build Coastguard Worker          (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2532*9880d681SAndroid Build Coastguard Worker}
2533*9880d681SAndroid Build Coastguard Worker
2534*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2535*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Shuffle Instructions
2536*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2537*9880d681SAndroid Build Coastguard Worker
2538*9880d681SAndroid Build Coastguard Worker/// sse12_shuffle - sse 1 & 2 fp shuffle instructions
2539*9880d681SAndroid Build Coastguard Workermulticlass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2540*9880d681SAndroid Build Coastguard Worker                         ValueType vt, string asm, PatFrag mem_frag,
2541*9880d681SAndroid Build Coastguard Worker                         Domain d> {
2542*9880d681SAndroid Build Coastguard Worker  def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2543*9880d681SAndroid Build Coastguard Worker                   (ins RC:$src1, x86memop:$src2, u8imm:$src3), asm,
2544*9880d681SAndroid Build Coastguard Worker                   [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2545*9880d681SAndroid Build Coastguard Worker                                       (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2546*9880d681SAndroid Build Coastguard Worker            Sched<[WriteFShuffleLd, ReadAfterLd]>;
2547*9880d681SAndroid Build Coastguard Worker  def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2548*9880d681SAndroid Build Coastguard Worker                 (ins RC:$src1, RC:$src2, u8imm:$src3), asm,
2549*9880d681SAndroid Build Coastguard Worker                 [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2550*9880d681SAndroid Build Coastguard Worker                                     (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2551*9880d681SAndroid Build Coastguard Worker            Sched<[WriteFShuffle]>;
2552*9880d681SAndroid Build Coastguard Worker}
2553*9880d681SAndroid Build Coastguard Worker
2554*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2555*9880d681SAndroid Build Coastguard Worker  defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2556*9880d681SAndroid Build Coastguard Worker           "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2557*9880d681SAndroid Build Coastguard Worker           loadv4f32, SSEPackedSingle>, PS, VEX_4V;
2558*9880d681SAndroid Build Coastguard Worker  defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2559*9880d681SAndroid Build Coastguard Worker           "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2560*9880d681SAndroid Build Coastguard Worker           loadv8f32, SSEPackedSingle>, PS, VEX_4V, VEX_L;
2561*9880d681SAndroid Build Coastguard Worker  defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2562*9880d681SAndroid Build Coastguard Worker           "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2563*9880d681SAndroid Build Coastguard Worker           loadv2f64, SSEPackedDouble>, PD, VEX_4V;
2564*9880d681SAndroid Build Coastguard Worker  defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2565*9880d681SAndroid Build Coastguard Worker           "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2566*9880d681SAndroid Build Coastguard Worker           loadv4f64, SSEPackedDouble>, PD, VEX_4V, VEX_L;
2567*9880d681SAndroid Build Coastguard Worker}
2568*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
2569*9880d681SAndroid Build Coastguard Worker  defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2570*9880d681SAndroid Build Coastguard Worker                    "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2571*9880d681SAndroid Build Coastguard Worker                    memopv4f32, SSEPackedSingle>, PS;
2572*9880d681SAndroid Build Coastguard Worker  defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2573*9880d681SAndroid Build Coastguard Worker                    "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2574*9880d681SAndroid Build Coastguard Worker                    memopv2f64, SSEPackedDouble>, PD;
2575*9880d681SAndroid Build Coastguard Worker}
2576*9880d681SAndroid Build Coastguard Worker
2577*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2578*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Shufp VR128:$src1,
2579*9880d681SAndroid Build Coastguard Worker                       (bc_v4i32 (loadv2i64 addr:$src2)), (i8 imm:$imm))),
2580*9880d681SAndroid Build Coastguard Worker            (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2581*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2582*9880d681SAndroid Build Coastguard Worker            (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2583*9880d681SAndroid Build Coastguard Worker
2584*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Shufp VR128:$src1,
2585*9880d681SAndroid Build Coastguard Worker                       (loadv2i64 addr:$src2), (i8 imm:$imm))),
2586*9880d681SAndroid Build Coastguard Worker            (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2587*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2588*9880d681SAndroid Build Coastguard Worker            (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2589*9880d681SAndroid Build Coastguard Worker
2590*9880d681SAndroid Build Coastguard Worker  // 256-bit patterns
2591*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2592*9880d681SAndroid Build Coastguard Worker            (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2593*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Shufp VR256:$src1,
2594*9880d681SAndroid Build Coastguard Worker                      (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
2595*9880d681SAndroid Build Coastguard Worker            (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2596*9880d681SAndroid Build Coastguard Worker
2597*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2598*9880d681SAndroid Build Coastguard Worker            (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2599*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Shufp VR256:$src1,
2600*9880d681SAndroid Build Coastguard Worker                              (loadv4i64 addr:$src2), (i8 imm:$imm))),
2601*9880d681SAndroid Build Coastguard Worker            (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2602*9880d681SAndroid Build Coastguard Worker}
2603*9880d681SAndroid Build Coastguard Worker
2604*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
2605*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Shufp VR128:$src1,
2606*9880d681SAndroid Build Coastguard Worker                       (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2607*9880d681SAndroid Build Coastguard Worker            (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2608*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2609*9880d681SAndroid Build Coastguard Worker            (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2610*9880d681SAndroid Build Coastguard Worker}
2611*9880d681SAndroid Build Coastguard Worker
2612*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
2613*9880d681SAndroid Build Coastguard Worker  // Generic SHUFPD patterns
2614*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Shufp VR128:$src1,
2615*9880d681SAndroid Build Coastguard Worker                       (memopv2i64 addr:$src2), (i8 imm:$imm))),
2616*9880d681SAndroid Build Coastguard Worker            (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2617*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2618*9880d681SAndroid Build Coastguard Worker            (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2619*9880d681SAndroid Build Coastguard Worker}
2620*9880d681SAndroid Build Coastguard Worker
2621*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2622*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Unpack FP Instructions
2623*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2624*9880d681SAndroid Build Coastguard Worker
2625*9880d681SAndroid Build Coastguard Worker/// sse12_unpack_interleave - sse 1 & 2 fp unpack and interleave
2626*9880d681SAndroid Build Coastguard Workermulticlass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2627*9880d681SAndroid Build Coastguard Worker                                   PatFrag mem_frag, RegisterClass RC,
2628*9880d681SAndroid Build Coastguard Worker                                   X86MemOperand x86memop, string asm,
2629*9880d681SAndroid Build Coastguard Worker                                   Domain d> {
2630*9880d681SAndroid Build Coastguard Worker    def rr : PI<opc, MRMSrcReg,
2631*9880d681SAndroid Build Coastguard Worker                (outs RC:$dst), (ins RC:$src1, RC:$src2),
2632*9880d681SAndroid Build Coastguard Worker                asm, [(set RC:$dst,
2633*9880d681SAndroid Build Coastguard Worker                           (vt (OpNode RC:$src1, RC:$src2)))],
2634*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_UNPCK, d>, Sched<[WriteFShuffle]>;
2635*9880d681SAndroid Build Coastguard Worker    def rm : PI<opc, MRMSrcMem,
2636*9880d681SAndroid Build Coastguard Worker                (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2637*9880d681SAndroid Build Coastguard Worker                asm, [(set RC:$dst,
2638*9880d681SAndroid Build Coastguard Worker                           (vt (OpNode RC:$src1,
2639*9880d681SAndroid Build Coastguard Worker                                       (mem_frag addr:$src2))))],
2640*9880d681SAndroid Build Coastguard Worker                                       IIC_SSE_UNPCK, d>,
2641*9880d681SAndroid Build Coastguard Worker             Sched<[WriteFShuffleLd, ReadAfterLd]>;
2642*9880d681SAndroid Build Coastguard Worker}
2643*9880d681SAndroid Build Coastguard Worker
2644*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
2645*9880d681SAndroid Build Coastguard Workerdefm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2646*9880d681SAndroid Build Coastguard Worker      VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2647*9880d681SAndroid Build Coastguard Worker                     SSEPackedSingle>, PS, VEX_4V;
2648*9880d681SAndroid Build Coastguard Workerdefm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2649*9880d681SAndroid Build Coastguard Worker      VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2650*9880d681SAndroid Build Coastguard Worker                     SSEPackedDouble>, PD, VEX_4V;
2651*9880d681SAndroid Build Coastguard Workerdefm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2652*9880d681SAndroid Build Coastguard Worker      VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2653*9880d681SAndroid Build Coastguard Worker                     SSEPackedSingle>, PS, VEX_4V;
2654*9880d681SAndroid Build Coastguard Workerdefm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2655*9880d681SAndroid Build Coastguard Worker      VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2656*9880d681SAndroid Build Coastguard Worker                     SSEPackedDouble>, PD, VEX_4V;
2657*9880d681SAndroid Build Coastguard Worker
2658*9880d681SAndroid Build Coastguard Workerdefm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2659*9880d681SAndroid Build Coastguard Worker      VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2660*9880d681SAndroid Build Coastguard Worker                     SSEPackedSingle>, PS, VEX_4V, VEX_L;
2661*9880d681SAndroid Build Coastguard Workerdefm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2662*9880d681SAndroid Build Coastguard Worker      VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2663*9880d681SAndroid Build Coastguard Worker                     SSEPackedDouble>, PD, VEX_4V, VEX_L;
2664*9880d681SAndroid Build Coastguard Workerdefm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2665*9880d681SAndroid Build Coastguard Worker      VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2666*9880d681SAndroid Build Coastguard Worker                     SSEPackedSingle>, PS, VEX_4V, VEX_L;
2667*9880d681SAndroid Build Coastguard Workerdefm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2668*9880d681SAndroid Build Coastguard Worker      VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2669*9880d681SAndroid Build Coastguard Worker                     SSEPackedDouble>, PD, VEX_4V, VEX_L;
2670*9880d681SAndroid Build Coastguard Worker}// Predicates = [HasAVX, NoVLX]
2671*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
2672*9880d681SAndroid Build Coastguard Worker  defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2673*9880d681SAndroid Build Coastguard Worker        VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2674*9880d681SAndroid Build Coastguard Worker                       SSEPackedSingle>, PS;
2675*9880d681SAndroid Build Coastguard Worker  defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2676*9880d681SAndroid Build Coastguard Worker        VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2677*9880d681SAndroid Build Coastguard Worker                       SSEPackedDouble>, PD;
2678*9880d681SAndroid Build Coastguard Worker  defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2679*9880d681SAndroid Build Coastguard Worker        VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2680*9880d681SAndroid Build Coastguard Worker                       SSEPackedSingle>, PS;
2681*9880d681SAndroid Build Coastguard Worker  defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2682*9880d681SAndroid Build Coastguard Worker        VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2683*9880d681SAndroid Build Coastguard Worker                       SSEPackedDouble>, PD;
2684*9880d681SAndroid Build Coastguard Worker} // Constraints = "$src1 = $dst"
2685*9880d681SAndroid Build Coastguard Worker
2686*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
2687*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2688*9880d681SAndroid Build Coastguard Worker            (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2689*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2690*9880d681SAndroid Build Coastguard Worker            (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2691*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2692*9880d681SAndroid Build Coastguard Worker            (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2693*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2694*9880d681SAndroid Build Coastguard Worker            (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2695*9880d681SAndroid Build Coastguard Worker
2696*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2697*9880d681SAndroid Build Coastguard Worker            (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2698*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2699*9880d681SAndroid Build Coastguard Worker            (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2700*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2701*9880d681SAndroid Build Coastguard Worker            (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2702*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2703*9880d681SAndroid Build Coastguard Worker            (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2704*9880d681SAndroid Build Coastguard Worker}
2705*9880d681SAndroid Build Coastguard Worker
2706*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2707*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Extract Floating-Point Sign mask
2708*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2709*9880d681SAndroid Build Coastguard Worker
2710*9880d681SAndroid Build Coastguard Worker/// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2711*9880d681SAndroid Build Coastguard Workermulticlass sse12_extr_sign_mask<RegisterClass RC, ValueType vt,
2712*9880d681SAndroid Build Coastguard Worker                                string asm, Domain d> {
2713*9880d681SAndroid Build Coastguard Worker  def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2714*9880d681SAndroid Build Coastguard Worker              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2715*9880d681SAndroid Build Coastguard Worker              [(set GR32orGR64:$dst, (X86movmsk (vt RC:$src)))], IIC_SSE_MOVMSK, d>,
2716*9880d681SAndroid Build Coastguard Worker              Sched<[WriteVecLogic]>;
2717*9880d681SAndroid Build Coastguard Worker}
2718*9880d681SAndroid Build Coastguard Worker
2719*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
2720*9880d681SAndroid Build Coastguard Worker  defm VMOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2721*9880d681SAndroid Build Coastguard Worker                                        SSEPackedSingle>, PS, VEX;
2722*9880d681SAndroid Build Coastguard Worker  defm VMOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2723*9880d681SAndroid Build Coastguard Worker                                        SSEPackedDouble>, PD, VEX;
2724*9880d681SAndroid Build Coastguard Worker  defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, v8f32, "movmskps",
2725*9880d681SAndroid Build Coastguard Worker                                         SSEPackedSingle>, PS, VEX, VEX_L;
2726*9880d681SAndroid Build Coastguard Worker  defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, v4f64, "movmskpd",
2727*9880d681SAndroid Build Coastguard Worker                                         SSEPackedDouble>, PD, VEX, VEX_L;
2728*9880d681SAndroid Build Coastguard Worker}
2729*9880d681SAndroid Build Coastguard Worker
2730*9880d681SAndroid Build Coastguard Workerdefm MOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2731*9880d681SAndroid Build Coastguard Worker                                     SSEPackedSingle>, PS;
2732*9880d681SAndroid Build Coastguard Workerdefm MOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2733*9880d681SAndroid Build Coastguard Worker                                     SSEPackedDouble>, PD;
2734*9880d681SAndroid Build Coastguard Worker
2735*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
2736*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Logical Instructions
2737*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
2738*9880d681SAndroid Build Coastguard Worker
2739*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { // SSE integer instructions
2740*9880d681SAndroid Build Coastguard Worker
2741*9880d681SAndroid Build Coastguard Worker/// PDI_binop_rm - Simple SSE2 binary operator.
2742*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2743*9880d681SAndroid Build Coastguard Worker                        ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2744*9880d681SAndroid Build Coastguard Worker                        X86MemOperand x86memop, OpndItins itins,
2745*9880d681SAndroid Build Coastguard Worker                        bit IsCommutable, bit Is2Addr> {
2746*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsCommutable in
2747*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2748*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
2749*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
2750*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2751*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2752*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
2753*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
2754*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2755*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
2756*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
2757*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2758*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2759*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpVT (OpNode RC:$src1,
2760*9880d681SAndroid Build Coastguard Worker                                     (bitconvert (memop_frag addr:$src2)))))],
2761*9880d681SAndroid Build Coastguard Worker                                     itins.rm>,
2762*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
2763*9880d681SAndroid Build Coastguard Worker}
2764*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
2765*9880d681SAndroid Build Coastguard Worker
2766*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2767*9880d681SAndroid Build Coastguard Worker                         ValueType OpVT128, ValueType OpVT256,
2768*9880d681SAndroid Build Coastguard Worker                         OpndItins itins, bit IsCommutable = 0, Predicate prd> {
2769*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, prd] in
2770*9880d681SAndroid Build Coastguard Worker  defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2771*9880d681SAndroid Build Coastguard Worker                    VR128, loadv2i64, i128mem, itins, IsCommutable, 0>, VEX_4V;
2772*9880d681SAndroid Build Coastguard Worker
2773*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
2774*9880d681SAndroid Build Coastguard Worker  defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2775*9880d681SAndroid Build Coastguard Worker                           memopv2i64, i128mem, itins, IsCommutable, 1>;
2776*9880d681SAndroid Build Coastguard Worker
2777*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, prd] in
2778*9880d681SAndroid Build Coastguard Worker  defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2779*9880d681SAndroid Build Coastguard Worker                               OpVT256, VR256, loadv4i64, i256mem, itins,
2780*9880d681SAndroid Build Coastguard Worker                               IsCommutable, 0>, VEX_4V, VEX_L;
2781*9880d681SAndroid Build Coastguard Worker}
2782*9880d681SAndroid Build Coastguard Worker
2783*9880d681SAndroid Build Coastguard Worker// These are ordered here for pattern ordering requirements with the fp versions
2784*9880d681SAndroid Build Coastguard Worker
2785*9880d681SAndroid Build Coastguard Workerdefm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64,
2786*9880d681SAndroid Build Coastguard Worker                           SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2787*9880d681SAndroid Build Coastguard Workerdefm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64,
2788*9880d681SAndroid Build Coastguard Worker                           SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2789*9880d681SAndroid Build Coastguard Workerdefm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64,
2790*9880d681SAndroid Build Coastguard Worker                           SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2791*9880d681SAndroid Build Coastguard Workerdefm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2792*9880d681SAndroid Build Coastguard Worker                           SSE_VEC_BIT_ITINS_P, 0, NoVLX>;
2793*9880d681SAndroid Build Coastguard Worker
2794*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2795*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Logical Instructions
2796*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2797*9880d681SAndroid Build Coastguard Worker
2798*9880d681SAndroid Build Coastguard Worker// Multiclass for scalars using the X86 logical operation aliases for FP.
2799*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_packed_scalar_logical_alias<
2800*9880d681SAndroid Build Coastguard Worker    bits<8> opc, string OpcodeStr, SDNode OpNode, OpndItins itins> {
2801*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2802*9880d681SAndroid Build Coastguard Worker                FR32, f32, f128mem, loadf32_128, SSEPackedSingle, itins, 0>,
2803*9880d681SAndroid Build Coastguard Worker                PS, VEX_4V;
2804*9880d681SAndroid Build Coastguard Worker
2805*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2806*9880d681SAndroid Build Coastguard Worker                FR64, f64, f128mem, loadf64_128, SSEPackedDouble, itins, 0>,
2807*9880d681SAndroid Build Coastguard Worker                PD, VEX_4V;
2808*9880d681SAndroid Build Coastguard Worker
2809*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
2810*9880d681SAndroid Build Coastguard Worker    defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2811*9880d681SAndroid Build Coastguard Worker                f32, f128mem, memopfsf32_128, SSEPackedSingle, itins>, PS;
2812*9880d681SAndroid Build Coastguard Worker
2813*9880d681SAndroid Build Coastguard Worker    defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2814*9880d681SAndroid Build Coastguard Worker                f64, f128mem, memopfsf64_128, SSEPackedDouble, itins>, PD;
2815*9880d681SAndroid Build Coastguard Worker  }
2816*9880d681SAndroid Build Coastguard Worker}
2817*9880d681SAndroid Build Coastguard Worker
2818*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
2819*9880d681SAndroid Build Coastguard Worker  defm FsAND  : sse12_fp_packed_scalar_logical_alias<0x54, "and", X86fand,
2820*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2821*9880d681SAndroid Build Coastguard Worker  defm FsOR   : sse12_fp_packed_scalar_logical_alias<0x56, "or", X86for,
2822*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2823*9880d681SAndroid Build Coastguard Worker  defm FsXOR  : sse12_fp_packed_scalar_logical_alias<0x57, "xor", X86fxor,
2824*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2825*9880d681SAndroid Build Coastguard Worker
2826*9880d681SAndroid Build Coastguard Worker  let isCommutable = 0 in
2827*9880d681SAndroid Build Coastguard Worker    defm FsANDN : sse12_fp_packed_scalar_logical_alias<0x55, "andn", X86fandn,
2828*9880d681SAndroid Build Coastguard Worker                  SSE_BIT_ITINS_P>;
2829*9880d681SAndroid Build Coastguard Worker}
2830*9880d681SAndroid Build Coastguard Worker
2831*9880d681SAndroid Build Coastguard Worker// Multiclass for vectors using the X86 logical operation aliases for FP.
2832*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_packed_vector_logical_alias<
2833*9880d681SAndroid Build Coastguard Worker    bits<8> opc, string OpcodeStr, SDNode OpNode, OpndItins itins> {
2834*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoDQI] in {
2835*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2836*9880d681SAndroid Build Coastguard Worker              VR128, v4f32, f128mem, loadv4f32, SSEPackedSingle, itins, 0>,
2837*9880d681SAndroid Build Coastguard Worker              PS, VEX_4V;
2838*9880d681SAndroid Build Coastguard Worker
2839*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2840*9880d681SAndroid Build Coastguard Worker        VR128, v2f64, f128mem, loadv2f64, SSEPackedDouble, itins, 0>,
2841*9880d681SAndroid Build Coastguard Worker        PD, VEX_4V;
2842*9880d681SAndroid Build Coastguard Worker
2843*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2844*9880d681SAndroid Build Coastguard Worker        VR256, v8f32, f256mem, loadv8f32, SSEPackedSingle, itins, 0>,
2845*9880d681SAndroid Build Coastguard Worker        PS, VEX_4V, VEX_L;
2846*9880d681SAndroid Build Coastguard Worker
2847*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2848*9880d681SAndroid Build Coastguard Worker        VR256, v4f64, f256mem, loadv4f64, SSEPackedDouble, itins, 0>,
2849*9880d681SAndroid Build Coastguard Worker        PD, VEX_4V, VEX_L;
2850*9880d681SAndroid Build Coastguard Worker  }
2851*9880d681SAndroid Build Coastguard Worker
2852*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
2853*9880d681SAndroid Build Coastguard Worker    defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2854*9880d681SAndroid Build Coastguard Worker                v4f32, f128mem, memopv4f32, SSEPackedSingle, itins>,
2855*9880d681SAndroid Build Coastguard Worker                PS;
2856*9880d681SAndroid Build Coastguard Worker
2857*9880d681SAndroid Build Coastguard Worker    defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2858*9880d681SAndroid Build Coastguard Worker                v2f64, f128mem, memopv2f64, SSEPackedDouble, itins>,
2859*9880d681SAndroid Build Coastguard Worker                PD;
2860*9880d681SAndroid Build Coastguard Worker  }
2861*9880d681SAndroid Build Coastguard Worker}
2862*9880d681SAndroid Build Coastguard Worker
2863*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
2864*9880d681SAndroid Build Coastguard Worker  defm FvAND  : sse12_fp_packed_vector_logical_alias<0x54, "and", X86fand,
2865*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2866*9880d681SAndroid Build Coastguard Worker  defm FvOR   : sse12_fp_packed_vector_logical_alias<0x56, "or", X86for,
2867*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2868*9880d681SAndroid Build Coastguard Worker  defm FvXOR  : sse12_fp_packed_vector_logical_alias<0x57, "xor", X86fxor,
2869*9880d681SAndroid Build Coastguard Worker                SSE_BIT_ITINS_P>;
2870*9880d681SAndroid Build Coastguard Worker
2871*9880d681SAndroid Build Coastguard Worker  let isCommutable = 0 in
2872*9880d681SAndroid Build Coastguard Worker    defm FvANDN : sse12_fp_packed_vector_logical_alias<0x55, "andn", X86fandn,
2873*9880d681SAndroid Build Coastguard Worker                  SSE_BIT_ITINS_P>;
2874*9880d681SAndroid Build Coastguard Worker}
2875*9880d681SAndroid Build Coastguard Worker
2876*9880d681SAndroid Build Coastguard Worker/// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2877*9880d681SAndroid Build Coastguard Worker///
2878*9880d681SAndroid Build Coastguard Workermulticlass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2879*9880d681SAndroid Build Coastguard Worker                                   SDNode OpNode> {
2880*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
2881*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2882*9880d681SAndroid Build Coastguard Worker        !strconcat(OpcodeStr, "ps"), f256mem,
2883*9880d681SAndroid Build Coastguard Worker        [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2884*9880d681SAndroid Build Coastguard Worker        [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2885*9880d681SAndroid Build Coastguard Worker                           (loadv4i64 addr:$src2)))], 0>, PS, VEX_4V, VEX_L;
2886*9880d681SAndroid Build Coastguard Worker
2887*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2888*9880d681SAndroid Build Coastguard Worker        !strconcat(OpcodeStr, "pd"), f256mem,
2889*9880d681SAndroid Build Coastguard Worker        [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2890*9880d681SAndroid Build Coastguard Worker                                  (bc_v4i64 (v4f64 VR256:$src2))))],
2891*9880d681SAndroid Build Coastguard Worker        [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2892*9880d681SAndroid Build Coastguard Worker                                  (loadv4i64 addr:$src2)))], 0>,
2893*9880d681SAndroid Build Coastguard Worker                                  PD, VEX_4V, VEX_L;
2894*9880d681SAndroid Build Coastguard Worker
2895*9880d681SAndroid Build Coastguard Worker  // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2896*9880d681SAndroid Build Coastguard Worker  // are all promoted to v2i64, and the patterns are covered by the int
2897*9880d681SAndroid Build Coastguard Worker  // version. This is needed in SSE only, because v2i64 isn't supported on
2898*9880d681SAndroid Build Coastguard Worker  // SSE1, but only on SSE2.
2899*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2900*9880d681SAndroid Build Coastguard Worker       !strconcat(OpcodeStr, "ps"), f128mem, [],
2901*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2902*9880d681SAndroid Build Coastguard Worker                                 (loadv2i64 addr:$src2)))], 0>, PS, VEX_4V;
2903*9880d681SAndroid Build Coastguard Worker
2904*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2905*9880d681SAndroid Build Coastguard Worker       !strconcat(OpcodeStr, "pd"), f128mem,
2906*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2907*9880d681SAndroid Build Coastguard Worker                                 (bc_v2i64 (v2f64 VR128:$src2))))],
2908*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2909*9880d681SAndroid Build Coastguard Worker                                 (loadv2i64 addr:$src2)))], 0>,
2910*9880d681SAndroid Build Coastguard Worker                                                 PD, VEX_4V;
2911*9880d681SAndroid Build Coastguard Worker  }
2912*9880d681SAndroid Build Coastguard Worker
2913*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
2914*9880d681SAndroid Build Coastguard Worker    defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2915*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "ps"), f128mem,
2916*9880d681SAndroid Build Coastguard Worker         [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2917*9880d681SAndroid Build Coastguard Worker         [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2918*9880d681SAndroid Build Coastguard Worker                                   (memopv2i64 addr:$src2)))]>, PS;
2919*9880d681SAndroid Build Coastguard Worker
2920*9880d681SAndroid Build Coastguard Worker    defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2921*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "pd"), f128mem,
2922*9880d681SAndroid Build Coastguard Worker         [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2923*9880d681SAndroid Build Coastguard Worker                                   (bc_v2i64 (v2f64 VR128:$src2))))],
2924*9880d681SAndroid Build Coastguard Worker         [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2925*9880d681SAndroid Build Coastguard Worker                                   (memopv2i64 addr:$src2)))]>, PD;
2926*9880d681SAndroid Build Coastguard Worker  }
2927*9880d681SAndroid Build Coastguard Worker}
2928*9880d681SAndroid Build Coastguard Worker
2929*9880d681SAndroid Build Coastguard Workerdefm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2930*9880d681SAndroid Build Coastguard Workerdefm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2931*9880d681SAndroid Build Coastguard Workerdefm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2932*9880d681SAndroid Build Coastguard Workerlet isCommutable = 0 in
2933*9880d681SAndroid Build Coastguard Worker  defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2934*9880d681SAndroid Build Coastguard Worker
2935*9880d681SAndroid Build Coastguard Worker// AVX1 requires type coercions in order to fold loads directly into logical
2936*9880d681SAndroid Build Coastguard Worker// operations.
2937*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
2938*9880d681SAndroid Build Coastguard Worker  def : Pat<(bc_v8f32 (and VR256:$src1, (loadv4i64 addr:$src2))),
2939*9880d681SAndroid Build Coastguard Worker            (VANDPSYrm VR256:$src1, addr:$src2)>;
2940*9880d681SAndroid Build Coastguard Worker  def : Pat<(bc_v8f32 (or VR256:$src1, (loadv4i64 addr:$src2))),
2941*9880d681SAndroid Build Coastguard Worker            (VORPSYrm VR256:$src1, addr:$src2)>;
2942*9880d681SAndroid Build Coastguard Worker  def : Pat<(bc_v8f32 (xor VR256:$src1, (loadv4i64 addr:$src2))),
2943*9880d681SAndroid Build Coastguard Worker            (VXORPSYrm VR256:$src1, addr:$src2)>;
2944*9880d681SAndroid Build Coastguard Worker  def : Pat<(bc_v8f32 (X86andnp VR256:$src1, (loadv4i64 addr:$src2))),
2945*9880d681SAndroid Build Coastguard Worker            (VANDNPSYrm VR256:$src1, addr:$src2)>;
2946*9880d681SAndroid Build Coastguard Worker}
2947*9880d681SAndroid Build Coastguard Worker
2948*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2949*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Arithmetic Instructions
2950*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
2951*9880d681SAndroid Build Coastguard Worker
2952*9880d681SAndroid Build Coastguard Worker/// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2953*9880d681SAndroid Build Coastguard Worker/// vector forms.
2954*9880d681SAndroid Build Coastguard Worker///
2955*9880d681SAndroid Build Coastguard Worker/// In addition, we also have a special variant of the scalar form here to
2956*9880d681SAndroid Build Coastguard Worker/// represent the associated intrinsic operation.  This form is unlike the
2957*9880d681SAndroid Build Coastguard Worker/// plain scalar form, in that it takes an entire vector (instead of a scalar)
2958*9880d681SAndroid Build Coastguard Worker/// and leaves the top elements unmodified (therefore these cannot be commuted).
2959*9880d681SAndroid Build Coastguard Worker///
2960*9880d681SAndroid Build Coastguard Worker/// These three forms can each be reg+reg or reg+mem.
2961*9880d681SAndroid Build Coastguard Worker///
2962*9880d681SAndroid Build Coastguard Worker
2963*9880d681SAndroid Build Coastguard Worker/// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2964*9880d681SAndroid Build Coastguard Worker/// classes below
2965*9880d681SAndroid Build Coastguard Workermulticlass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
2966*9880d681SAndroid Build Coastguard Worker                                  SDNode OpNode, SizeItins itins> {
2967*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
2968*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2969*9880d681SAndroid Build Coastguard Worker                               VR128, v4f32, f128mem, loadv4f32,
2970*9880d681SAndroid Build Coastguard Worker                               SSEPackedSingle, itins.s, 0>, PS, VEX_4V;
2971*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2972*9880d681SAndroid Build Coastguard Worker                               VR128, v2f64, f128mem, loadv2f64,
2973*9880d681SAndroid Build Coastguard Worker                               SSEPackedDouble, itins.d, 0>, PD, VEX_4V;
2974*9880d681SAndroid Build Coastguard Worker
2975*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
2976*9880d681SAndroid Build Coastguard Worker                        OpNode, VR256, v8f32, f256mem, loadv8f32,
2977*9880d681SAndroid Build Coastguard Worker                        SSEPackedSingle, itins.s, 0>, PS, VEX_4V, VEX_L;
2978*9880d681SAndroid Build Coastguard Worker  defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
2979*9880d681SAndroid Build Coastguard Worker                        OpNode, VR256, v4f64, f256mem, loadv4f64,
2980*9880d681SAndroid Build Coastguard Worker                        SSEPackedDouble, itins.d, 0>, PD, VEX_4V, VEX_L;
2981*9880d681SAndroid Build Coastguard Worker  }
2982*9880d681SAndroid Build Coastguard Worker
2983*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
2984*9880d681SAndroid Build Coastguard Worker    defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2985*9880d681SAndroid Build Coastguard Worker                              v4f32, f128mem, memopv4f32, SSEPackedSingle,
2986*9880d681SAndroid Build Coastguard Worker                              itins.s>, PS;
2987*9880d681SAndroid Build Coastguard Worker    defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2988*9880d681SAndroid Build Coastguard Worker                              v2f64, f128mem, memopv2f64, SSEPackedDouble,
2989*9880d681SAndroid Build Coastguard Worker                              itins.d>, PD;
2990*9880d681SAndroid Build Coastguard Worker  }
2991*9880d681SAndroid Build Coastguard Worker}
2992*9880d681SAndroid Build Coastguard Worker
2993*9880d681SAndroid Build Coastguard Workermulticlass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2994*9880d681SAndroid Build Coastguard Worker                                  SizeItins itins> {
2995*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2996*9880d681SAndroid Build Coastguard Worker                         OpNode, FR32, f32mem, SSEPackedSingle, itins.s, 0>,
2997*9880d681SAndroid Build Coastguard Worker                         XS, VEX_4V, VEX_LIG;
2998*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2999*9880d681SAndroid Build Coastguard Worker                         OpNode, FR64, f64mem, SSEPackedDouble, itins.d, 0>,
3000*9880d681SAndroid Build Coastguard Worker                         XD, VEX_4V, VEX_LIG;
3001*9880d681SAndroid Build Coastguard Worker
3002*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
3003*9880d681SAndroid Build Coastguard Worker    defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3004*9880d681SAndroid Build Coastguard Worker                              OpNode, FR32, f32mem, SSEPackedSingle,
3005*9880d681SAndroid Build Coastguard Worker                              itins.s>, XS;
3006*9880d681SAndroid Build Coastguard Worker    defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3007*9880d681SAndroid Build Coastguard Worker                              OpNode, FR64, f64mem, SSEPackedDouble,
3008*9880d681SAndroid Build Coastguard Worker                              itins.d>, XD;
3009*9880d681SAndroid Build Coastguard Worker  }
3010*9880d681SAndroid Build Coastguard Worker}
3011*9880d681SAndroid Build Coastguard Worker
3012*9880d681SAndroid Build Coastguard Workermulticlass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
3013*9880d681SAndroid Build Coastguard Worker                                      SizeItins itins> {
3014*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3015*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3016*9880d681SAndroid Build Coastguard Worker                   SSEPackedSingle, itins.s, 0>, XS, VEX_4V, VEX_LIG;
3017*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3018*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3019*9880d681SAndroid Build Coastguard Worker                   SSEPackedDouble, itins.d, 0>, XD, VEX_4V, VEX_LIG;
3020*9880d681SAndroid Build Coastguard Worker
3021*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in {
3022*9880d681SAndroid Build Coastguard Worker    defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3023*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3024*9880d681SAndroid Build Coastguard Worker                   SSEPackedSingle, itins.s>, XS;
3025*9880d681SAndroid Build Coastguard Worker    defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3026*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3027*9880d681SAndroid Build Coastguard Worker                   SSEPackedDouble, itins.d>, XD;
3028*9880d681SAndroid Build Coastguard Worker  }
3029*9880d681SAndroid Build Coastguard Worker}
3030*9880d681SAndroid Build Coastguard Worker
3031*9880d681SAndroid Build Coastguard Worker// Binary Arithmetic instructions
3032*9880d681SAndroid Build Coastguard Workerdefm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SSE_ALU_ITINS_P>,
3033*9880d681SAndroid Build Coastguard Worker           basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
3034*9880d681SAndroid Build Coastguard Worker           basic_sse12_fp_binop_s_int<0x58, "add", SSE_ALU_ITINS_S>;
3035*9880d681SAndroid Build Coastguard Workerdefm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SSE_MUL_ITINS_P>,
3036*9880d681SAndroid Build Coastguard Worker           basic_sse12_fp_binop_s<0x59, "mul", fmul, SSE_MUL_ITINS_S>,
3037*9880d681SAndroid Build Coastguard Worker           basic_sse12_fp_binop_s_int<0x59, "mul", SSE_MUL_ITINS_S>;
3038*9880d681SAndroid Build Coastguard Workerlet isCommutable = 0 in {
3039*9880d681SAndroid Build Coastguard Worker  defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SSE_ALU_ITINS_P>,
3040*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>,
3041*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s_int<0x5C, "sub", SSE_ALU_ITINS_S>;
3042*9880d681SAndroid Build Coastguard Worker  defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SSE_DIV_ITINS_P>,
3043*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5E, "div", fdiv, SSE_DIV_ITINS_S>,
3044*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s_int<0x5E, "div", SSE_DIV_ITINS_S>;
3045*9880d681SAndroid Build Coastguard Worker  defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SSE_ALU_ITINS_P>,
3046*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>,
3047*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s_int<0x5F, "max", SSE_ALU_ITINS_S>;
3048*9880d681SAndroid Build Coastguard Worker  defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SSE_ALU_ITINS_P>,
3049*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>,
3050*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s_int<0x5D, "min", SSE_ALU_ITINS_S>;
3051*9880d681SAndroid Build Coastguard Worker}
3052*9880d681SAndroid Build Coastguard Worker
3053*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
3054*9880d681SAndroid Build Coastguard Worker  defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_P>,
3055*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_S>;
3056*9880d681SAndroid Build Coastguard Worker  defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SSE_ALU_ITINS_P>,
3057*9880d681SAndroid Build Coastguard Worker             basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SSE_ALU_ITINS_S>;
3058*9880d681SAndroid Build Coastguard Worker}
3059*9880d681SAndroid Build Coastguard Worker
3060*9880d681SAndroid Build Coastguard Worker// Patterns used to select SSE scalar fp arithmetic instructions from
3061*9880d681SAndroid Build Coastguard Worker// either:
3062*9880d681SAndroid Build Coastguard Worker//
3063*9880d681SAndroid Build Coastguard Worker// (1) a scalar fp operation followed by a blend
3064*9880d681SAndroid Build Coastguard Worker//
3065*9880d681SAndroid Build Coastguard Worker// The effect is that the backend no longer emits unnecessary vector
3066*9880d681SAndroid Build Coastguard Worker// insert instructions immediately after SSE scalar fp instructions
3067*9880d681SAndroid Build Coastguard Worker// like addss or mulss.
3068*9880d681SAndroid Build Coastguard Worker//
3069*9880d681SAndroid Build Coastguard Worker// For example, given the following code:
3070*9880d681SAndroid Build Coastguard Worker//   __m128 foo(__m128 A, __m128 B) {
3071*9880d681SAndroid Build Coastguard Worker//     A[0] += B[0];
3072*9880d681SAndroid Build Coastguard Worker//     return A;
3073*9880d681SAndroid Build Coastguard Worker//   }
3074*9880d681SAndroid Build Coastguard Worker//
3075*9880d681SAndroid Build Coastguard Worker// Previously we generated:
3076*9880d681SAndroid Build Coastguard Worker//   addss %xmm0, %xmm1
3077*9880d681SAndroid Build Coastguard Worker//   movss %xmm1, %xmm0
3078*9880d681SAndroid Build Coastguard Worker//
3079*9880d681SAndroid Build Coastguard Worker// We now generate:
3080*9880d681SAndroid Build Coastguard Worker//   addss %xmm1, %xmm0
3081*9880d681SAndroid Build Coastguard Worker//
3082*9880d681SAndroid Build Coastguard Worker// (2) a vector packed single/double fp operation followed by a vector insert
3083*9880d681SAndroid Build Coastguard Worker//
3084*9880d681SAndroid Build Coastguard Worker// The effect is that the backend converts the packed fp instruction
3085*9880d681SAndroid Build Coastguard Worker// followed by a vector insert into a single SSE scalar fp instruction.
3086*9880d681SAndroid Build Coastguard Worker//
3087*9880d681SAndroid Build Coastguard Worker// For example, given the following code:
3088*9880d681SAndroid Build Coastguard Worker//   __m128 foo(__m128 A, __m128 B) {
3089*9880d681SAndroid Build Coastguard Worker//     __m128 C = A + B;
3090*9880d681SAndroid Build Coastguard Worker//     return (__m128) {c[0], a[1], a[2], a[3]};
3091*9880d681SAndroid Build Coastguard Worker//   }
3092*9880d681SAndroid Build Coastguard Worker//
3093*9880d681SAndroid Build Coastguard Worker// Previously we generated:
3094*9880d681SAndroid Build Coastguard Worker//   addps %xmm0, %xmm1
3095*9880d681SAndroid Build Coastguard Worker//   movss %xmm1, %xmm0
3096*9880d681SAndroid Build Coastguard Worker//
3097*9880d681SAndroid Build Coastguard Worker// We now generate:
3098*9880d681SAndroid Build Coastguard Worker//   addss %xmm1, %xmm0
3099*9880d681SAndroid Build Coastguard Worker
3100*9880d681SAndroid Build Coastguard Worker// TODO: Some canonicalization in lowering would simplify the number of
3101*9880d681SAndroid Build Coastguard Worker// patterns we have to try to match.
3102*9880d681SAndroid Build Coastguard Workermulticlass scalar_math_f32_patterns<SDNode Op, string OpcPrefix> {
3103*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE1] in {
3104*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via movss
3105*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3106*9880d681SAndroid Build Coastguard Worker          (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3107*9880d681SAndroid Build Coastguard Worker          FR32:$src))))),
3108*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst,
3109*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR32:$src, VR128))>;
3110*9880d681SAndroid Build Coastguard Worker
3111*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via movss
3112*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3113*9880d681SAndroid Build Coastguard Worker          (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3114*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3115*9880d681SAndroid Build Coastguard Worker  }
3116*9880d681SAndroid Build Coastguard Worker
3117*9880d681SAndroid Build Coastguard Worker  // With SSE 4.1, blendi is preferred to movsd, so match that too.
3118*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE41] in {
3119*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via blend
3120*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3121*9880d681SAndroid Build Coastguard Worker          (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3122*9880d681SAndroid Build Coastguard Worker          FR32:$src))), (i8 1))),
3123*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst,
3124*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR32:$src, VR128))>;
3125*9880d681SAndroid Build Coastguard Worker
3126*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via blend
3127*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst),
3128*9880d681SAndroid Build Coastguard Worker          (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)), (i8 1))),
3129*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SSrr_Int)v4f32:$dst, v4f32:$src)>;
3130*9880d681SAndroid Build Coastguard Worker
3131*9880d681SAndroid Build Coastguard Worker  }
3132*9880d681SAndroid Build Coastguard Worker
3133*9880d681SAndroid Build Coastguard Worker  // Repeat everything for AVX, except for the movss + scalar combo...
3134*9880d681SAndroid Build Coastguard Worker  // because that one shouldn't occur with AVX codegen?
3135*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in {
3136*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via blend
3137*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3138*9880d681SAndroid Build Coastguard Worker          (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3139*9880d681SAndroid Build Coastguard Worker          FR32:$src))), (i8 1))),
3140*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst,
3141*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR32:$src, VR128))>;
3142*9880d681SAndroid Build Coastguard Worker
3143*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via movss
3144*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3145*9880d681SAndroid Build Coastguard Worker          (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3146*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3147*9880d681SAndroid Build Coastguard Worker
3148*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via blend
3149*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst),
3150*9880d681SAndroid Build Coastguard Worker          (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)), (i8 1))),
3151*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3152*9880d681SAndroid Build Coastguard Worker  }
3153*9880d681SAndroid Build Coastguard Worker}
3154*9880d681SAndroid Build Coastguard Worker
3155*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f32_patterns<fadd, "ADD">;
3156*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f32_patterns<fsub, "SUB">;
3157*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f32_patterns<fmul, "MUL">;
3158*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f32_patterns<fdiv, "DIV">;
3159*9880d681SAndroid Build Coastguard Worker
3160*9880d681SAndroid Build Coastguard Workermulticlass scalar_math_f64_patterns<SDNode Op, string OpcPrefix> {
3161*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE2] in {
3162*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via movsd
3163*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3164*9880d681SAndroid Build Coastguard Worker          (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3165*9880d681SAndroid Build Coastguard Worker          FR64:$src))))),
3166*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst,
3167*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128))>;
3168*9880d681SAndroid Build Coastguard Worker
3169*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via movsd
3170*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3171*9880d681SAndroid Build Coastguard Worker          (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3172*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3173*9880d681SAndroid Build Coastguard Worker  }
3174*9880d681SAndroid Build Coastguard Worker
3175*9880d681SAndroid Build Coastguard Worker  // With SSE 4.1, blendi is preferred to movsd, so match those too.
3176*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE41] in {
3177*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via blend
3178*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3179*9880d681SAndroid Build Coastguard Worker          (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3180*9880d681SAndroid Build Coastguard Worker          FR64:$src))), (i8 1))),
3181*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst,
3182*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128))>;
3183*9880d681SAndroid Build Coastguard Worker
3184*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via blend
3185*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst),
3186*9880d681SAndroid Build Coastguard Worker          (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)), (i8 1))),
3187*9880d681SAndroid Build Coastguard Worker      (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3188*9880d681SAndroid Build Coastguard Worker  }
3189*9880d681SAndroid Build Coastguard Worker
3190*9880d681SAndroid Build Coastguard Worker  // Repeat everything for AVX.
3191*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in {
3192*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via movsd
3193*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3194*9880d681SAndroid Build Coastguard Worker          (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3195*9880d681SAndroid Build Coastguard Worker          FR64:$src))))),
3196*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst,
3197*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128))>;
3198*9880d681SAndroid Build Coastguard Worker
3199*9880d681SAndroid Build Coastguard Worker    // extracted scalar math op with insert via blend
3200*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3201*9880d681SAndroid Build Coastguard Worker          (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3202*9880d681SAndroid Build Coastguard Worker          FR64:$src))), (i8 1))),
3203*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst,
3204*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS FR64:$src, VR128))>;
3205*9880d681SAndroid Build Coastguard Worker
3206*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via movsd
3207*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3208*9880d681SAndroid Build Coastguard Worker          (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3209*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3210*9880d681SAndroid Build Coastguard Worker
3211*9880d681SAndroid Build Coastguard Worker    // vector math op with insert via blend
3212*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst),
3213*9880d681SAndroid Build Coastguard Worker          (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)), (i8 1))),
3214*9880d681SAndroid Build Coastguard Worker      (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3215*9880d681SAndroid Build Coastguard Worker  }
3216*9880d681SAndroid Build Coastguard Worker}
3217*9880d681SAndroid Build Coastguard Worker
3218*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f64_patterns<fadd, "ADD">;
3219*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f64_patterns<fsub, "SUB">;
3220*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f64_patterns<fmul, "MUL">;
3221*9880d681SAndroid Build Coastguard Workerdefm : scalar_math_f64_patterns<fdiv, "DIV">;
3222*9880d681SAndroid Build Coastguard Worker
3223*9880d681SAndroid Build Coastguard Worker
3224*9880d681SAndroid Build Coastguard Worker/// Unop Arithmetic
3225*9880d681SAndroid Build Coastguard Worker/// In addition, we also have a special variant of the scalar form here to
3226*9880d681SAndroid Build Coastguard Worker/// represent the associated intrinsic operation.  This form is unlike the
3227*9880d681SAndroid Build Coastguard Worker/// plain scalar form, in that it takes an entire vector (instead of a
3228*9880d681SAndroid Build Coastguard Worker/// scalar) and leaves the top elements undefined.
3229*9880d681SAndroid Build Coastguard Worker///
3230*9880d681SAndroid Build Coastguard Worker/// And, we have a special variant form for a full-vector intrinsic form.
3231*9880d681SAndroid Build Coastguard Worker
3232*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFSqrt in {
3233*9880d681SAndroid Build Coastguard Workerdef SSE_SQRTPS : OpndItins<
3234*9880d681SAndroid Build Coastguard Worker  IIC_SSE_SQRTPS_RR, IIC_SSE_SQRTPS_RM
3235*9880d681SAndroid Build Coastguard Worker>;
3236*9880d681SAndroid Build Coastguard Worker
3237*9880d681SAndroid Build Coastguard Workerdef SSE_SQRTSS : OpndItins<
3238*9880d681SAndroid Build Coastguard Worker  IIC_SSE_SQRTSS_RR, IIC_SSE_SQRTSS_RM
3239*9880d681SAndroid Build Coastguard Worker>;
3240*9880d681SAndroid Build Coastguard Worker
3241*9880d681SAndroid Build Coastguard Workerdef SSE_SQRTPD : OpndItins<
3242*9880d681SAndroid Build Coastguard Worker  IIC_SSE_SQRTPD_RR, IIC_SSE_SQRTPD_RM
3243*9880d681SAndroid Build Coastguard Worker>;
3244*9880d681SAndroid Build Coastguard Worker
3245*9880d681SAndroid Build Coastguard Workerdef SSE_SQRTSD : OpndItins<
3246*9880d681SAndroid Build Coastguard Worker  IIC_SSE_SQRTSD_RR, IIC_SSE_SQRTSD_RM
3247*9880d681SAndroid Build Coastguard Worker>;
3248*9880d681SAndroid Build Coastguard Worker}
3249*9880d681SAndroid Build Coastguard Worker
3250*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFRsqrt in {
3251*9880d681SAndroid Build Coastguard Workerdef SSE_RSQRTPS : OpndItins<
3252*9880d681SAndroid Build Coastguard Worker  IIC_SSE_RSQRTPS_RR, IIC_SSE_RSQRTPS_RM
3253*9880d681SAndroid Build Coastguard Worker>;
3254*9880d681SAndroid Build Coastguard Worker
3255*9880d681SAndroid Build Coastguard Workerdef SSE_RSQRTSS : OpndItins<
3256*9880d681SAndroid Build Coastguard Worker  IIC_SSE_RSQRTSS_RR, IIC_SSE_RSQRTSS_RM
3257*9880d681SAndroid Build Coastguard Worker>;
3258*9880d681SAndroid Build Coastguard Worker}
3259*9880d681SAndroid Build Coastguard Worker
3260*9880d681SAndroid Build Coastguard Workerlet Sched = WriteFRcp in {
3261*9880d681SAndroid Build Coastguard Workerdef SSE_RCPP : OpndItins<
3262*9880d681SAndroid Build Coastguard Worker  IIC_SSE_RCPP_RR, IIC_SSE_RCPP_RM
3263*9880d681SAndroid Build Coastguard Worker>;
3264*9880d681SAndroid Build Coastguard Worker
3265*9880d681SAndroid Build Coastguard Workerdef SSE_RCPS : OpndItins<
3266*9880d681SAndroid Build Coastguard Worker  IIC_SSE_RCPS_RR, IIC_SSE_RCPS_RM
3267*9880d681SAndroid Build Coastguard Worker>;
3268*9880d681SAndroid Build Coastguard Worker}
3269*9880d681SAndroid Build Coastguard Worker
3270*9880d681SAndroid Build Coastguard Worker/// sse_fp_unop_s - SSE1 unops in scalar form
3271*9880d681SAndroid Build Coastguard Worker/// For the non-AVX defs, we need $src1 to be tied to $dst because
3272*9880d681SAndroid Build Coastguard Worker/// the HW instructions are 2 operand / destructive.
3273*9880d681SAndroid Build Coastguard Workermulticlass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
3274*9880d681SAndroid Build Coastguard Worker                          ValueType vt, ValueType ScalarVT,
3275*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, Operand vec_memop,
3276*9880d681SAndroid Build Coastguard Worker                          ComplexPattern mem_cpat, Intrinsic Intr,
3277*9880d681SAndroid Build Coastguard Worker                          SDNode OpNode, Domain d, OpndItins itins,
3278*9880d681SAndroid Build Coastguard Worker                          Predicate target, string Suffix> {
3279*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in {
3280*9880d681SAndroid Build Coastguard Worker  def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1),
3281*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
3282*9880d681SAndroid Build Coastguard Worker            [(set RC:$dst, (OpNode RC:$src1))], itins.rr, d>, Sched<[itins.Sched]>,
3283*9880d681SAndroid Build Coastguard Worker            Requires<[target]>;
3284*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
3285*9880d681SAndroid Build Coastguard Worker  def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1),
3286*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
3287*9880d681SAndroid Build Coastguard Worker            [(set RC:$dst, (OpNode (load addr:$src1)))], itins.rm, d>,
3288*9880d681SAndroid Build Coastguard Worker            Sched<[itins.Sched.Folded, ReadAfterLd]>,
3289*9880d681SAndroid Build Coastguard Worker            Requires<[target, OptForSize]>;
3290*9880d681SAndroid Build Coastguard Worker
3291*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1, Constraints = "$src1 = $dst" in {
3292*9880d681SAndroid Build Coastguard Worker  def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3293*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3294*9880d681SAndroid Build Coastguard Worker            []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3295*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
3296*9880d681SAndroid Build Coastguard Worker  def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, vec_memop:$src2),
3297*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3298*9880d681SAndroid Build Coastguard Worker            []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3299*9880d681SAndroid Build Coastguard Worker  }
3300*9880d681SAndroid Build Coastguard Worker  }
3301*9880d681SAndroid Build Coastguard Worker
3302*9880d681SAndroid Build Coastguard Worker  let Predicates = [target] in {
3303*9880d681SAndroid Build Coastguard Worker  def : Pat<(vt (OpNode mem_cpat:$src)),
3304*9880d681SAndroid Build Coastguard Worker            (vt (COPY_TO_REGCLASS (vt (!cast<Instruction>(NAME#Suffix##m_Int)
3305*9880d681SAndroid Build Coastguard Worker                 (vt (IMPLICIT_DEF)), mem_cpat:$src)), RC))>;
3306*9880d681SAndroid Build Coastguard Worker  // These are unary operations, but they are modeled as having 2 source operands
3307*9880d681SAndroid Build Coastguard Worker  // because the high elements of the destination are unchanged in SSE.
3308*9880d681SAndroid Build Coastguard Worker  def : Pat<(Intr VR128:$src),
3309*9880d681SAndroid Build Coastguard Worker            (!cast<Instruction>(NAME#Suffix##r_Int) VR128:$src, VR128:$src)>;
3310*9880d681SAndroid Build Coastguard Worker  def : Pat<(Intr (load addr:$src)),
3311*9880d681SAndroid Build Coastguard Worker            (vt (COPY_TO_REGCLASS(!cast<Instruction>(NAME#Suffix##m)
3312*9880d681SAndroid Build Coastguard Worker                                      addr:$src), VR128))>;
3313*9880d681SAndroid Build Coastguard Worker  }
3314*9880d681SAndroid Build Coastguard Worker  // We don't want to fold scalar loads into these instructions unless
3315*9880d681SAndroid Build Coastguard Worker  // optimizing for size. This is because the folded instruction will have a
3316*9880d681SAndroid Build Coastguard Worker  // partial register update, while the unfolded sequence will not, e.g.
3317*9880d681SAndroid Build Coastguard Worker  // movss mem, %xmm0
3318*9880d681SAndroid Build Coastguard Worker  // rcpss %xmm0, %xmm0
3319*9880d681SAndroid Build Coastguard Worker  // which has a clobber before the rcp, vs.
3320*9880d681SAndroid Build Coastguard Worker  // rcpss mem, %xmm0
3321*9880d681SAndroid Build Coastguard Worker  let Predicates = [target, OptForSize] in {
3322*9880d681SAndroid Build Coastguard Worker    def : Pat<(Intr mem_cpat:$src),
3323*9880d681SAndroid Build Coastguard Worker               (!cast<Instruction>(NAME#Suffix##m_Int)
3324*9880d681SAndroid Build Coastguard Worker                      (vt (IMPLICIT_DEF)), mem_cpat:$src)>;
3325*9880d681SAndroid Build Coastguard Worker  }
3326*9880d681SAndroid Build Coastguard Worker}
3327*9880d681SAndroid Build Coastguard Worker
3328*9880d681SAndroid Build Coastguard Workermulticlass avx_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
3329*9880d681SAndroid Build Coastguard Worker                          ValueType vt, ValueType ScalarVT,
3330*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, Operand vec_memop,
3331*9880d681SAndroid Build Coastguard Worker                          ComplexPattern mem_cpat,
3332*9880d681SAndroid Build Coastguard Worker                          Intrinsic Intr, SDNode OpNode, Domain d,
3333*9880d681SAndroid Build Coastguard Worker                          OpndItins itins, string Suffix> {
3334*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in {
3335*9880d681SAndroid Build Coastguard Worker  def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
3336*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3337*9880d681SAndroid Build Coastguard Worker            [], itins.rr, d>, Sched<[itins.Sched]>;
3338*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
3339*9880d681SAndroid Build Coastguard Worker  def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
3340*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3341*9880d681SAndroid Build Coastguard Worker            [], itins.rm, d>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3342*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in {
3343*9880d681SAndroid Build Coastguard Worker  def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst),
3344*9880d681SAndroid Build Coastguard Worker                (ins VR128:$src1, VR128:$src2),
3345*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3346*9880d681SAndroid Build Coastguard Worker             []>, Sched<[itins.Sched.Folded]>;
3347*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
3348*9880d681SAndroid Build Coastguard Worker  def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst),
3349*9880d681SAndroid Build Coastguard Worker                (ins VR128:$src1, vec_memop:$src2),
3350*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3351*9880d681SAndroid Build Coastguard Worker             []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3352*9880d681SAndroid Build Coastguard Worker  }
3353*9880d681SAndroid Build Coastguard Worker  }
3354*9880d681SAndroid Build Coastguard Worker
3355*9880d681SAndroid Build Coastguard Worker  // We don't want to fold scalar loads into these instructions unless
3356*9880d681SAndroid Build Coastguard Worker  // optimizing for size. This is because the folded instruction will have a
3357*9880d681SAndroid Build Coastguard Worker  // partial register update, while the unfolded sequence will not, e.g.
3358*9880d681SAndroid Build Coastguard Worker  // vmovss mem, %xmm0
3359*9880d681SAndroid Build Coastguard Worker  // vrcpss %xmm0, %xmm0, %xmm0
3360*9880d681SAndroid Build Coastguard Worker  // which has a clobber before the rcp, vs.
3361*9880d681SAndroid Build Coastguard Worker  // vrcpss mem, %xmm0, %xmm0
3362*9880d681SAndroid Build Coastguard Worker  // TODO: In theory, we could fold the load, and avoid the stall caused by
3363*9880d681SAndroid Build Coastguard Worker  // the partial register store, either in ExeDepFix or with smarter RA.
3364*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in {
3365*9880d681SAndroid Build Coastguard Worker   def : Pat<(OpNode RC:$src),  (!cast<Instruction>("V"#NAME#Suffix##r)
3366*9880d681SAndroid Build Coastguard Worker                                (ScalarVT (IMPLICIT_DEF)), RC:$src)>;
3367*9880d681SAndroid Build Coastguard Worker  }
3368*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in {
3369*9880d681SAndroid Build Coastguard Worker   def : Pat<(Intr VR128:$src),
3370*9880d681SAndroid Build Coastguard Worker             (!cast<Instruction>("V"#NAME#Suffix##r_Int) (vt (IMPLICIT_DEF)),
3371*9880d681SAndroid Build Coastguard Worker                                 VR128:$src)>;
3372*9880d681SAndroid Build Coastguard Worker  }
3373*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, OptForSize] in {
3374*9880d681SAndroid Build Coastguard Worker    def : Pat<(Intr mem_cpat:$src),
3375*9880d681SAndroid Build Coastguard Worker              (!cast<Instruction>("V"#NAME#Suffix##m_Int)
3376*9880d681SAndroid Build Coastguard Worker                    (vt (IMPLICIT_DEF)), mem_cpat:$src)>;
3377*9880d681SAndroid Build Coastguard Worker  }
3378*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX, OptForSize] in {
3379*9880d681SAndroid Build Coastguard Worker    def : Pat<(ScalarVT (OpNode (load addr:$src))),
3380*9880d681SAndroid Build Coastguard Worker              (!cast<Instruction>("V"#NAME#Suffix##m) (ScalarVT (IMPLICIT_DEF)),
3381*9880d681SAndroid Build Coastguard Worker            addr:$src)>;
3382*9880d681SAndroid Build Coastguard Worker    def : Pat<(vt (OpNode mem_cpat:$src)),
3383*9880d681SAndroid Build Coastguard Worker              (!cast<Instruction>("V"#NAME#Suffix##m_Int) (vt (IMPLICIT_DEF)),
3384*9880d681SAndroid Build Coastguard Worker                                  mem_cpat:$src)>;
3385*9880d681SAndroid Build Coastguard Worker  }
3386*9880d681SAndroid Build Coastguard Worker}
3387*9880d681SAndroid Build Coastguard Worker
3388*9880d681SAndroid Build Coastguard Worker/// sse1_fp_unop_p - SSE1 unops in packed form.
3389*9880d681SAndroid Build Coastguard Workermulticlass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3390*9880d681SAndroid Build Coastguard Worker                          OpndItins itins, list<Predicate> prds> {
3391*9880d681SAndroid Build Coastguard Workerlet Predicates = prds in {
3392*9880d681SAndroid Build Coastguard Worker  def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3393*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
3394*9880d681SAndroid Build Coastguard Worker                                  "ps\t{$src, $dst|$dst, $src}"),
3395*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))],
3396*9880d681SAndroid Build Coastguard Worker                       itins.rr>, VEX, Sched<[itins.Sched]>;
3397*9880d681SAndroid Build Coastguard Worker  def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3398*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
3399*9880d681SAndroid Build Coastguard Worker                                  "ps\t{$src, $dst|$dst, $src}"),
3400*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))],
3401*9880d681SAndroid Build Coastguard Worker                       itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3402*9880d681SAndroid Build Coastguard Worker  def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3403*9880d681SAndroid Build Coastguard Worker                        !strconcat("v", OpcodeStr,
3404*9880d681SAndroid Build Coastguard Worker                                   "ps\t{$src, $dst|$dst, $src}"),
3405*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))],
3406*9880d681SAndroid Build Coastguard Worker                        itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3407*9880d681SAndroid Build Coastguard Worker  def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3408*9880d681SAndroid Build Coastguard Worker                        !strconcat("v", OpcodeStr,
3409*9880d681SAndroid Build Coastguard Worker                                   "ps\t{$src, $dst|$dst, $src}"),
3410*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))],
3411*9880d681SAndroid Build Coastguard Worker                        itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3412*9880d681SAndroid Build Coastguard Worker}
3413*9880d681SAndroid Build Coastguard Worker
3414*9880d681SAndroid Build Coastguard Worker  def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3415*9880d681SAndroid Build Coastguard Worker                !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3416*9880d681SAndroid Build Coastguard Worker                [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))], itins.rr>,
3417*9880d681SAndroid Build Coastguard Worker            Sched<[itins.Sched]>;
3418*9880d681SAndroid Build Coastguard Worker  def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3419*9880d681SAndroid Build Coastguard Worker                !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3420*9880d681SAndroid Build Coastguard Worker                [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))], itins.rm>,
3421*9880d681SAndroid Build Coastguard Worker            Sched<[itins.Sched.Folded]>;
3422*9880d681SAndroid Build Coastguard Worker}
3423*9880d681SAndroid Build Coastguard Worker
3424*9880d681SAndroid Build Coastguard Worker/// sse2_fp_unop_p - SSE2 unops in vector forms.
3425*9880d681SAndroid Build Coastguard Workermulticlass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3426*9880d681SAndroid Build Coastguard Worker                          SDNode OpNode, OpndItins itins> {
3427*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
3428*9880d681SAndroid Build Coastguard Worker  def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3429*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
3430*9880d681SAndroid Build Coastguard Worker                                  "pd\t{$src, $dst|$dst, $src}"),
3431*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))],
3432*9880d681SAndroid Build Coastguard Worker                       itins.rr>, VEX, Sched<[itins.Sched]>;
3433*9880d681SAndroid Build Coastguard Worker  def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3434*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
3435*9880d681SAndroid Build Coastguard Worker                                  "pd\t{$src, $dst|$dst, $src}"),
3436*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))],
3437*9880d681SAndroid Build Coastguard Worker                       itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3438*9880d681SAndroid Build Coastguard Worker  def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3439*9880d681SAndroid Build Coastguard Worker                        !strconcat("v", OpcodeStr,
3440*9880d681SAndroid Build Coastguard Worker                                   "pd\t{$src, $dst|$dst, $src}"),
3441*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))],
3442*9880d681SAndroid Build Coastguard Worker                        itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3443*9880d681SAndroid Build Coastguard Worker  def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3444*9880d681SAndroid Build Coastguard Worker                        !strconcat("v", OpcodeStr,
3445*9880d681SAndroid Build Coastguard Worker                                   "pd\t{$src, $dst|$dst, $src}"),
3446*9880d681SAndroid Build Coastguard Worker                        [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))],
3447*9880d681SAndroid Build Coastguard Worker                        itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3448*9880d681SAndroid Build Coastguard Worker}
3449*9880d681SAndroid Build Coastguard Worker
3450*9880d681SAndroid Build Coastguard Worker  def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3451*9880d681SAndroid Build Coastguard Worker              !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3452*9880d681SAndroid Build Coastguard Worker              [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))], itins.rr>,
3453*9880d681SAndroid Build Coastguard Worker            Sched<[itins.Sched]>;
3454*9880d681SAndroid Build Coastguard Worker  def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3455*9880d681SAndroid Build Coastguard Worker                !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3456*9880d681SAndroid Build Coastguard Worker                [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))], itins.rm>,
3457*9880d681SAndroid Build Coastguard Worker            Sched<[itins.Sched.Folded]>;
3458*9880d681SAndroid Build Coastguard Worker}
3459*9880d681SAndroid Build Coastguard Worker
3460*9880d681SAndroid Build Coastguard Workermulticlass sse1_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3461*9880d681SAndroid Build Coastguard Worker                          OpndItins itins> {
3462*9880d681SAndroid Build Coastguard Worker  defm SS        :  sse_fp_unop_s<opc, OpcodeStr##ss, FR32, v4f32, f32, f32mem,
3463*9880d681SAndroid Build Coastguard Worker                      ssmem, sse_load_f32,
3464*9880d681SAndroid Build Coastguard Worker                      !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
3465*9880d681SAndroid Build Coastguard Worker                      SSEPackedSingle, itins, UseSSE1, "SS">, XS;
3466*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SS  : avx_fp_unop_s<opc, "v"#OpcodeStr##ss, FR32, v4f32, f32,
3467*9880d681SAndroid Build Coastguard Worker                      f32mem, ssmem, sse_load_f32,
3468*9880d681SAndroid Build Coastguard Worker                      !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
3469*9880d681SAndroid Build Coastguard Worker                      SSEPackedSingle, itins, "SS">, XS, VEX_4V, VEX_LIG;
3470*9880d681SAndroid Build Coastguard Worker}
3471*9880d681SAndroid Build Coastguard Worker
3472*9880d681SAndroid Build Coastguard Workermulticlass sse2_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3473*9880d681SAndroid Build Coastguard Worker                          OpndItins itins> {
3474*9880d681SAndroid Build Coastguard Worker  defm SD         : sse_fp_unop_s<opc, OpcodeStr##sd, FR64, v2f64, f64, f64mem,
3475*9880d681SAndroid Build Coastguard Worker                         sdmem, sse_load_f64,
3476*9880d681SAndroid Build Coastguard Worker                         !cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
3477*9880d681SAndroid Build Coastguard Worker                         OpNode, SSEPackedDouble, itins, UseSSE2, "SD">, XD;
3478*9880d681SAndroid Build Coastguard Worker  defm V#NAME#SD  : avx_fp_unop_s<opc, "v"#OpcodeStr##sd, FR64, v2f64, f64,
3479*9880d681SAndroid Build Coastguard Worker                         f64mem, sdmem, sse_load_f64,
3480*9880d681SAndroid Build Coastguard Worker                         !cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
3481*9880d681SAndroid Build Coastguard Worker                         OpNode, SSEPackedDouble, itins, "SD">,
3482*9880d681SAndroid Build Coastguard Worker                         XD, VEX_4V, VEX_LIG;
3483*9880d681SAndroid Build Coastguard Worker}
3484*9880d681SAndroid Build Coastguard Worker
3485*9880d681SAndroid Build Coastguard Worker// Square root.
3486*9880d681SAndroid Build Coastguard Workerdefm SQRT  : sse1_fp_unop_s<0x51, "sqrt", fsqrt, SSE_SQRTSS>,
3487*9880d681SAndroid Build Coastguard Worker             sse1_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPS, [HasAVX]>,
3488*9880d681SAndroid Build Coastguard Worker             sse2_fp_unop_s<0x51, "sqrt", fsqrt, SSE_SQRTSD>,
3489*9880d681SAndroid Build Coastguard Worker             sse2_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPD>;
3490*9880d681SAndroid Build Coastguard Worker
3491*9880d681SAndroid Build Coastguard Worker// Reciprocal approximations. Note that these typically require refinement
3492*9880d681SAndroid Build Coastguard Worker// in order to obtain suitable precision.
3493*9880d681SAndroid Build Coastguard Workerdefm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, SSE_RSQRTSS>,
3494*9880d681SAndroid Build Coastguard Worker             sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SSE_RSQRTPS, [HasAVX, NoVLX] >;
3495*9880d681SAndroid Build Coastguard Workerdefm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, SSE_RCPS>,
3496*9880d681SAndroid Build Coastguard Worker             sse1_fp_unop_p<0x53, "rcp", X86frcp, SSE_RCPP, [HasAVX, NoVLX]>;
3497*9880d681SAndroid Build Coastguard Worker
3498*9880d681SAndroid Build Coastguard Worker// There is no f64 version of the reciprocal approximation instructions.
3499*9880d681SAndroid Build Coastguard Worker
3500*9880d681SAndroid Build Coastguard Worker// TODO: We should add *scalar* op patterns for these just like we have for
3501*9880d681SAndroid Build Coastguard Worker// the binops above. If the binop and unop patterns could all be unified
3502*9880d681SAndroid Build Coastguard Worker// that would be even better.
3503*9880d681SAndroid Build Coastguard Worker
3504*9880d681SAndroid Build Coastguard Workermulticlass scalar_unary_math_patterns<Intrinsic Intr, string OpcPrefix,
3505*9880d681SAndroid Build Coastguard Worker                                      SDNode Move, ValueType VT,
3506*9880d681SAndroid Build Coastguard Worker                                      Predicate BasePredicate> {
3507*9880d681SAndroid Build Coastguard Worker  let Predicates = [BasePredicate] in {
3508*9880d681SAndroid Build Coastguard Worker    def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
3509*9880d681SAndroid Build Coastguard Worker              (!cast<I>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3510*9880d681SAndroid Build Coastguard Worker  }
3511*9880d681SAndroid Build Coastguard Worker
3512*9880d681SAndroid Build Coastguard Worker  // With SSE 4.1, blendi is preferred to movs*, so match that too.
3513*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE41] in {
3514*9880d681SAndroid Build Coastguard Worker    def : Pat<(VT (X86Blendi VT:$dst, (Intr VT:$src), (i8 1))),
3515*9880d681SAndroid Build Coastguard Worker              (!cast<I>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3516*9880d681SAndroid Build Coastguard Worker  }
3517*9880d681SAndroid Build Coastguard Worker
3518*9880d681SAndroid Build Coastguard Worker  // Repeat for AVX versions of the instructions.
3519*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in {
3520*9880d681SAndroid Build Coastguard Worker    def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
3521*9880d681SAndroid Build Coastguard Worker              (!cast<I>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3522*9880d681SAndroid Build Coastguard Worker
3523*9880d681SAndroid Build Coastguard Worker    def : Pat<(VT (X86Blendi VT:$dst, (Intr VT:$src), (i8 1))),
3524*9880d681SAndroid Build Coastguard Worker              (!cast<I>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3525*9880d681SAndroid Build Coastguard Worker  }
3526*9880d681SAndroid Build Coastguard Worker}
3527*9880d681SAndroid Build Coastguard Worker
3528*9880d681SAndroid Build Coastguard Workerdefm : scalar_unary_math_patterns<int_x86_sse_rcp_ss, "RCPSS", X86Movss,
3529*9880d681SAndroid Build Coastguard Worker                                  v4f32, UseSSE1>;
3530*9880d681SAndroid Build Coastguard Workerdefm : scalar_unary_math_patterns<int_x86_sse_rsqrt_ss, "RSQRTSS", X86Movss,
3531*9880d681SAndroid Build Coastguard Worker                                  v4f32, UseSSE1>;
3532*9880d681SAndroid Build Coastguard Workerdefm : scalar_unary_math_patterns<int_x86_sse_sqrt_ss, "SQRTSS", X86Movss,
3533*9880d681SAndroid Build Coastguard Worker                                  v4f32, UseSSE1>;
3534*9880d681SAndroid Build Coastguard Workerdefm : scalar_unary_math_patterns<int_x86_sse2_sqrt_sd, "SQRTSD", X86Movsd,
3535*9880d681SAndroid Build Coastguard Worker                                  v2f64, UseSSE2>;
3536*9880d681SAndroid Build Coastguard Worker
3537*9880d681SAndroid Build Coastguard Worker
3538*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3539*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Non-temporal stores
3540*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3541*9880d681SAndroid Build Coastguard Worker
3542*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 400 in { // Prefer non-temporal versions
3543*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteStore] in {
3544*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
3545*9880d681SAndroid Build Coastguard Workerdef VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3546*9880d681SAndroid Build Coastguard Worker                     (ins f128mem:$dst, VR128:$src),
3547*9880d681SAndroid Build Coastguard Worker                     "movntps\t{$src, $dst|$dst, $src}",
3548*9880d681SAndroid Build Coastguard Worker                     [(alignednontemporalstore (v4f32 VR128:$src),
3549*9880d681SAndroid Build Coastguard Worker                                               addr:$dst)],
3550*9880d681SAndroid Build Coastguard Worker                                               IIC_SSE_MOVNT>, VEX;
3551*9880d681SAndroid Build Coastguard Workerdef VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3552*9880d681SAndroid Build Coastguard Worker                     (ins f128mem:$dst, VR128:$src),
3553*9880d681SAndroid Build Coastguard Worker                     "movntpd\t{$src, $dst|$dst, $src}",
3554*9880d681SAndroid Build Coastguard Worker                     [(alignednontemporalstore (v2f64 VR128:$src),
3555*9880d681SAndroid Build Coastguard Worker                                               addr:$dst)],
3556*9880d681SAndroid Build Coastguard Worker                                               IIC_SSE_MOVNT>, VEX;
3557*9880d681SAndroid Build Coastguard Worker
3558*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in
3559*9880d681SAndroid Build Coastguard Workerdef VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3560*9880d681SAndroid Build Coastguard Worker                         (ins f128mem:$dst, VR128:$src),
3561*9880d681SAndroid Build Coastguard Worker                         "movntdq\t{$src, $dst|$dst, $src}",
3562*9880d681SAndroid Build Coastguard Worker                         [(alignednontemporalstore (v2i64 VR128:$src),
3563*9880d681SAndroid Build Coastguard Worker                                                   addr:$dst)],
3564*9880d681SAndroid Build Coastguard Worker                                                   IIC_SSE_MOVNT>, VEX;
3565*9880d681SAndroid Build Coastguard Worker
3566*9880d681SAndroid Build Coastguard Workerdef VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3567*9880d681SAndroid Build Coastguard Worker                     (ins f256mem:$dst, VR256:$src),
3568*9880d681SAndroid Build Coastguard Worker                     "movntps\t{$src, $dst|$dst, $src}",
3569*9880d681SAndroid Build Coastguard Worker                     [(alignednontemporalstore (v8f32 VR256:$src),
3570*9880d681SAndroid Build Coastguard Worker                                               addr:$dst)],
3571*9880d681SAndroid Build Coastguard Worker                                               IIC_SSE_MOVNT>, VEX, VEX_L;
3572*9880d681SAndroid Build Coastguard Workerdef VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3573*9880d681SAndroid Build Coastguard Worker                     (ins f256mem:$dst, VR256:$src),
3574*9880d681SAndroid Build Coastguard Worker                     "movntpd\t{$src, $dst|$dst, $src}",
3575*9880d681SAndroid Build Coastguard Worker                     [(alignednontemporalstore (v4f64 VR256:$src),
3576*9880d681SAndroid Build Coastguard Worker                                               addr:$dst)],
3577*9880d681SAndroid Build Coastguard Worker                                               IIC_SSE_MOVNT>, VEX, VEX_L;
3578*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in
3579*9880d681SAndroid Build Coastguard Workerdef VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3580*9880d681SAndroid Build Coastguard Worker                    (ins f256mem:$dst, VR256:$src),
3581*9880d681SAndroid Build Coastguard Worker                    "movntdq\t{$src, $dst|$dst, $src}",
3582*9880d681SAndroid Build Coastguard Worker                    [(alignednontemporalstore (v4i64 VR256:$src),
3583*9880d681SAndroid Build Coastguard Worker                                              addr:$dst)],
3584*9880d681SAndroid Build Coastguard Worker                                              IIC_SSE_MOVNT>, VEX, VEX_L;
3585*9880d681SAndroid Build Coastguard Worker}
3586*9880d681SAndroid Build Coastguard Worker
3587*9880d681SAndroid Build Coastguard Workerdef MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3588*9880d681SAndroid Build Coastguard Worker                    "movntps\t{$src, $dst|$dst, $src}",
3589*9880d681SAndroid Build Coastguard Worker                    [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)],
3590*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOVNT>;
3591*9880d681SAndroid Build Coastguard Workerdef MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3592*9880d681SAndroid Build Coastguard Worker                    "movntpd\t{$src, $dst|$dst, $src}",
3593*9880d681SAndroid Build Coastguard Worker                    [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)],
3594*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOVNT>;
3595*9880d681SAndroid Build Coastguard Worker
3596*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in
3597*9880d681SAndroid Build Coastguard Workerdef MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3598*9880d681SAndroid Build Coastguard Worker                    "movntdq\t{$src, $dst|$dst, $src}",
3599*9880d681SAndroid Build Coastguard Worker                    [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)],
3600*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOVNT>;
3601*9880d681SAndroid Build Coastguard Worker
3602*9880d681SAndroid Build Coastguard Worker// There is no AVX form for instructions below this point
3603*9880d681SAndroid Build Coastguard Workerdef MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3604*9880d681SAndroid Build Coastguard Worker                 "movnti{l}\t{$src, $dst|$dst, $src}",
3605*9880d681SAndroid Build Coastguard Worker                 [(nontemporalstore (i32 GR32:$src), addr:$dst)],
3606*9880d681SAndroid Build Coastguard Worker                 IIC_SSE_MOVNT>,
3607*9880d681SAndroid Build Coastguard Worker               PS, Requires<[HasSSE2]>;
3608*9880d681SAndroid Build Coastguard Workerdef MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3609*9880d681SAndroid Build Coastguard Worker                     "movnti{q}\t{$src, $dst|$dst, $src}",
3610*9880d681SAndroid Build Coastguard Worker                     [(nontemporalstore (i64 GR64:$src), addr:$dst)],
3611*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_MOVNT>,
3612*9880d681SAndroid Build Coastguard Worker                  PS, Requires<[HasSSE2]>;
3613*9880d681SAndroid Build Coastguard Worker} // SchedRW = [WriteStore]
3614*9880d681SAndroid Build Coastguard Worker
3615*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
3616*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v8i32 VR256:$src), addr:$dst),
3617*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3618*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v16i16 VR256:$src), addr:$dst),
3619*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3620*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v32i8 VR256:$src), addr:$dst),
3621*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3622*9880d681SAndroid Build Coastguard Worker
3623*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3624*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQmr addr:$dst, VR128:$src)>;
3625*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3626*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQmr addr:$dst, VR128:$src)>;
3627*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3628*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQmr addr:$dst, VR128:$src)>;
3629*9880d681SAndroid Build Coastguard Worker}
3630*9880d681SAndroid Build Coastguard Worker
3631*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
3632*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3633*9880d681SAndroid Build Coastguard Worker            (MOVNTDQmr addr:$dst, VR128:$src)>;
3634*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3635*9880d681SAndroid Build Coastguard Worker            (MOVNTDQmr addr:$dst, VR128:$src)>;
3636*9880d681SAndroid Build Coastguard Worker  def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3637*9880d681SAndroid Build Coastguard Worker            (MOVNTDQmr addr:$dst, VR128:$src)>;
3638*9880d681SAndroid Build Coastguard Worker}
3639*9880d681SAndroid Build Coastguard Worker
3640*9880d681SAndroid Build Coastguard Worker} // AddedComplexity
3641*9880d681SAndroid Build Coastguard Worker
3642*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3643*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Prefetch and memory fence
3644*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3645*9880d681SAndroid Build Coastguard Worker
3646*9880d681SAndroid Build Coastguard Worker// Prefetch intrinsic.
3647*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasSSE1], SchedRW = [WriteLoad] in {
3648*9880d681SAndroid Build Coastguard Workerdef PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3649*9880d681SAndroid Build Coastguard Worker    "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))],
3650*9880d681SAndroid Build Coastguard Worker    IIC_SSE_PREFETCH>, TB;
3651*9880d681SAndroid Build Coastguard Workerdef PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3652*9880d681SAndroid Build Coastguard Worker    "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))],
3653*9880d681SAndroid Build Coastguard Worker    IIC_SSE_PREFETCH>, TB;
3654*9880d681SAndroid Build Coastguard Workerdef PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3655*9880d681SAndroid Build Coastguard Worker    "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))],
3656*9880d681SAndroid Build Coastguard Worker    IIC_SSE_PREFETCH>, TB;
3657*9880d681SAndroid Build Coastguard Workerdef PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3658*9880d681SAndroid Build Coastguard Worker    "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))],
3659*9880d681SAndroid Build Coastguard Worker    IIC_SSE_PREFETCH>, TB;
3660*9880d681SAndroid Build Coastguard Worker}
3661*9880d681SAndroid Build Coastguard Worker
3662*9880d681SAndroid Build Coastguard Worker// FIXME: How should flush instruction be modeled?
3663*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteLoad] in {
3664*9880d681SAndroid Build Coastguard Worker// Flush cache
3665*9880d681SAndroid Build Coastguard Workerdef CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3666*9880d681SAndroid Build Coastguard Worker               "clflush\t$src", [(int_x86_sse2_clflush addr:$src)],
3667*9880d681SAndroid Build Coastguard Worker               IIC_SSE_PREFETCH>, PS, Requires<[HasSSE2]>;
3668*9880d681SAndroid Build Coastguard Worker}
3669*9880d681SAndroid Build Coastguard Worker
3670*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteNop] in {
3671*9880d681SAndroid Build Coastguard Worker// Pause. This "instruction" is encoded as "rep; nop", so even though it
3672*9880d681SAndroid Build Coastguard Worker// was introduced with SSE2, it's backward compatible.
3673*9880d681SAndroid Build Coastguard Workerdef PAUSE : I<0x90, RawFrm, (outs), (ins),
3674*9880d681SAndroid Build Coastguard Worker              "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>,
3675*9880d681SAndroid Build Coastguard Worker              OBXS, Requires<[HasSSE2]>;
3676*9880d681SAndroid Build Coastguard Worker}
3677*9880d681SAndroid Build Coastguard Worker
3678*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteFence] in {
3679*9880d681SAndroid Build Coastguard Worker// Load, store, and memory fence
3680*9880d681SAndroid Build Coastguard Worker// TODO: As with mfence, we may want to ease the availablity of sfence/lfence
3681*9880d681SAndroid Build Coastguard Worker// to include any 64-bit target.
3682*9880d681SAndroid Build Coastguard Workerdef SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3683*9880d681SAndroid Build Coastguard Worker               "sfence", [(int_x86_sse_sfence)], IIC_SSE_SFENCE>,
3684*9880d681SAndroid Build Coastguard Worker               PS, Requires<[HasSSE1]>;
3685*9880d681SAndroid Build Coastguard Workerdef LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3686*9880d681SAndroid Build Coastguard Worker               "lfence", [(int_x86_sse2_lfence)], IIC_SSE_LFENCE>,
3687*9880d681SAndroid Build Coastguard Worker               TB, Requires<[HasSSE2]>;
3688*9880d681SAndroid Build Coastguard Workerdef MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3689*9880d681SAndroid Build Coastguard Worker               "mfence", [(int_x86_sse2_mfence)], IIC_SSE_MFENCE>,
3690*9880d681SAndroid Build Coastguard Worker               TB, Requires<[HasMFence]>;
3691*9880d681SAndroid Build Coastguard Worker} // SchedRW
3692*9880d681SAndroid Build Coastguard Worker
3693*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86MFence), (MFENCE)>;
3694*9880d681SAndroid Build Coastguard Worker
3695*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3696*9880d681SAndroid Build Coastguard Worker// SSE 1 & 2 - Load/Store XCSR register
3697*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3698*9880d681SAndroid Build Coastguard Worker
3699*9880d681SAndroid Build Coastguard Workerdef VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3700*9880d681SAndroid Build Coastguard Worker                  "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3701*9880d681SAndroid Build Coastguard Worker                  IIC_SSE_LDMXCSR>, VEX, Sched<[WriteLoad]>;
3702*9880d681SAndroid Build Coastguard Workerdef VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3703*9880d681SAndroid Build Coastguard Worker                  "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3704*9880d681SAndroid Build Coastguard Worker                  IIC_SSE_STMXCSR>, VEX, Sched<[WriteStore]>;
3705*9880d681SAndroid Build Coastguard Worker
3706*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE1] in {
3707*9880d681SAndroid Build Coastguard Workerdef LDMXCSR : I<0xAE, MRM2m, (outs), (ins i32mem:$src),
3708*9880d681SAndroid Build Coastguard Worker                "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3709*9880d681SAndroid Build Coastguard Worker                IIC_SSE_LDMXCSR>, TB, Sched<[WriteLoad]>;
3710*9880d681SAndroid Build Coastguard Workerdef STMXCSR : I<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3711*9880d681SAndroid Build Coastguard Worker                "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3712*9880d681SAndroid Build Coastguard Worker                IIC_SSE_STMXCSR>, TB, Sched<[WriteStore]>;
3713*9880d681SAndroid Build Coastguard Worker}
3714*9880d681SAndroid Build Coastguard Worker
3715*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
3716*9880d681SAndroid Build Coastguard Worker// SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3717*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
3718*9880d681SAndroid Build Coastguard Worker
3719*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { // SSE integer instructions
3720*9880d681SAndroid Build Coastguard Worker
3721*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, SchedRW = [WriteMove] in {
3722*9880d681SAndroid Build Coastguard Workerdef VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3723*9880d681SAndroid Build Coastguard Worker                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3724*9880d681SAndroid Build Coastguard Worker                    VEX;
3725*9880d681SAndroid Build Coastguard Workerdef VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3726*9880d681SAndroid Build Coastguard Worker                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3727*9880d681SAndroid Build Coastguard Worker                    VEX, VEX_L;
3728*9880d681SAndroid Build Coastguard Workerdef VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3729*9880d681SAndroid Build Coastguard Worker                    "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3730*9880d681SAndroid Build Coastguard Worker                    VEX;
3731*9880d681SAndroid Build Coastguard Workerdef VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3732*9880d681SAndroid Build Coastguard Worker                    "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3733*9880d681SAndroid Build Coastguard Worker                    VEX, VEX_L;
3734*9880d681SAndroid Build Coastguard Worker}
3735*9880d681SAndroid Build Coastguard Worker
3736*9880d681SAndroid Build Coastguard Worker// For Disassembler
3737*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
3738*9880d681SAndroid Build Coastguard Worker    SchedRW = [WriteMove] in {
3739*9880d681SAndroid Build Coastguard Workerdef VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3740*9880d681SAndroid Build Coastguard Worker                        "movdqa\t{$src, $dst|$dst, $src}", [],
3741*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVA_P_RR>,
3742*9880d681SAndroid Build Coastguard Worker                        VEX;
3743*9880d681SAndroid Build Coastguard Workerdef VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3744*9880d681SAndroid Build Coastguard Worker                        "movdqa\t{$src, $dst|$dst, $src}", [],
3745*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
3746*9880d681SAndroid Build Coastguard Workerdef VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3747*9880d681SAndroid Build Coastguard Worker                        "movdqu\t{$src, $dst|$dst, $src}", [],
3748*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVU_P_RR>,
3749*9880d681SAndroid Build Coastguard Worker                        VEX;
3750*9880d681SAndroid Build Coastguard Workerdef VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3751*9880d681SAndroid Build Coastguard Worker                        "movdqu\t{$src, $dst|$dst, $src}", [],
3752*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
3753*9880d681SAndroid Build Coastguard Worker}
3754*9880d681SAndroid Build Coastguard Worker
3755*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3756*9880d681SAndroid Build Coastguard Worker    hasSideEffects = 0, SchedRW = [WriteLoad] in {
3757*9880d681SAndroid Build Coastguard Workerdef VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3758*9880d681SAndroid Build Coastguard Worker                   "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3759*9880d681SAndroid Build Coastguard Worker                   VEX;
3760*9880d681SAndroid Build Coastguard Workerdef VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3761*9880d681SAndroid Build Coastguard Worker                   "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3762*9880d681SAndroid Build Coastguard Worker                   VEX, VEX_L;
3763*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
3764*9880d681SAndroid Build Coastguard Worker  def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3765*9880d681SAndroid Build Coastguard Worker                    "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3766*9880d681SAndroid Build Coastguard Worker                    XS, VEX;
3767*9880d681SAndroid Build Coastguard Worker  def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3768*9880d681SAndroid Build Coastguard Worker                    "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3769*9880d681SAndroid Build Coastguard Worker                    XS, VEX, VEX_L;
3770*9880d681SAndroid Build Coastguard Worker}
3771*9880d681SAndroid Build Coastguard Worker}
3772*9880d681SAndroid Build Coastguard Worker
3773*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
3774*9880d681SAndroid Build Coastguard Workerdef VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3775*9880d681SAndroid Build Coastguard Worker                     (ins i128mem:$dst, VR128:$src),
3776*9880d681SAndroid Build Coastguard Worker                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3777*9880d681SAndroid Build Coastguard Worker                     VEX;
3778*9880d681SAndroid Build Coastguard Workerdef VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3779*9880d681SAndroid Build Coastguard Worker                     (ins i256mem:$dst, VR256:$src),
3780*9880d681SAndroid Build Coastguard Worker                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3781*9880d681SAndroid Build Coastguard Worker                     VEX, VEX_L;
3782*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
3783*9880d681SAndroid Build Coastguard Workerdef VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3784*9880d681SAndroid Build Coastguard Worker                  "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3785*9880d681SAndroid Build Coastguard Worker                  XS, VEX;
3786*9880d681SAndroid Build Coastguard Workerdef VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3787*9880d681SAndroid Build Coastguard Worker                  "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3788*9880d681SAndroid Build Coastguard Worker                  XS, VEX, VEX_L;
3789*9880d681SAndroid Build Coastguard Worker}
3790*9880d681SAndroid Build Coastguard Worker}
3791*9880d681SAndroid Build Coastguard Worker
3792*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteMove] in {
3793*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in
3794*9880d681SAndroid Build Coastguard Workerdef MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3795*9880d681SAndroid Build Coastguard Worker                   "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>;
3796*9880d681SAndroid Build Coastguard Worker
3797*9880d681SAndroid Build Coastguard Workerdef MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3798*9880d681SAndroid Build Coastguard Worker                   "movdqu\t{$src, $dst|$dst, $src}",
3799*9880d681SAndroid Build Coastguard Worker                   [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3800*9880d681SAndroid Build Coastguard Worker
3801*9880d681SAndroid Build Coastguard Worker// For Disassembler
3802*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3803*9880d681SAndroid Build Coastguard Workerdef MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3804*9880d681SAndroid Build Coastguard Worker                       "movdqa\t{$src, $dst|$dst, $src}", [],
3805*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_MOVA_P_RR>;
3806*9880d681SAndroid Build Coastguard Worker
3807*9880d681SAndroid Build Coastguard Workerdef MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3808*9880d681SAndroid Build Coastguard Worker                       "movdqu\t{$src, $dst|$dst, $src}",
3809*9880d681SAndroid Build Coastguard Worker                       [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3810*9880d681SAndroid Build Coastguard Worker}
3811*9880d681SAndroid Build Coastguard Worker} // SchedRW
3812*9880d681SAndroid Build Coastguard Worker
3813*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3814*9880d681SAndroid Build Coastguard Worker    hasSideEffects = 0, SchedRW = [WriteLoad] in {
3815*9880d681SAndroid Build Coastguard Workerdef MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3816*9880d681SAndroid Build Coastguard Worker                   "movdqa\t{$src, $dst|$dst, $src}",
3817*9880d681SAndroid Build Coastguard Worker                   [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/],
3818*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_RM>;
3819*9880d681SAndroid Build Coastguard Workerdef MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3820*9880d681SAndroid Build Coastguard Worker                   "movdqu\t{$src, $dst|$dst, $src}",
3821*9880d681SAndroid Build Coastguard Worker                   [/*(set VR128:$dst, (loadv2i64 addr:$src))*/],
3822*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_RM>,
3823*9880d681SAndroid Build Coastguard Worker                 XS, Requires<[UseSSE2]>;
3824*9880d681SAndroid Build Coastguard Worker}
3825*9880d681SAndroid Build Coastguard Worker
3826*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
3827*9880d681SAndroid Build Coastguard Workerdef MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3828*9880d681SAndroid Build Coastguard Worker                   "movdqa\t{$src, $dst|$dst, $src}",
3829*9880d681SAndroid Build Coastguard Worker                   [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/],
3830*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVA_P_MR>;
3831*9880d681SAndroid Build Coastguard Workerdef MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3832*9880d681SAndroid Build Coastguard Worker                   "movdqu\t{$src, $dst|$dst, $src}",
3833*9880d681SAndroid Build Coastguard Worker                   [/*(store (v2i64 VR128:$src), addr:$dst)*/],
3834*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_MOVU_P_MR>,
3835*9880d681SAndroid Build Coastguard Worker                 XS, Requires<[UseSSE2]>;
3836*9880d681SAndroid Build Coastguard Worker}
3837*9880d681SAndroid Build Coastguard Worker
3838*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
3839*9880d681SAndroid Build Coastguard Worker
3840*9880d681SAndroid Build Coastguard Worker// Aliases to help the assembler pick two byte VEX encodings by swapping the
3841*9880d681SAndroid Build Coastguard Worker// operands relative to the normal instructions to use VEX.R instead of VEX.B.
3842*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3843*9880d681SAndroid Build Coastguard Worker                (VMOVDQArr_REV VR128L:$dst, VR128H:$src), 0>;
3844*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3845*9880d681SAndroid Build Coastguard Worker                (VMOVDQAYrr_REV VR256L:$dst, VR256H:$src), 0>;
3846*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3847*9880d681SAndroid Build Coastguard Worker                (VMOVDQUrr_REV VR128L:$dst, VR128H:$src), 0>;
3848*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3849*9880d681SAndroid Build Coastguard Worker                (VMOVDQUYrr_REV VR256L:$dst, VR256H:$src), 0>;
3850*9880d681SAndroid Build Coastguard Worker
3851*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
3852*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Arithmetic Instructions
3853*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
3854*9880d681SAndroid Build Coastguard Worker
3855*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecIMul in
3856*9880d681SAndroid Build Coastguard Workerdef SSE_PMADD : OpndItins<
3857*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PMADD, IIC_SSE_PMADD
3858*9880d681SAndroid Build Coastguard Worker>;
3859*9880d681SAndroid Build Coastguard Worker
3860*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in { // SSE integer instructions
3861*9880d681SAndroid Build Coastguard Worker
3862*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3863*9880d681SAndroid Build Coastguard Worker                            RegisterClass RC, PatFrag memop_frag,
3864*9880d681SAndroid Build Coastguard Worker                            X86MemOperand x86memop,
3865*9880d681SAndroid Build Coastguard Worker                            OpndItins itins,
3866*9880d681SAndroid Build Coastguard Worker                            bit IsCommutable = 0,
3867*9880d681SAndroid Build Coastguard Worker                            bit Is2Addr = 1> {
3868*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsCommutable in
3869*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3870*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
3871*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3872*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3873*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3874*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (IntId RC:$src1, RC:$src2))], itins.rr>,
3875*9880d681SAndroid Build Coastguard Worker      Sched<[itins.Sched]>;
3876*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3877*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
3878*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3879*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3880*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3881*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))],
3882*9880d681SAndroid Build Coastguard Worker       itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3883*9880d681SAndroid Build Coastguard Worker}
3884*9880d681SAndroid Build Coastguard Worker
3885*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_all_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
3886*9880d681SAndroid Build Coastguard Worker                             Intrinsic IntId256, OpndItins itins,
3887*9880d681SAndroid Build Coastguard Worker                             bit IsCommutable = 0> {
3888*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in
3889*9880d681SAndroid Build Coastguard Worker  defm V#NAME : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId128,
3890*9880d681SAndroid Build Coastguard Worker                                 VR128, loadv2i64, i128mem, itins,
3891*9880d681SAndroid Build Coastguard Worker                                 IsCommutable, 0>, VEX_4V;
3892*9880d681SAndroid Build Coastguard Worker
3893*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
3894*9880d681SAndroid Build Coastguard Worker  defm NAME : PDI_binop_rm_int<opc, OpcodeStr, IntId128, VR128, memopv2i64,
3895*9880d681SAndroid Build Coastguard Worker                               i128mem, itins, IsCommutable, 1>;
3896*9880d681SAndroid Build Coastguard Worker
3897*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in
3898*9880d681SAndroid Build Coastguard Worker  defm V#NAME#Y : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId256,
3899*9880d681SAndroid Build Coastguard Worker                                   VR256, loadv4i64, i256mem, itins,
3900*9880d681SAndroid Build Coastguard Worker                                   IsCommutable, 0>, VEX_4V, VEX_L;
3901*9880d681SAndroid Build Coastguard Worker}
3902*9880d681SAndroid Build Coastguard Worker
3903*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3904*9880d681SAndroid Build Coastguard Worker                         string OpcodeStr, SDNode OpNode,
3905*9880d681SAndroid Build Coastguard Worker                         SDNode OpNode2, RegisterClass RC,
3906*9880d681SAndroid Build Coastguard Worker                         ValueType DstVT, ValueType SrcVT,
3907*9880d681SAndroid Build Coastguard Worker                         PatFrag ld_frag, ShiftOpndItins itins,
3908*9880d681SAndroid Build Coastguard Worker                         bit Is2Addr = 1> {
3909*9880d681SAndroid Build Coastguard Worker  // src2 is always 128-bit
3910*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3911*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, VR128:$src2),
3912*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3913*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3914*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3915*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))],
3916*9880d681SAndroid Build Coastguard Worker        itins.rr>, Sched<[WriteVecShift]>;
3917*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3918*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, i128mem:$src2),
3919*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3920*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3921*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3922*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode RC:$src1,
3923*9880d681SAndroid Build Coastguard Worker                       (SrcVT (bitconvert (ld_frag addr:$src2))))))], itins.rm>,
3924*9880d681SAndroid Build Coastguard Worker      Sched<[WriteVecShiftLd, ReadAfterLd]>;
3925*9880d681SAndroid Build Coastguard Worker  def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3926*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, u8imm:$src2),
3927*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3928*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3929*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3930*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))], itins.ri>,
3931*9880d681SAndroid Build Coastguard Worker       Sched<[WriteVecShift]>;
3932*9880d681SAndroid Build Coastguard Worker}
3933*9880d681SAndroid Build Coastguard Worker
3934*9880d681SAndroid Build Coastguard Worker/// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
3935*9880d681SAndroid Build Coastguard Workermulticlass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3936*9880d681SAndroid Build Coastguard Worker                         ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3937*9880d681SAndroid Build Coastguard Worker                         PatFrag memop_frag, X86MemOperand x86memop,
3938*9880d681SAndroid Build Coastguard Worker                         OpndItins itins,
3939*9880d681SAndroid Build Coastguard Worker                         bit IsCommutable = 0, bit Is2Addr = 1> {
3940*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsCommutable in
3941*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3942*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
3943*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3944*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3945*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3946*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
3947*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
3948*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3949*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
3950*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
3951*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3952*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3953*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
3954*9880d681SAndroid Build Coastguard Worker                                     (bitconvert (memop_frag addr:$src2)))))]>,
3955*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3956*9880d681SAndroid Build Coastguard Worker}
3957*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
3958*9880d681SAndroid Build Coastguard Worker
3959*9880d681SAndroid Build Coastguard Workerdefm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
3960*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3961*9880d681SAndroid Build Coastguard Workerdefm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
3962*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3963*9880d681SAndroid Build Coastguard Workerdefm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
3964*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX>;
3965*9880d681SAndroid Build Coastguard Workerdefm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
3966*9880d681SAndroid Build Coastguard Worker                             SSE_INTALUQ_ITINS_P, 1, NoVLX>;
3967*9880d681SAndroid Build Coastguard Workerdefm PADDSB  : PDI_binop_all<0xEC, "paddsb", X86adds, v16i8, v32i8,
3968*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3969*9880d681SAndroid Build Coastguard Workerdefm PADDSW  : PDI_binop_all<0xED, "paddsw", X86adds, v8i16, v16i16,
3970*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3971*9880d681SAndroid Build Coastguard Workerdefm PADDUSB : PDI_binop_all<0xDC, "paddusb", X86addus, v16i8, v32i8,
3972*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3973*9880d681SAndroid Build Coastguard Workerdefm PADDUSW : PDI_binop_all<0xDD, "paddusw", X86addus, v8i16, v16i16,
3974*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3975*9880d681SAndroid Build Coastguard Workerdefm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
3976*9880d681SAndroid Build Coastguard Worker                             SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3977*9880d681SAndroid Build Coastguard Workerdefm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16,
3978*9880d681SAndroid Build Coastguard Worker                             SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3979*9880d681SAndroid Build Coastguard Workerdefm PMULHW  : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16,
3980*9880d681SAndroid Build Coastguard Worker                             SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3981*9880d681SAndroid Build Coastguard Workerdefm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
3982*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3983*9880d681SAndroid Build Coastguard Workerdefm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
3984*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3985*9880d681SAndroid Build Coastguard Workerdefm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
3986*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX>;
3987*9880d681SAndroid Build Coastguard Workerdefm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
3988*9880d681SAndroid Build Coastguard Worker                             SSE_INTALUQ_ITINS_P, 0, NoVLX>;
3989*9880d681SAndroid Build Coastguard Workerdefm PSUBSB  : PDI_binop_all<0xE8, "psubsb", X86subs, v16i8, v32i8,
3990*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3991*9880d681SAndroid Build Coastguard Workerdefm PSUBSW  : PDI_binop_all<0xE9, "psubsw", X86subs, v8i16, v16i16,
3992*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3993*9880d681SAndroid Build Coastguard Workerdefm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
3994*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3995*9880d681SAndroid Build Coastguard Workerdefm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
3996*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3997*9880d681SAndroid Build Coastguard Workerdefm PMINUB  : PDI_binop_all<0xDA, "pminub", umin, v16i8, v32i8,
3998*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3999*9880d681SAndroid Build Coastguard Workerdefm PMINSW  : PDI_binop_all<0xEA, "pminsw", smin, v8i16, v16i16,
4000*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4001*9880d681SAndroid Build Coastguard Workerdefm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", umax, v16i8, v32i8,
4002*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4003*9880d681SAndroid Build Coastguard Workerdefm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", smax, v8i16, v16i16,
4004*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4005*9880d681SAndroid Build Coastguard Workerdefm PAVGB   : PDI_binop_all<0xE0, "pavgb", X86avg, v16i8, v32i8,
4006*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4007*9880d681SAndroid Build Coastguard Workerdefm PAVGW   : PDI_binop_all<0xE3, "pavgw", X86avg, v8i16, v16i16,
4008*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4009*9880d681SAndroid Build Coastguard Worker
4010*9880d681SAndroid Build Coastguard Worker// Intrinsic forms
4011*9880d681SAndroid Build Coastguard Workerdefm PMADDWD : PDI_binop_all_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
4012*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx2_pmadd_wd, SSE_PMADD, 1>;
4013*9880d681SAndroid Build Coastguard Worker
4014*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in
4015*9880d681SAndroid Build Coastguard Workerdefm VPSADBW : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v2i64, v16i8, VR128,
4016*9880d681SAndroid Build Coastguard Worker                             loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 1, 0>,
4017*9880d681SAndroid Build Coastguard Worker                             VEX_4V;
4018*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
4019*9880d681SAndroid Build Coastguard Workerdefm VPSADBWY : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v4i64, v32i8, VR256,
4020*9880d681SAndroid Build Coastguard Worker                             loadv4i64, i256mem, SSE_INTMUL_ITINS_P, 1, 0>,
4021*9880d681SAndroid Build Coastguard Worker                             VEX_4V, VEX_L;
4022*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
4023*9880d681SAndroid Build Coastguard Workerdefm PSADBW : PDI_binop_rm2<0xF6, "psadbw", X86psadbw, v2i64, v16i8, VR128,
4024*9880d681SAndroid Build Coastguard Worker                            memopv2i64, i128mem, SSE_INTALU_ITINS_P, 1>;
4025*9880d681SAndroid Build Coastguard Worker
4026*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in
4027*9880d681SAndroid Build Coastguard Workerdefm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
4028*9880d681SAndroid Build Coastguard Worker                              loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 1, 0>,
4029*9880d681SAndroid Build Coastguard Worker                              VEX_4V;
4030*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in
4031*9880d681SAndroid Build Coastguard Workerdefm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
4032*9880d681SAndroid Build Coastguard Worker                               VR256, loadv4i64, i256mem,
4033*9880d681SAndroid Build Coastguard Worker                               SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
4034*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
4035*9880d681SAndroid Build Coastguard Workerdefm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
4036*9880d681SAndroid Build Coastguard Worker                             memopv2i64, i128mem, SSE_INTMUL_ITINS_P, 1>;
4037*9880d681SAndroid Build Coastguard Worker
4038*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4039*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Logical Instructions
4040*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4041*9880d681SAndroid Build Coastguard Worker
4042*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
4043*9880d681SAndroid Build Coastguard Workerdefm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4044*9880d681SAndroid Build Coastguard Worker                            VR128, v4i32, v4i32, loadv2i64,
4045*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4046*9880d681SAndroid Build Coastguard Workerdefm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4047*9880d681SAndroid Build Coastguard Worker                            VR128, v2i64, v2i64, loadv2i64,
4048*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4049*9880d681SAndroid Build Coastguard Worker
4050*9880d681SAndroid Build Coastguard Workerdefm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4051*9880d681SAndroid Build Coastguard Worker                            VR128, v4i32, v4i32, loadv2i64,
4052*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4053*9880d681SAndroid Build Coastguard Workerdefm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4054*9880d681SAndroid Build Coastguard Worker                            VR128, v2i64, v2i64, loadv2i64,
4055*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4056*9880d681SAndroid Build Coastguard Worker
4057*9880d681SAndroid Build Coastguard Workerdefm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4058*9880d681SAndroid Build Coastguard Worker                            VR128, v4i32, v4i32, loadv2i64,
4059*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4060*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX, NoVLX]
4061*9880d681SAndroid Build Coastguard Worker
4062*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4063*9880d681SAndroid Build Coastguard Workerdefm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4064*9880d681SAndroid Build Coastguard Worker                            VR128, v8i16, v8i16, loadv2i64,
4065*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4066*9880d681SAndroid Build Coastguard Workerdefm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4067*9880d681SAndroid Build Coastguard Worker                            VR128, v8i16, v8i16, loadv2i64,
4068*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4069*9880d681SAndroid Build Coastguard Workerdefm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4070*9880d681SAndroid Build Coastguard Worker                            VR128, v8i16, v8i16, loadv2i64,
4071*9880d681SAndroid Build Coastguard Worker                            SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4072*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX, NoVLX_Or_NoBWI]
4073*9880d681SAndroid Build Coastguard Worker
4074*9880d681SAndroid Build Coastguard Worker
4075*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] ,
4076*9880d681SAndroid Build Coastguard Worker                                    Predicates = [HasAVX, NoVLX_Or_NoBWI]in {
4077*9880d681SAndroid Build Coastguard Worker  // 128-bit logical shifts.
4078*9880d681SAndroid Build Coastguard Worker  def VPSLLDQri : PDIi8<0x73, MRM7r,
4079*9880d681SAndroid Build Coastguard Worker                    (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4080*9880d681SAndroid Build Coastguard Worker                    "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4081*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
4082*9880d681SAndroid Build Coastguard Worker                      (v16i8 (X86vshldq VR128:$src1, (i8 imm:$src2))))]>,
4083*9880d681SAndroid Build Coastguard Worker                    VEX_4V;
4084*9880d681SAndroid Build Coastguard Worker  def VPSRLDQri : PDIi8<0x73, MRM3r,
4085*9880d681SAndroid Build Coastguard Worker                    (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4086*9880d681SAndroid Build Coastguard Worker                    "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4087*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
4088*9880d681SAndroid Build Coastguard Worker                      (v16i8 (X86vshrdq VR128:$src1, (i8 imm:$src2))))]>,
4089*9880d681SAndroid Build Coastguard Worker                    VEX_4V;
4090*9880d681SAndroid Build Coastguard Worker  // PSRADQri doesn't exist in SSE[1-3].
4091*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX, NoVLX_Or_NoBWI]
4092*9880d681SAndroid Build Coastguard Worker
4093*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
4094*9880d681SAndroid Build Coastguard Workerdefm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4095*9880d681SAndroid Build Coastguard Worker                             VR256, v8i32, v4i32, loadv2i64,
4096*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4097*9880d681SAndroid Build Coastguard Workerdefm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4098*9880d681SAndroid Build Coastguard Worker                             VR256, v4i64, v2i64, loadv2i64,
4099*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4100*9880d681SAndroid Build Coastguard Worker
4101*9880d681SAndroid Build Coastguard Workerdefm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4102*9880d681SAndroid Build Coastguard Worker                             VR256, v8i32, v4i32, loadv2i64,
4103*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4104*9880d681SAndroid Build Coastguard Workerdefm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4105*9880d681SAndroid Build Coastguard Worker                             VR256, v4i64, v2i64, loadv2i64,
4106*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4107*9880d681SAndroid Build Coastguard Worker
4108*9880d681SAndroid Build Coastguard Workerdefm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4109*9880d681SAndroid Build Coastguard Worker                             VR256, v8i32, v4i32, loadv2i64,
4110*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4111*9880d681SAndroid Build Coastguard Worker}// Predicates = [HasAVX2, NoVLX]
4112*9880d681SAndroid Build Coastguard Worker
4113*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4114*9880d681SAndroid Build Coastguard Workerdefm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4115*9880d681SAndroid Build Coastguard Worker                             VR256, v16i16, v8i16, loadv2i64,
4116*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4117*9880d681SAndroid Build Coastguard Workerdefm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4118*9880d681SAndroid Build Coastguard Worker                             VR256, v16i16, v8i16, loadv2i64,
4119*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4120*9880d681SAndroid Build Coastguard Workerdefm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4121*9880d681SAndroid Build Coastguard Worker                             VR256, v16i16, v8i16, loadv2i64,
4122*9880d681SAndroid Build Coastguard Worker                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4123*9880d681SAndroid Build Coastguard Worker}// Predicates = [HasAVX2, NoVLX_Or_NoBWI]
4124*9880d681SAndroid Build Coastguard Worker
4125*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift], hasSideEffects = 0 ,
4126*9880d681SAndroid Build Coastguard Worker                                    Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4127*9880d681SAndroid Build Coastguard Worker  // 256-bit logical shifts.
4128*9880d681SAndroid Build Coastguard Worker  def VPSLLDQYri : PDIi8<0x73, MRM7r,
4129*9880d681SAndroid Build Coastguard Worker                    (outs VR256:$dst), (ins VR256:$src1, u8imm:$src2),
4130*9880d681SAndroid Build Coastguard Worker                    "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4131*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst,
4132*9880d681SAndroid Build Coastguard Worker                      (v32i8 (X86vshldq VR256:$src1, (i8 imm:$src2))))]>,
4133*9880d681SAndroid Build Coastguard Worker                    VEX_4V, VEX_L;
4134*9880d681SAndroid Build Coastguard Worker  def VPSRLDQYri : PDIi8<0x73, MRM3r,
4135*9880d681SAndroid Build Coastguard Worker                    (outs VR256:$dst), (ins VR256:$src1, u8imm:$src2),
4136*9880d681SAndroid Build Coastguard Worker                    "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4137*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst,
4138*9880d681SAndroid Build Coastguard Worker                      (v32i8 (X86vshrdq VR256:$src1, (i8 imm:$src2))))]>,
4139*9880d681SAndroid Build Coastguard Worker                    VEX_4V, VEX_L;
4140*9880d681SAndroid Build Coastguard Worker  // PSRADQYri doesn't exist in SSE[1-3].
4141*9880d681SAndroid Build Coastguard Worker} // Predicates = [HasAVX2, NoVLX_Or_NoBWI]
4142*9880d681SAndroid Build Coastguard Worker
4143*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
4144*9880d681SAndroid Build Coastguard Workerdefm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
4145*9880d681SAndroid Build Coastguard Worker                           VR128, v8i16, v8i16, memopv2i64,
4146*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4147*9880d681SAndroid Build Coastguard Workerdefm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
4148*9880d681SAndroid Build Coastguard Worker                           VR128, v4i32, v4i32, memopv2i64,
4149*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4150*9880d681SAndroid Build Coastguard Workerdefm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
4151*9880d681SAndroid Build Coastguard Worker                           VR128, v2i64, v2i64, memopv2i64,
4152*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4153*9880d681SAndroid Build Coastguard Worker
4154*9880d681SAndroid Build Coastguard Workerdefm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
4155*9880d681SAndroid Build Coastguard Worker                           VR128, v8i16, v8i16, memopv2i64,
4156*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4157*9880d681SAndroid Build Coastguard Workerdefm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
4158*9880d681SAndroid Build Coastguard Worker                           VR128, v4i32, v4i32, memopv2i64,
4159*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4160*9880d681SAndroid Build Coastguard Workerdefm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
4161*9880d681SAndroid Build Coastguard Worker                           VR128, v2i64, v2i64, memopv2i64,
4162*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4163*9880d681SAndroid Build Coastguard Worker
4164*9880d681SAndroid Build Coastguard Workerdefm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
4165*9880d681SAndroid Build Coastguard Worker                           VR128, v8i16, v8i16, memopv2i64,
4166*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4167*9880d681SAndroid Build Coastguard Workerdefm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
4168*9880d681SAndroid Build Coastguard Worker                           VR128, v4i32, v4i32, memopv2i64,
4169*9880d681SAndroid Build Coastguard Worker                           SSE_INTSHIFT_ITINS_P>;
4170*9880d681SAndroid Build Coastguard Worker
4171*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift], hasSideEffects = 0 in {
4172*9880d681SAndroid Build Coastguard Worker  // 128-bit logical shifts.
4173*9880d681SAndroid Build Coastguard Worker  def PSLLDQri : PDIi8<0x73, MRM7r,
4174*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4175*9880d681SAndroid Build Coastguard Worker                       "pslldq\t{$src2, $dst|$dst, $src2}",
4176*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
4177*9880d681SAndroid Build Coastguard Worker                         (v16i8 (X86vshldq VR128:$src1, (i8 imm:$src2))))],
4178*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_INTSHDQ_P_RI>;
4179*9880d681SAndroid Build Coastguard Worker  def PSRLDQri : PDIi8<0x73, MRM3r,
4180*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4181*9880d681SAndroid Build Coastguard Worker                       "psrldq\t{$src2, $dst|$dst, $src2}",
4182*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst,
4183*9880d681SAndroid Build Coastguard Worker                         (v16i8 (X86vshrdq VR128:$src1, (i8 imm:$src2))))],
4184*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_INTSHDQ_P_RI>;
4185*9880d681SAndroid Build Coastguard Worker  // PSRADQri doesn't exist in SSE[1-3].
4186*9880d681SAndroid Build Coastguard Worker}
4187*9880d681SAndroid Build Coastguard Worker} // Constraints = "$src1 = $dst"
4188*9880d681SAndroid Build Coastguard Worker
4189*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4190*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Comparison Instructions
4191*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4192*9880d681SAndroid Build Coastguard Worker
4193*9880d681SAndroid Build Coastguard Workerdefm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
4194*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, TruePredicate>;
4195*9880d681SAndroid Build Coastguard Workerdefm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
4196*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, TruePredicate>;
4197*9880d681SAndroid Build Coastguard Workerdefm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
4198*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 1, TruePredicate>;
4199*9880d681SAndroid Build Coastguard Workerdefm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
4200*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, TruePredicate>;
4201*9880d681SAndroid Build Coastguard Workerdefm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
4202*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, TruePredicate>;
4203*9880d681SAndroid Build Coastguard Workerdefm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
4204*9880d681SAndroid Build Coastguard Worker                             SSE_INTALU_ITINS_P, 0, TruePredicate>;
4205*9880d681SAndroid Build Coastguard Worker
4206*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4207*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Shuffle Instructions
4208*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4209*9880d681SAndroid Build Coastguard Worker
4210*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in {
4211*9880d681SAndroid Build Coastguard Workermulticlass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
4212*9880d681SAndroid Build Coastguard Worker                         SDNode OpNode, Predicate prd> {
4213*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, prd] in {
4214*9880d681SAndroid Build Coastguard Worker  def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
4215*9880d681SAndroid Build Coastguard Worker                      (ins VR128:$src1, u8imm:$src2),
4216*9880d681SAndroid Build Coastguard Worker                      !strconcat("v", OpcodeStr,
4217*9880d681SAndroid Build Coastguard Worker                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4218*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
4219*9880d681SAndroid Build Coastguard Worker                        (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4220*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_PSHUF_RI>, VEX, Sched<[WriteShuffle]>;
4221*9880d681SAndroid Build Coastguard Worker  def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
4222*9880d681SAndroid Build Coastguard Worker                      (ins i128mem:$src1, u8imm:$src2),
4223*9880d681SAndroid Build Coastguard Worker                      !strconcat("v", OpcodeStr,
4224*9880d681SAndroid Build Coastguard Worker                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4225*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
4226*9880d681SAndroid Build Coastguard Worker                       (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
4227*9880d681SAndroid Build Coastguard Worker                        (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX,
4228*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffleLd]>;
4229*9880d681SAndroid Build Coastguard Worker}
4230*9880d681SAndroid Build Coastguard Worker
4231*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, prd] in {
4232*9880d681SAndroid Build Coastguard Worker  def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
4233*9880d681SAndroid Build Coastguard Worker                       (ins VR256:$src1, u8imm:$src2),
4234*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
4235*9880d681SAndroid Build Coastguard Worker                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4236*9880d681SAndroid Build Coastguard Worker                       [(set VR256:$dst,
4237*9880d681SAndroid Build Coastguard Worker                         (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))],
4238*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_PSHUF_RI>, VEX, VEX_L, Sched<[WriteShuffle]>;
4239*9880d681SAndroid Build Coastguard Worker  def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
4240*9880d681SAndroid Build Coastguard Worker                       (ins i256mem:$src1, u8imm:$src2),
4241*9880d681SAndroid Build Coastguard Worker                       !strconcat("v", OpcodeStr,
4242*9880d681SAndroid Build Coastguard Worker                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4243*9880d681SAndroid Build Coastguard Worker                      [(set VR256:$dst,
4244*9880d681SAndroid Build Coastguard Worker                        (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
4245*9880d681SAndroid Build Coastguard Worker                         (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX, VEX_L,
4246*9880d681SAndroid Build Coastguard Worker                   Sched<[WriteShuffleLd]>;
4247*9880d681SAndroid Build Coastguard Worker}
4248*9880d681SAndroid Build Coastguard Worker
4249*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
4250*9880d681SAndroid Build Coastguard Worker  def ri : Ii8<0x70, MRMSrcReg,
4251*9880d681SAndroid Build Coastguard Worker               (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4252*9880d681SAndroid Build Coastguard Worker               !strconcat(OpcodeStr,
4253*9880d681SAndroid Build Coastguard Worker                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4254*9880d681SAndroid Build Coastguard Worker                [(set VR128:$dst,
4255*9880d681SAndroid Build Coastguard Worker                  (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4256*9880d681SAndroid Build Coastguard Worker                IIC_SSE_PSHUF_RI>, Sched<[WriteShuffle]>;
4257*9880d681SAndroid Build Coastguard Worker  def mi : Ii8<0x70, MRMSrcMem,
4258*9880d681SAndroid Build Coastguard Worker               (outs VR128:$dst), (ins i128mem:$src1, u8imm:$src2),
4259*9880d681SAndroid Build Coastguard Worker               !strconcat(OpcodeStr,
4260*9880d681SAndroid Build Coastguard Worker                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4261*9880d681SAndroid Build Coastguard Worker                [(set VR128:$dst,
4262*9880d681SAndroid Build Coastguard Worker                  (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
4263*9880d681SAndroid Build Coastguard Worker                          (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>,
4264*9880d681SAndroid Build Coastguard Worker           Sched<[WriteShuffleLd, ReadAfterLd]>;
4265*9880d681SAndroid Build Coastguard Worker}
4266*9880d681SAndroid Build Coastguard Worker}
4267*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4268*9880d681SAndroid Build Coastguard Worker
4269*9880d681SAndroid Build Coastguard Workerdefm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd, NoVLX>, PD;
4270*9880d681SAndroid Build Coastguard Workerdefm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw,
4271*9880d681SAndroid Build Coastguard Worker                             NoVLX_Or_NoBWI>, XS;
4272*9880d681SAndroid Build Coastguard Workerdefm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw,
4273*9880d681SAndroid Build Coastguard Worker                             NoVLX_Or_NoBWI>, XD;
4274*9880d681SAndroid Build Coastguard Worker
4275*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
4276*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86PShufd (loadv4f32 addr:$src1), (i8 imm:$imm))),
4277*9880d681SAndroid Build Coastguard Worker            (VPSHUFDmi addr:$src1, imm:$imm)>;
4278*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4279*9880d681SAndroid Build Coastguard Worker            (VPSHUFDri VR128:$src1, imm:$imm)>;
4280*9880d681SAndroid Build Coastguard Worker}
4281*9880d681SAndroid Build Coastguard Worker
4282*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
4283*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4284*9880d681SAndroid Build Coastguard Worker            (PSHUFDmi addr:$src1, imm:$imm)>;
4285*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4286*9880d681SAndroid Build Coastguard Worker            (PSHUFDri VR128:$src1, imm:$imm)>;
4287*9880d681SAndroid Build Coastguard Worker}
4288*9880d681SAndroid Build Coastguard Worker
4289*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4290*9880d681SAndroid Build Coastguard Worker// Packed Integer Pack Instructions (SSE & AVX)
4291*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4292*9880d681SAndroid Build Coastguard Worker
4293*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in {
4294*9880d681SAndroid Build Coastguard Workermulticlass sse2_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4295*9880d681SAndroid Build Coastguard Worker                     ValueType ArgVT, SDNode OpNode, PatFrag ld_frag,
4296*9880d681SAndroid Build Coastguard Worker                     bit Is2Addr = 1> {
4297*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg,
4298*9880d681SAndroid Build Coastguard Worker               (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4299*9880d681SAndroid Build Coastguard Worker               !if(Is2Addr,
4300*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4301*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr,
4302*9880d681SAndroid Build Coastguard Worker                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4303*9880d681SAndroid Build Coastguard Worker               [(set VR128:$dst,
4304*9880d681SAndroid Build Coastguard Worker                     (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4305*9880d681SAndroid Build Coastguard Worker               Sched<[WriteShuffle]>;
4306*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem,
4307*9880d681SAndroid Build Coastguard Worker               (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4308*9880d681SAndroid Build Coastguard Worker               !if(Is2Addr,
4309*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4310*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr,
4311*9880d681SAndroid Build Coastguard Worker                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4312*9880d681SAndroid Build Coastguard Worker               [(set VR128:$dst,
4313*9880d681SAndroid Build Coastguard Worker                     (OutVT (OpNode (ArgVT VR128:$src1),
4314*9880d681SAndroid Build Coastguard Worker                                    (bitconvert (ld_frag addr:$src2)))))]>,
4315*9880d681SAndroid Build Coastguard Worker               Sched<[WriteShuffleLd, ReadAfterLd]>;
4316*9880d681SAndroid Build Coastguard Worker}
4317*9880d681SAndroid Build Coastguard Worker
4318*9880d681SAndroid Build Coastguard Workermulticlass sse2_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4319*9880d681SAndroid Build Coastguard Worker                       ValueType ArgVT, SDNode OpNode> {
4320*9880d681SAndroid Build Coastguard Worker  def Yrr : PDI<opc, MRMSrcReg,
4321*9880d681SAndroid Build Coastguard Worker                (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4322*9880d681SAndroid Build Coastguard Worker                !strconcat(OpcodeStr,
4323*9880d681SAndroid Build Coastguard Worker                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4324*9880d681SAndroid Build Coastguard Worker                [(set VR256:$dst,
4325*9880d681SAndroid Build Coastguard Worker                      (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4326*9880d681SAndroid Build Coastguard Worker                Sched<[WriteShuffle]>;
4327*9880d681SAndroid Build Coastguard Worker  def Yrm : PDI<opc, MRMSrcMem,
4328*9880d681SAndroid Build Coastguard Worker                (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4329*9880d681SAndroid Build Coastguard Worker                !strconcat(OpcodeStr,
4330*9880d681SAndroid Build Coastguard Worker                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4331*9880d681SAndroid Build Coastguard Worker                [(set VR256:$dst,
4332*9880d681SAndroid Build Coastguard Worker                      (OutVT (OpNode (ArgVT VR256:$src1),
4333*9880d681SAndroid Build Coastguard Worker                                     (bitconvert (loadv4i64 addr:$src2)))))]>,
4334*9880d681SAndroid Build Coastguard Worker                Sched<[WriteShuffleLd, ReadAfterLd]>;
4335*9880d681SAndroid Build Coastguard Worker}
4336*9880d681SAndroid Build Coastguard Worker
4337*9880d681SAndroid Build Coastguard Workermulticlass sse4_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4338*9880d681SAndroid Build Coastguard Worker                     ValueType ArgVT, SDNode OpNode, PatFrag ld_frag,
4339*9880d681SAndroid Build Coastguard Worker                     bit Is2Addr = 1> {
4340*9880d681SAndroid Build Coastguard Worker  def rr : SS48I<opc, MRMSrcReg,
4341*9880d681SAndroid Build Coastguard Worker                 (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4342*9880d681SAndroid Build Coastguard Worker                 !if(Is2Addr,
4343*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4344*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr,
4345*9880d681SAndroid Build Coastguard Worker                                "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4346*9880d681SAndroid Build Coastguard Worker                 [(set VR128:$dst,
4347*9880d681SAndroid Build Coastguard Worker                       (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4348*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteShuffle]>;
4349*9880d681SAndroid Build Coastguard Worker  def rm : SS48I<opc, MRMSrcMem,
4350*9880d681SAndroid Build Coastguard Worker                 (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4351*9880d681SAndroid Build Coastguard Worker                 !if(Is2Addr,
4352*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4353*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr,
4354*9880d681SAndroid Build Coastguard Worker                                "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4355*9880d681SAndroid Build Coastguard Worker                 [(set VR128:$dst,
4356*9880d681SAndroid Build Coastguard Worker                       (OutVT (OpNode (ArgVT VR128:$src1),
4357*9880d681SAndroid Build Coastguard Worker                                      (bitconvert (ld_frag addr:$src2)))))]>,
4358*9880d681SAndroid Build Coastguard Worker                 Sched<[WriteShuffleLd, ReadAfterLd]>;
4359*9880d681SAndroid Build Coastguard Worker}
4360*9880d681SAndroid Build Coastguard Worker
4361*9880d681SAndroid Build Coastguard Workermulticlass sse4_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4362*9880d681SAndroid Build Coastguard Worker                     ValueType ArgVT, SDNode OpNode> {
4363*9880d681SAndroid Build Coastguard Worker  def Yrr : SS48I<opc, MRMSrcReg,
4364*9880d681SAndroid Build Coastguard Worker                  (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4365*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr,
4366*9880d681SAndroid Build Coastguard Worker                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4367*9880d681SAndroid Build Coastguard Worker                  [(set VR256:$dst,
4368*9880d681SAndroid Build Coastguard Worker                        (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4369*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffle]>;
4370*9880d681SAndroid Build Coastguard Worker  def Yrm : SS48I<opc, MRMSrcMem,
4371*9880d681SAndroid Build Coastguard Worker                  (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4372*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr,
4373*9880d681SAndroid Build Coastguard Worker                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4374*9880d681SAndroid Build Coastguard Worker                  [(set VR256:$dst,
4375*9880d681SAndroid Build Coastguard Worker                        (OutVT (OpNode (ArgVT VR256:$src1),
4376*9880d681SAndroid Build Coastguard Worker                                       (bitconvert (loadv4i64 addr:$src2)))))]>,
4377*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffleLd, ReadAfterLd]>;
4378*9880d681SAndroid Build Coastguard Worker}
4379*9880d681SAndroid Build Coastguard Worker
4380*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4381*9880d681SAndroid Build Coastguard Worker  defm VPACKSSWB : sse2_pack<0x63, "vpacksswb", v16i8, v8i16, X86Packss,
4382*9880d681SAndroid Build Coastguard Worker                             loadv2i64, 0>, VEX_4V;
4383*9880d681SAndroid Build Coastguard Worker  defm VPACKSSDW : sse2_pack<0x6B, "vpackssdw", v8i16, v4i32, X86Packss,
4384*9880d681SAndroid Build Coastguard Worker                             loadv2i64, 0>, VEX_4V;
4385*9880d681SAndroid Build Coastguard Worker
4386*9880d681SAndroid Build Coastguard Worker  defm VPACKUSWB : sse2_pack<0x67, "vpackuswb", v16i8, v8i16, X86Packus,
4387*9880d681SAndroid Build Coastguard Worker                             loadv2i64, 0>, VEX_4V;
4388*9880d681SAndroid Build Coastguard Worker  defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus,
4389*9880d681SAndroid Build Coastguard Worker                             loadv2i64, 0>, VEX_4V;
4390*9880d681SAndroid Build Coastguard Worker}
4391*9880d681SAndroid Build Coastguard Worker
4392*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4393*9880d681SAndroid Build Coastguard Worker  defm VPACKSSWB : sse2_pack_y<0x63, "vpacksswb", v32i8, v16i16, X86Packss>,
4394*9880d681SAndroid Build Coastguard Worker                               VEX_4V, VEX_L;
4395*9880d681SAndroid Build Coastguard Worker  defm VPACKSSDW : sse2_pack_y<0x6B, "vpackssdw", v16i16, v8i32, X86Packss>,
4396*9880d681SAndroid Build Coastguard Worker                               VEX_4V, VEX_L;
4397*9880d681SAndroid Build Coastguard Worker
4398*9880d681SAndroid Build Coastguard Worker  defm VPACKUSWB : sse2_pack_y<0x67, "vpackuswb", v32i8, v16i16, X86Packus>,
4399*9880d681SAndroid Build Coastguard Worker                               VEX_4V, VEX_L;
4400*9880d681SAndroid Build Coastguard Worker  defm VPACKUSDW : sse4_pack_y<0x2B, "vpackusdw", v16i16, v8i32, X86Packus>,
4401*9880d681SAndroid Build Coastguard Worker                               VEX_4V, VEX_L;
4402*9880d681SAndroid Build Coastguard Worker}
4403*9880d681SAndroid Build Coastguard Worker
4404*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
4405*9880d681SAndroid Build Coastguard Worker  defm PACKSSWB : sse2_pack<0x63, "packsswb", v16i8, v8i16, X86Packss,
4406*9880d681SAndroid Build Coastguard Worker                            memopv2i64>;
4407*9880d681SAndroid Build Coastguard Worker  defm PACKSSDW : sse2_pack<0x6B, "packssdw", v8i16, v4i32, X86Packss,
4408*9880d681SAndroid Build Coastguard Worker                            memopv2i64>;
4409*9880d681SAndroid Build Coastguard Worker
4410*9880d681SAndroid Build Coastguard Worker  defm PACKUSWB : sse2_pack<0x67, "packuswb", v16i8, v8i16, X86Packus,
4411*9880d681SAndroid Build Coastguard Worker                            memopv2i64>;
4412*9880d681SAndroid Build Coastguard Worker
4413*9880d681SAndroid Build Coastguard Worker  defm PACKUSDW : sse4_pack<0x2B, "packusdw", v8i16, v4i32, X86Packus,
4414*9880d681SAndroid Build Coastguard Worker                            memopv2i64>;
4415*9880d681SAndroid Build Coastguard Worker}
4416*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4417*9880d681SAndroid Build Coastguard Worker
4418*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4419*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Unpack Instructions
4420*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4421*9880d681SAndroid Build Coastguard Worker
4422*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in {
4423*9880d681SAndroid Build Coastguard Workermulticlass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4424*9880d681SAndroid Build Coastguard Worker                       SDNode OpNode, PatFrag ld_frag, bit Is2Addr = 1> {
4425*9880d681SAndroid Build Coastguard Worker  def rr : PDI<opc, MRMSrcReg,
4426*9880d681SAndroid Build Coastguard Worker      (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4427*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
4428*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4429*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4430*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))],
4431*9880d681SAndroid Build Coastguard Worker      IIC_SSE_UNPCK>, Sched<[WriteShuffle]>;
4432*9880d681SAndroid Build Coastguard Worker  def rm : PDI<opc, MRMSrcMem,
4433*9880d681SAndroid Build Coastguard Worker      (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4434*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
4435*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4436*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4437*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst, (vt (OpNode VR128:$src1,
4438*9880d681SAndroid Build Coastguard Worker                                  (bitconvert (ld_frag addr:$src2)))))],
4439*9880d681SAndroid Build Coastguard Worker                                               IIC_SSE_UNPCK>,
4440*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffleLd, ReadAfterLd]>;
4441*9880d681SAndroid Build Coastguard Worker}
4442*9880d681SAndroid Build Coastguard Worker
4443*9880d681SAndroid Build Coastguard Workermulticlass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4444*9880d681SAndroid Build Coastguard Worker                         SDNode OpNode> {
4445*9880d681SAndroid Build Coastguard Worker  def Yrr : PDI<opc, MRMSrcReg,
4446*9880d681SAndroid Build Coastguard Worker      (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4447*9880d681SAndroid Build Coastguard Worker      !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4448*9880d681SAndroid Build Coastguard Worker      [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>,
4449*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffle]>;
4450*9880d681SAndroid Build Coastguard Worker  def Yrm : PDI<opc, MRMSrcMem,
4451*9880d681SAndroid Build Coastguard Worker      (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4452*9880d681SAndroid Build Coastguard Worker      !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4453*9880d681SAndroid Build Coastguard Worker      [(set VR256:$dst, (vt (OpNode VR256:$src1,
4454*9880d681SAndroid Build Coastguard Worker                                  (bitconvert (loadv4i64 addr:$src2)))))]>,
4455*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffleLd, ReadAfterLd]>;
4456*9880d681SAndroid Build Coastguard Worker}
4457*9880d681SAndroid Build Coastguard Worker
4458*9880d681SAndroid Build Coastguard Worker
4459*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4460*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4461*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4462*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4463*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4464*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4465*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4466*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4467*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4468*9880d681SAndroid Build Coastguard Worker}
4469*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
4470*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4471*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4472*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4473*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4474*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4475*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4476*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4477*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, 0>, VEX_4V;
4478*9880d681SAndroid Build Coastguard Worker}
4479*9880d681SAndroid Build Coastguard Worker
4480*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4481*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl>,
4482*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4483*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl>,
4484*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4485*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh>,
4486*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4487*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh>,
4488*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4489*9880d681SAndroid Build Coastguard Worker}
4490*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
4491*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl>,
4492*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4493*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl>,
4494*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4495*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh>,
4496*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4497*9880d681SAndroid Build Coastguard Worker  defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh>,
4498*9880d681SAndroid Build Coastguard Worker                                   VEX_4V, VEX_L;
4499*9880d681SAndroid Build Coastguard Worker}
4500*9880d681SAndroid Build Coastguard Worker
4501*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
4502*9880d681SAndroid Build Coastguard Worker  defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4503*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4504*9880d681SAndroid Build Coastguard Worker  defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4505*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4506*9880d681SAndroid Build Coastguard Worker  defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4507*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4508*9880d681SAndroid Build Coastguard Worker  defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4509*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4510*9880d681SAndroid Build Coastguard Worker
4511*9880d681SAndroid Build Coastguard Worker  defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4512*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4513*9880d681SAndroid Build Coastguard Worker  defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4514*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4515*9880d681SAndroid Build Coastguard Worker  defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4516*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4517*9880d681SAndroid Build Coastguard Worker  defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4518*9880d681SAndroid Build Coastguard Worker                                memopv2i64>;
4519*9880d681SAndroid Build Coastguard Worker}
4520*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4521*9880d681SAndroid Build Coastguard Worker
4522*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4523*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Integer Extract and Insert
4524*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4525*9880d681SAndroid Build Coastguard Worker
4526*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt in {
4527*9880d681SAndroid Build Coastguard Workermulticlass sse2_pinsrw<bit Is2Addr = 1> {
4528*9880d681SAndroid Build Coastguard Worker  def rri : Ii8<0xC4, MRMSrcReg,
4529*9880d681SAndroid Build Coastguard Worker       (outs VR128:$dst), (ins VR128:$src1,
4530*9880d681SAndroid Build Coastguard Worker        GR32orGR64:$src2, u8imm:$src3),
4531*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
4532*9880d681SAndroid Build Coastguard Worker           "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4533*9880d681SAndroid Build Coastguard Worker           "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4534*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst,
4535*9880d681SAndroid Build Coastguard Worker         (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))],
4536*9880d681SAndroid Build Coastguard Worker       IIC_SSE_PINSRW>, Sched<[WriteShuffle]>;
4537*9880d681SAndroid Build Coastguard Worker  def rmi : Ii8<0xC4, MRMSrcMem,
4538*9880d681SAndroid Build Coastguard Worker                       (outs VR128:$dst), (ins VR128:$src1,
4539*9880d681SAndroid Build Coastguard Worker                        i16mem:$src2, u8imm:$src3),
4540*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
4541*9880d681SAndroid Build Coastguard Worker           "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4542*9880d681SAndroid Build Coastguard Worker           "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4543*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst,
4544*9880d681SAndroid Build Coastguard Worker         (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4545*9880d681SAndroid Build Coastguard Worker                    imm:$src3))], IIC_SSE_PINSRW>,
4546*9880d681SAndroid Build Coastguard Worker       Sched<[WriteShuffleLd, ReadAfterLd]>;
4547*9880d681SAndroid Build Coastguard Worker}
4548*9880d681SAndroid Build Coastguard Worker
4549*9880d681SAndroid Build Coastguard Worker// Extract
4550*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoBWI] in
4551*9880d681SAndroid Build Coastguard Workerdef VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4552*9880d681SAndroid Build Coastguard Worker                    (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
4553*9880d681SAndroid Build Coastguard Worker                    "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4554*9880d681SAndroid Build Coastguard Worker                    [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4555*9880d681SAndroid Build Coastguard Worker                                            imm:$src2))]>, PD, VEX,
4556*9880d681SAndroid Build Coastguard Worker                Sched<[WriteShuffle]>;
4557*9880d681SAndroid Build Coastguard Workerdef PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4558*9880d681SAndroid Build Coastguard Worker                    (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
4559*9880d681SAndroid Build Coastguard Worker                    "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4560*9880d681SAndroid Build Coastguard Worker                    [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4561*9880d681SAndroid Build Coastguard Worker                                            imm:$src2))], IIC_SSE_PEXTRW>,
4562*9880d681SAndroid Build Coastguard Worker               Sched<[WriteShuffleLd, ReadAfterLd]>;
4563*9880d681SAndroid Build Coastguard Worker
4564*9880d681SAndroid Build Coastguard Worker// Insert
4565*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoBWI] in
4566*9880d681SAndroid Build Coastguard Workerdefm VPINSRW : sse2_pinsrw<0>, PD, VEX_4V;
4567*9880d681SAndroid Build Coastguard Worker
4568*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
4569*9880d681SAndroid Build Coastguard Workerdefm PINSRW : sse2_pinsrw, PD;
4570*9880d681SAndroid Build Coastguard Worker
4571*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4572*9880d681SAndroid Build Coastguard Worker
4573*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4574*9880d681SAndroid Build Coastguard Worker// SSE2 - Packed Mask Creation
4575*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4576*9880d681SAndroid Build Coastguard Worker
4577*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4578*9880d681SAndroid Build Coastguard Worker
4579*9880d681SAndroid Build Coastguard Workerdef VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4580*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src),
4581*9880d681SAndroid Build Coastguard Worker           "pmovmskb\t{$src, $dst|$dst, $src}",
4582*9880d681SAndroid Build Coastguard Worker           [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))],
4583*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MOVMSK>, VEX;
4584*9880d681SAndroid Build Coastguard Worker
4585*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
4586*9880d681SAndroid Build Coastguard Workerdef VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4587*9880d681SAndroid Build Coastguard Worker           (ins VR256:$src),
4588*9880d681SAndroid Build Coastguard Worker           "pmovmskb\t{$src, $dst|$dst, $src}",
4589*9880d681SAndroid Build Coastguard Worker           [(set GR32orGR64:$dst, (X86movmsk (v32i8 VR256:$src)))]>,
4590*9880d681SAndroid Build Coastguard Worker           VEX, VEX_L;
4591*9880d681SAndroid Build Coastguard Worker}
4592*9880d681SAndroid Build Coastguard Worker
4593*9880d681SAndroid Build Coastguard Workerdef PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
4594*9880d681SAndroid Build Coastguard Worker           "pmovmskb\t{$src, $dst|$dst, $src}",
4595*9880d681SAndroid Build Coastguard Worker           [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))],
4596*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MOVMSK>;
4597*9880d681SAndroid Build Coastguard Worker
4598*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4599*9880d681SAndroid Build Coastguard Worker
4600*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4601*9880d681SAndroid Build Coastguard Worker// SSE2 - Conditional Store
4602*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4603*9880d681SAndroid Build Coastguard Worker
4604*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4605*9880d681SAndroid Build Coastguard Worker
4606*9880d681SAndroid Build Coastguard Workerlet Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
4607*9880d681SAndroid Build Coastguard Workerdef VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4608*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src, VR128:$mask),
4609*9880d681SAndroid Build Coastguard Worker           "maskmovdqu\t{$mask, $src|$src, $mask}",
4610*9880d681SAndroid Build Coastguard Worker           [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4611*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MASKMOV>, VEX;
4612*9880d681SAndroid Build Coastguard Workerlet Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
4613*9880d681SAndroid Build Coastguard Workerdef VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4614*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src, VR128:$mask),
4615*9880d681SAndroid Build Coastguard Worker           "maskmovdqu\t{$mask, $src|$src, $mask}",
4616*9880d681SAndroid Build Coastguard Worker           [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4617*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MASKMOV>, VEX;
4618*9880d681SAndroid Build Coastguard Worker
4619*9880d681SAndroid Build Coastguard Workerlet Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
4620*9880d681SAndroid Build Coastguard Workerdef MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4621*9880d681SAndroid Build Coastguard Worker           "maskmovdqu\t{$mask, $src|$src, $mask}",
4622*9880d681SAndroid Build Coastguard Worker           [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4623*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MASKMOV>;
4624*9880d681SAndroid Build Coastguard Workerlet Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
4625*9880d681SAndroid Build Coastguard Workerdef MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4626*9880d681SAndroid Build Coastguard Worker           "maskmovdqu\t{$mask, $src|$src, $mask}",
4627*9880d681SAndroid Build Coastguard Worker           [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4628*9880d681SAndroid Build Coastguard Worker           IIC_SSE_MASKMOV>;
4629*9880d681SAndroid Build Coastguard Worker
4630*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedInt
4631*9880d681SAndroid Build Coastguard Worker
4632*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4633*9880d681SAndroid Build Coastguard Worker// SSE2 - Move Doubleword/Quadword
4634*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4635*9880d681SAndroid Build Coastguard Worker
4636*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4637*9880d681SAndroid Build Coastguard Worker// Move Int Doubleword to Packed Double Int
4638*9880d681SAndroid Build Coastguard Worker//
4639*9880d681SAndroid Build Coastguard Workerdef VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4640*9880d681SAndroid Build Coastguard Worker                      "movd\t{$src, $dst|$dst, $src}",
4641*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
4642*9880d681SAndroid Build Coastguard Worker                        (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4643*9880d681SAndroid Build Coastguard Worker                        VEX, Sched<[WriteMove]>;
4644*9880d681SAndroid Build Coastguard Workerdef VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4645*9880d681SAndroid Build Coastguard Worker                      "movd\t{$src, $dst|$dst, $src}",
4646*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
4647*9880d681SAndroid Build Coastguard Worker                        (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4648*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>,
4649*9880d681SAndroid Build Coastguard Worker                      VEX, Sched<[WriteLoad]>;
4650*9880d681SAndroid Build Coastguard Workerdef VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4651*9880d681SAndroid Build Coastguard Worker                        "movq\t{$src, $dst|$dst, $src}",
4652*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
4653*9880d681SAndroid Build Coastguard Worker                          (v2i64 (scalar_to_vector GR64:$src)))],
4654*9880d681SAndroid Build Coastguard Worker                          IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4655*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
4656*9880d681SAndroid Build Coastguard Workerdef VMOV64toPQIrm : VRS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4657*9880d681SAndroid Build Coastguard Worker                        "movq\t{$src, $dst|$dst, $src}",
4658*9880d681SAndroid Build Coastguard Worker                        [], IIC_SSE_MOVDQ>, VEX, Sched<[WriteLoad]>;
4659*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in
4660*9880d681SAndroid Build Coastguard Workerdef VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4661*9880d681SAndroid Build Coastguard Worker                       "movq\t{$src, $dst|$dst, $src}",
4662*9880d681SAndroid Build Coastguard Worker                       [(set FR64:$dst, (bitconvert GR64:$src))],
4663*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4664*9880d681SAndroid Build Coastguard Worker
4665*9880d681SAndroid Build Coastguard Workerdef MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4666*9880d681SAndroid Build Coastguard Worker                      "movd\t{$src, $dst|$dst, $src}",
4667*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
4668*9880d681SAndroid Build Coastguard Worker                        (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4669*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteMove]>;
4670*9880d681SAndroid Build Coastguard Workerdef MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4671*9880d681SAndroid Build Coastguard Worker                      "movd\t{$src, $dst|$dst, $src}",
4672*9880d681SAndroid Build Coastguard Worker                      [(set VR128:$dst,
4673*9880d681SAndroid Build Coastguard Worker                        (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4674*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4675*9880d681SAndroid Build Coastguard Workerdef MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4676*9880d681SAndroid Build Coastguard Worker                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4677*9880d681SAndroid Build Coastguard Worker                        [(set VR128:$dst,
4678*9880d681SAndroid Build Coastguard Worker                          (v2i64 (scalar_to_vector GR64:$src)))],
4679*9880d681SAndroid Build Coastguard Worker                          IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4680*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
4681*9880d681SAndroid Build Coastguard Workerdef MOV64toPQIrm : RS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4682*9880d681SAndroid Build Coastguard Worker                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4683*9880d681SAndroid Build Coastguard Worker                        [], IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4684*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in
4685*9880d681SAndroid Build Coastguard Workerdef MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4686*9880d681SAndroid Build Coastguard Worker                       "mov{d|q}\t{$src, $dst|$dst, $src}",
4687*9880d681SAndroid Build Coastguard Worker                       [(set FR64:$dst, (bitconvert GR64:$src))],
4688*9880d681SAndroid Build Coastguard Worker                       IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4689*9880d681SAndroid Build Coastguard Worker
4690*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4691*9880d681SAndroid Build Coastguard Worker// Move Int Doubleword to Single Scalar
4692*9880d681SAndroid Build Coastguard Worker//
4693*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
4694*9880d681SAndroid Build Coastguard Worker  def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4695*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4696*9880d681SAndroid Build Coastguard Worker                        [(set FR32:$dst, (bitconvert GR32:$src))],
4697*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4698*9880d681SAndroid Build Coastguard Worker
4699*9880d681SAndroid Build Coastguard Worker  def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4700*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4701*9880d681SAndroid Build Coastguard Worker                        [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4702*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>,
4703*9880d681SAndroid Build Coastguard Worker                        VEX, Sched<[WriteLoad]>;
4704*9880d681SAndroid Build Coastguard Worker  def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4705*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4706*9880d681SAndroid Build Coastguard Worker                        [(set FR32:$dst, (bitconvert GR32:$src))],
4707*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4708*9880d681SAndroid Build Coastguard Worker
4709*9880d681SAndroid Build Coastguard Worker  def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4710*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4711*9880d681SAndroid Build Coastguard Worker                        [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4712*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4713*9880d681SAndroid Build Coastguard Worker}
4714*9880d681SAndroid Build Coastguard Worker
4715*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4716*9880d681SAndroid Build Coastguard Worker// Move Packed Doubleword Int to Packed Double Int
4717*9880d681SAndroid Build Coastguard Worker//
4718*9880d681SAndroid Build Coastguard Workerdef VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4719*9880d681SAndroid Build Coastguard Worker                       "movd\t{$src, $dst|$dst, $src}",
4720*9880d681SAndroid Build Coastguard Worker                       [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4721*9880d681SAndroid Build Coastguard Worker                                        (iPTR 0)))], IIC_SSE_MOVD_ToGP>, VEX,
4722*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteMove]>;
4723*9880d681SAndroid Build Coastguard Workerdef VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4724*9880d681SAndroid Build Coastguard Worker                       (ins i32mem:$dst, VR128:$src),
4725*9880d681SAndroid Build Coastguard Worker                       "movd\t{$src, $dst|$dst, $src}",
4726*9880d681SAndroid Build Coastguard Worker                       [(store (i32 (extractelt (v4i32 VR128:$src),
4727*9880d681SAndroid Build Coastguard Worker                                     (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
4728*9880d681SAndroid Build Coastguard Worker                                     VEX, Sched<[WriteStore]>;
4729*9880d681SAndroid Build Coastguard Workerdef MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4730*9880d681SAndroid Build Coastguard Worker                       "movd\t{$src, $dst|$dst, $src}",
4731*9880d681SAndroid Build Coastguard Worker                       [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4732*9880d681SAndroid Build Coastguard Worker                                        (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
4733*9880d681SAndroid Build Coastguard Worker                   Sched<[WriteMove]>;
4734*9880d681SAndroid Build Coastguard Workerdef MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4735*9880d681SAndroid Build Coastguard Worker                       "movd\t{$src, $dst|$dst, $src}",
4736*9880d681SAndroid Build Coastguard Worker                       [(store (i32 (extractelt (v4i32 VR128:$src),
4737*9880d681SAndroid Build Coastguard Worker                                     (iPTR 0))), addr:$dst)],
4738*9880d681SAndroid Build Coastguard Worker                                     IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4739*9880d681SAndroid Build Coastguard Worker
4740*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86Vinsert (v8i32 immAllZerosV), GR32:$src2, (iPTR 0))),
4741*9880d681SAndroid Build Coastguard Worker        (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4742*9880d681SAndroid Build Coastguard Worker
4743*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86Vinsert (bc_v4i64 (v8i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
4744*9880d681SAndroid Build Coastguard Worker        (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4745*9880d681SAndroid Build Coastguard Worker
4746*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
4747*9880d681SAndroid Build Coastguard Worker        (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4748*9880d681SAndroid Build Coastguard Worker
4749*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
4750*9880d681SAndroid Build Coastguard Worker        (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4751*9880d681SAndroid Build Coastguard Worker
4752*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4753*9880d681SAndroid Build Coastguard Worker// Move Packed Doubleword Int first element to Doubleword Int
4754*9880d681SAndroid Build Coastguard Worker//
4755*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteMove] in {
4756*9880d681SAndroid Build Coastguard Workerdef VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4757*9880d681SAndroid Build Coastguard Worker                          "movq\t{$src, $dst|$dst, $src}",
4758*9880d681SAndroid Build Coastguard Worker                          [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4759*9880d681SAndroid Build Coastguard Worker                                                        (iPTR 0)))],
4760*9880d681SAndroid Build Coastguard Worker                                                           IIC_SSE_MOVD_ToGP>,
4761*9880d681SAndroid Build Coastguard Worker                      VEX;
4762*9880d681SAndroid Build Coastguard Worker
4763*9880d681SAndroid Build Coastguard Workerdef MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4764*9880d681SAndroid Build Coastguard Worker                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4765*9880d681SAndroid Build Coastguard Worker                        [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4766*9880d681SAndroid Build Coastguard Worker                                                         (iPTR 0)))],
4767*9880d681SAndroid Build Coastguard Worker                                                         IIC_SSE_MOVD_ToGP>;
4768*9880d681SAndroid Build Coastguard Worker} //SchedRW
4769*9880d681SAndroid Build Coastguard Worker
4770*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4771*9880d681SAndroid Build Coastguard Workerdef VMOVPQIto64rm : VRS2I<0x7E, MRMDestMem, (outs),
4772*9880d681SAndroid Build Coastguard Worker                          (ins i64mem:$dst, VR128:$src),
4773*9880d681SAndroid Build Coastguard Worker                          "movq\t{$src, $dst|$dst, $src}",
4774*9880d681SAndroid Build Coastguard Worker                          [], IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4775*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4776*9880d681SAndroid Build Coastguard Workerdef MOVPQIto64rm : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4777*9880d681SAndroid Build Coastguard Worker                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4778*9880d681SAndroid Build Coastguard Worker                        [], IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4779*9880d681SAndroid Build Coastguard Worker
4780*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4781*9880d681SAndroid Build Coastguard Worker// Bitcast FR64 <-> GR64
4782*9880d681SAndroid Build Coastguard Worker//
4783*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
4784*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in
4785*9880d681SAndroid Build Coastguard Worker  def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4786*9880d681SAndroid Build Coastguard Worker                          "movq\t{$src, $dst|$dst, $src}",
4787*9880d681SAndroid Build Coastguard Worker                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4788*9880d681SAndroid Build Coastguard Worker                          VEX, Sched<[WriteLoad]>;
4789*9880d681SAndroid Build Coastguard Worker  def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4790*9880d681SAndroid Build Coastguard Worker                           "movq\t{$src, $dst|$dst, $src}",
4791*9880d681SAndroid Build Coastguard Worker                           [(set GR64:$dst, (bitconvert FR64:$src))],
4792*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4793*9880d681SAndroid Build Coastguard Worker  def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4794*9880d681SAndroid Build Coastguard Worker                           "movq\t{$src, $dst|$dst, $src}",
4795*9880d681SAndroid Build Coastguard Worker                           [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4796*9880d681SAndroid Build Coastguard Worker                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4797*9880d681SAndroid Build Coastguard Worker
4798*9880d681SAndroid Build Coastguard Worker  def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4799*9880d681SAndroid Build Coastguard Worker                         "movq\t{$src, $dst|$dst, $src}",
4800*9880d681SAndroid Build Coastguard Worker                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))],
4801*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4802*9880d681SAndroid Build Coastguard Worker  def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4803*9880d681SAndroid Build Coastguard Worker                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4804*9880d681SAndroid Build Coastguard Worker                         [(set GR64:$dst, (bitconvert FR64:$src))],
4805*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4806*9880d681SAndroid Build Coastguard Worker  def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4807*9880d681SAndroid Build Coastguard Worker                         "movq\t{$src, $dst|$dst, $src}",
4808*9880d681SAndroid Build Coastguard Worker                         [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4809*9880d681SAndroid Build Coastguard Worker                         IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4810*9880d681SAndroid Build Coastguard Worker}
4811*9880d681SAndroid Build Coastguard Worker
4812*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4813*9880d681SAndroid Build Coastguard Worker// Move Scalar Single to Double Int
4814*9880d681SAndroid Build Coastguard Worker//
4815*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in {
4816*9880d681SAndroid Build Coastguard Worker  def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4817*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4818*9880d681SAndroid Build Coastguard Worker                        [(set GR32:$dst, (bitconvert FR32:$src))],
4819*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVD_ToGP>, VEX, Sched<[WriteMove]>;
4820*9880d681SAndroid Build Coastguard Worker  def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4821*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4822*9880d681SAndroid Build Coastguard Worker                        [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4823*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4824*9880d681SAndroid Build Coastguard Worker  def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4825*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4826*9880d681SAndroid Build Coastguard Worker                        [(set GR32:$dst, (bitconvert FR32:$src))],
4827*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4828*9880d681SAndroid Build Coastguard Worker  def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4829*9880d681SAndroid Build Coastguard Worker                        "movd\t{$src, $dst|$dst, $src}",
4830*9880d681SAndroid Build Coastguard Worker                        [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4831*9880d681SAndroid Build Coastguard Worker                        IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4832*9880d681SAndroid Build Coastguard Worker}
4833*9880d681SAndroid Build Coastguard Worker
4834*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
4835*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 15 in {
4836*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4837*9880d681SAndroid Build Coastguard Worker              (VMOVDI2PDIrr GR32:$src)>;
4838*9880d681SAndroid Build Coastguard Worker
4839*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4840*9880d681SAndroid Build Coastguard Worker              (VMOV64toPQIrr GR64:$src)>;
4841*9880d681SAndroid Build Coastguard Worker
4842*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4843*9880d681SAndroid Build Coastguard Worker                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
4844*9880d681SAndroid Build Coastguard Worker              (SUBREG_TO_REG (i64 0), (VMOV64toPQIrr GR64:$src), sub_xmm)>;
4845*9880d681SAndroid Build Coastguard Worker  }
4846*9880d681SAndroid Build Coastguard Worker  // AVX 128-bit movd/movq instructions write zeros in the high 128-bit part.
4847*9880d681SAndroid Build Coastguard Worker  // These instructions also write zeros in the high part of a 256-bit register.
4848*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in {
4849*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4850*9880d681SAndroid Build Coastguard Worker              (VMOVDI2PDIrm addr:$src)>;
4851*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4852*9880d681SAndroid Build Coastguard Worker              (VMOVDI2PDIrm addr:$src)>;
4853*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4854*9880d681SAndroid Build Coastguard Worker              (VMOVDI2PDIrm addr:$src)>;
4855*9880d681SAndroid Build Coastguard Worker    def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4856*9880d681SAndroid Build Coastguard Worker                (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
4857*9880d681SAndroid Build Coastguard Worker              (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrm addr:$src), sub_xmm)>;
4858*9880d681SAndroid Build Coastguard Worker  }
4859*9880d681SAndroid Build Coastguard Worker  // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4860*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4861*9880d681SAndroid Build Coastguard Worker                               (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
4862*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
4863*9880d681SAndroid Build Coastguard Worker}
4864*9880d681SAndroid Build Coastguard Worker
4865*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2] in {
4866*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 15 in {
4867*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4868*9880d681SAndroid Build Coastguard Worker              (MOVDI2PDIrr GR32:$src)>;
4869*9880d681SAndroid Build Coastguard Worker
4870*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4871*9880d681SAndroid Build Coastguard Worker              (MOV64toPQIrr GR64:$src)>;
4872*9880d681SAndroid Build Coastguard Worker  }
4873*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 20 in {
4874*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4875*9880d681SAndroid Build Coastguard Worker              (MOVDI2PDIrm addr:$src)>;
4876*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4877*9880d681SAndroid Build Coastguard Worker              (MOVDI2PDIrm addr:$src)>;
4878*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4879*9880d681SAndroid Build Coastguard Worker              (MOVDI2PDIrm addr:$src)>;
4880*9880d681SAndroid Build Coastguard Worker  }
4881*9880d681SAndroid Build Coastguard Worker}
4882*9880d681SAndroid Build Coastguard Worker
4883*9880d681SAndroid Build Coastguard Worker// These are the correct encodings of the instructions so that we know how to
4884*9880d681SAndroid Build Coastguard Worker// read correct assembly, even though we continue to emit the wrong ones for
4885*9880d681SAndroid Build Coastguard Worker// compatibility with Darwin's buggy assembler.
4886*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4887*9880d681SAndroid Build Coastguard Worker                (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4888*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4889*9880d681SAndroid Build Coastguard Worker                (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4890*9880d681SAndroid Build Coastguard Worker// Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
4891*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4892*9880d681SAndroid Build Coastguard Worker                (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4893*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4894*9880d681SAndroid Build Coastguard Worker                (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4895*9880d681SAndroid Build Coastguard Worker
4896*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4897*9880d681SAndroid Build Coastguard Worker// SSE2 - Move Quadword
4898*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4899*9880d681SAndroid Build Coastguard Worker
4900*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4901*9880d681SAndroid Build Coastguard Worker// Move Quadword Int to Packed Quadword Int
4902*9880d681SAndroid Build Coastguard Worker//
4903*9880d681SAndroid Build Coastguard Worker
4904*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteLoad] in {
4905*9880d681SAndroid Build Coastguard Workerdef VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4906*9880d681SAndroid Build Coastguard Worker                    "vmovq\t{$src, $dst|$dst, $src}",
4907*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
4908*9880d681SAndroid Build Coastguard Worker                      (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4909*9880d681SAndroid Build Coastguard Worker                    VEX, Requires<[UseAVX]>;
4910*9880d681SAndroid Build Coastguard Workerdef MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4911*9880d681SAndroid Build Coastguard Worker                    "movq\t{$src, $dst|$dst, $src}",
4912*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
4913*9880d681SAndroid Build Coastguard Worker                      (v2i64 (scalar_to_vector (loadi64 addr:$src))))],
4914*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_MOVDQ>, XS,
4915*9880d681SAndroid Build Coastguard Worker                    Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
4916*9880d681SAndroid Build Coastguard Worker} // ExeDomain, SchedRW
4917*9880d681SAndroid Build Coastguard Worker
4918*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4919*9880d681SAndroid Build Coastguard Worker// Move Packed Quadword Int to Quadword Int
4920*9880d681SAndroid Build Coastguard Worker//
4921*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4922*9880d681SAndroid Build Coastguard Workerdef VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4923*9880d681SAndroid Build Coastguard Worker                      "movq\t{$src, $dst|$dst, $src}",
4924*9880d681SAndroid Build Coastguard Worker                      [(store (i64 (extractelt (v2i64 VR128:$src),
4925*9880d681SAndroid Build Coastguard Worker                                    (iPTR 0))), addr:$dst)],
4926*9880d681SAndroid Build Coastguard Worker                                    IIC_SSE_MOVDQ>, VEX;
4927*9880d681SAndroid Build Coastguard Workerdef MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4928*9880d681SAndroid Build Coastguard Worker                      "movq\t{$src, $dst|$dst, $src}",
4929*9880d681SAndroid Build Coastguard Worker                      [(store (i64 (extractelt (v2i64 VR128:$src),
4930*9880d681SAndroid Build Coastguard Worker                                    (iPTR 0))), addr:$dst)],
4931*9880d681SAndroid Build Coastguard Worker                                    IIC_SSE_MOVDQ>;
4932*9880d681SAndroid Build Coastguard Worker} // ExeDomain, SchedRW
4933*9880d681SAndroid Build Coastguard Worker
4934*9880d681SAndroid Build Coastguard Worker// For disassembler only
4935*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
4936*9880d681SAndroid Build Coastguard Worker    SchedRW = [WriteVecLogic] in {
4937*9880d681SAndroid Build Coastguard Workerdef VMOVPQI2QIrr : VS2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4938*9880d681SAndroid Build Coastguard Worker                     "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>, VEX;
4939*9880d681SAndroid Build Coastguard Workerdef MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4940*9880d681SAndroid Build Coastguard Worker                      "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>;
4941*9880d681SAndroid Build Coastguard Worker}
4942*9880d681SAndroid Build Coastguard Worker
4943*9880d681SAndroid Build Coastguard Worker// Aliases to help the assembler pick two byte VEX encodings by swapping the
4944*9880d681SAndroid Build Coastguard Worker// operands relative to the normal instructions to use VEX.R instead of VEX.B.
4945*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"vmovq\t{$src, $dst|$dst, $src}",
4946*9880d681SAndroid Build Coastguard Worker                (VMOVPQI2QIrr VR128L:$dst, VR128H:$src), 0>;
4947*9880d681SAndroid Build Coastguard Worker
4948*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4949*9880d681SAndroid Build Coastguard Worker// Store / copy lower 64-bits of a XMM register.
4950*9880d681SAndroid Build Coastguard Worker//
4951*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, isCodeGenOnly = 1, AddedComplexity = 20 in {
4952*9880d681SAndroid Build Coastguard Workerdef VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4953*9880d681SAndroid Build Coastguard Worker                     "vmovq\t{$src, $dst|$dst, $src}",
4954*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
4955*9880d681SAndroid Build Coastguard Worker                       (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4956*9880d681SAndroid Build Coastguard Worker                                                 (loadi64 addr:$src))))))],
4957*9880d681SAndroid Build Coastguard Worker                                                 IIC_SSE_MOVDQ>,
4958*9880d681SAndroid Build Coastguard Worker                     XS, VEX, Requires<[UseAVX]>, Sched<[WriteLoad]>;
4959*9880d681SAndroid Build Coastguard Worker
4960*9880d681SAndroid Build Coastguard Workerdef MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4961*9880d681SAndroid Build Coastguard Worker                     "movq\t{$src, $dst|$dst, $src}",
4962*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
4963*9880d681SAndroid Build Coastguard Worker                       (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4964*9880d681SAndroid Build Coastguard Worker                                                 (loadi64 addr:$src))))))],
4965*9880d681SAndroid Build Coastguard Worker                                                 IIC_SSE_MOVDQ>,
4966*9880d681SAndroid Build Coastguard Worker                     XS, Requires<[UseSSE2]>, Sched<[WriteLoad]>;
4967*9880d681SAndroid Build Coastguard Worker} // ExeDomain, isCodeGenOnly, AddedComplexity
4968*9880d681SAndroid Build Coastguard Worker
4969*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX], AddedComplexity = 20 in {
4970*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4971*9880d681SAndroid Build Coastguard Worker            (VMOVZQI2PQIrm addr:$src)>;
4972*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86vzload addr:$src)),
4973*9880d681SAndroid Build Coastguard Worker            (VMOVZQI2PQIrm addr:$src)>;
4974*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4975*9880d681SAndroid Build Coastguard Worker              (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
4976*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrm addr:$src), sub_xmm)>;
4977*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86vzload addr:$src)),
4978*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrm addr:$src), sub_xmm)>;
4979*9880d681SAndroid Build Coastguard Worker}
4980*9880d681SAndroid Build Coastguard Worker
4981*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE2], AddedComplexity = 20 in {
4982*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4983*9880d681SAndroid Build Coastguard Worker            (MOVZQI2PQIrm addr:$src)>;
4984*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4985*9880d681SAndroid Build Coastguard Worker}
4986*9880d681SAndroid Build Coastguard Worker
4987*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
4988*9880d681SAndroid Build Coastguard Worker// Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4989*9880d681SAndroid Build Coastguard Worker// IA32 document. movq xmm1, xmm2 does clear the high bits.
4990*9880d681SAndroid Build Coastguard Worker//
4991*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4992*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 15 in
4993*9880d681SAndroid Build Coastguard Workerdef VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4994*9880d681SAndroid Build Coastguard Worker                        "vmovq\t{$src, $dst|$dst, $src}",
4995*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
4996*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOVQ_RR>,
4997*9880d681SAndroid Build Coastguard Worker                      XS, VEX, Requires<[UseAVX]>;
4998*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 15 in
4999*9880d681SAndroid Build Coastguard Workerdef MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5000*9880d681SAndroid Build Coastguard Worker                        "movq\t{$src, $dst|$dst, $src}",
5001*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
5002*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOVQ_RR>,
5003*9880d681SAndroid Build Coastguard Worker                      XS, Requires<[UseSSE2]>;
5004*9880d681SAndroid Build Coastguard Worker} // ExeDomain, SchedRW
5005*9880d681SAndroid Build Coastguard Worker
5006*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedInt, isCodeGenOnly = 1, SchedRW = [WriteVecLogicLd] in {
5007*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in
5008*9880d681SAndroid Build Coastguard Workerdef VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5009*9880d681SAndroid Build Coastguard Worker                        "vmovq\t{$src, $dst|$dst, $src}",
5010*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2i64 (X86vzmovl
5011*9880d681SAndroid Build Coastguard Worker                                             (loadv2i64 addr:$src))))],
5012*9880d681SAndroid Build Coastguard Worker                                             IIC_SSE_MOVDQ>,
5013*9880d681SAndroid Build Coastguard Worker                      XS, VEX, Requires<[UseAVX]>;
5014*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {
5015*9880d681SAndroid Build Coastguard Workerdef MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5016*9880d681SAndroid Build Coastguard Worker                        "movq\t{$src, $dst|$dst, $src}",
5017*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2i64 (X86vzmovl
5018*9880d681SAndroid Build Coastguard Worker                                             (loadv2i64 addr:$src))))],
5019*9880d681SAndroid Build Coastguard Worker                                             IIC_SSE_MOVDQ>,
5020*9880d681SAndroid Build Coastguard Worker                      XS, Requires<[UseSSE2]>;
5021*9880d681SAndroid Build Coastguard Worker}
5022*9880d681SAndroid Build Coastguard Worker} // ExeDomain, isCodeGenOnly, SchedRW
5023*9880d681SAndroid Build Coastguard Worker
5024*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 20 in {
5025*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in {
5026*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5027*9880d681SAndroid Build Coastguard Worker              (VMOVZPQILo2PQIrr VR128:$src)>;
5028*9880d681SAndroid Build Coastguard Worker  }
5029*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseSSE2] in {
5030*9880d681SAndroid Build Coastguard Worker    def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5031*9880d681SAndroid Build Coastguard Worker              (MOVZPQILo2PQIrr VR128:$src)>;
5032*9880d681SAndroid Build Coastguard Worker  }
5033*9880d681SAndroid Build Coastguard Worker}
5034*9880d681SAndroid Build Coastguard Worker
5035*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5036*9880d681SAndroid Build Coastguard Worker// SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
5037*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5038*9880d681SAndroid Build Coastguard Workermulticlass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
5039*9880d681SAndroid Build Coastguard Worker                              ValueType vt, RegisterClass RC, PatFrag mem_frag,
5040*9880d681SAndroid Build Coastguard Worker                              X86MemOperand x86memop> {
5041*9880d681SAndroid Build Coastguard Workerdef rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
5042*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5043*9880d681SAndroid Build Coastguard Worker                      [(set RC:$dst, (vt (OpNode RC:$src)))],
5044*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5045*9880d681SAndroid Build Coastguard Workerdef rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
5046*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5047*9880d681SAndroid Build Coastguard Worker                      [(set RC:$dst, (OpNode (mem_frag addr:$src)))],
5048*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5049*9880d681SAndroid Build Coastguard Worker}
5050*9880d681SAndroid Build Coastguard Worker
5051*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
5052*9880d681SAndroid Build Coastguard Worker  defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5053*9880d681SAndroid Build Coastguard Worker                                       v4f32, VR128, loadv4f32, f128mem>, VEX;
5054*9880d681SAndroid Build Coastguard Worker  defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5055*9880d681SAndroid Build Coastguard Worker                                       v4f32, VR128, loadv4f32, f128mem>, VEX;
5056*9880d681SAndroid Build Coastguard Worker  defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5057*9880d681SAndroid Build Coastguard Worker                                 v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5058*9880d681SAndroid Build Coastguard Worker  defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5059*9880d681SAndroid Build Coastguard Worker                                 v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5060*9880d681SAndroid Build Coastguard Worker}
5061*9880d681SAndroid Build Coastguard Workerdefm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
5062*9880d681SAndroid Build Coastguard Worker                                   memopv4f32, f128mem>;
5063*9880d681SAndroid Build Coastguard Workerdefm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
5064*9880d681SAndroid Build Coastguard Worker                                   memopv4f32, f128mem>;
5065*9880d681SAndroid Build Coastguard Worker
5066*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
5067*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5068*9880d681SAndroid Build Coastguard Worker            (VMOVSHDUPrr VR128:$src)>;
5069*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
5070*9880d681SAndroid Build Coastguard Worker            (VMOVSHDUPrm addr:$src)>;
5071*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5072*9880d681SAndroid Build Coastguard Worker            (VMOVSLDUPrr VR128:$src)>;
5073*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
5074*9880d681SAndroid Build Coastguard Worker            (VMOVSLDUPrm addr:$src)>;
5075*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Movshdup VR256:$src)),
5076*9880d681SAndroid Build Coastguard Worker            (VMOVSHDUPYrr VR256:$src)>;
5077*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
5078*9880d681SAndroid Build Coastguard Worker            (VMOVSHDUPYrm addr:$src)>;
5079*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Movsldup VR256:$src)),
5080*9880d681SAndroid Build Coastguard Worker            (VMOVSLDUPYrr VR256:$src)>;
5081*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
5082*9880d681SAndroid Build Coastguard Worker            (VMOVSLDUPYrm addr:$src)>;
5083*9880d681SAndroid Build Coastguard Worker}
5084*9880d681SAndroid Build Coastguard Worker
5085*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE3] in {
5086*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5087*9880d681SAndroid Build Coastguard Worker            (MOVSHDUPrr VR128:$src)>;
5088*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5089*9880d681SAndroid Build Coastguard Worker            (MOVSHDUPrm addr:$src)>;
5090*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5091*9880d681SAndroid Build Coastguard Worker            (MOVSLDUPrr VR128:$src)>;
5092*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5093*9880d681SAndroid Build Coastguard Worker            (MOVSLDUPrm addr:$src)>;
5094*9880d681SAndroid Build Coastguard Worker}
5095*9880d681SAndroid Build Coastguard Worker
5096*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5097*9880d681SAndroid Build Coastguard Worker// SSE3 - Replicate Double FP - MOVDDUP
5098*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5099*9880d681SAndroid Build Coastguard Worker
5100*9880d681SAndroid Build Coastguard Workermulticlass sse3_replicate_dfp<string OpcodeStr> {
5101*9880d681SAndroid Build Coastguard Workerdef rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5102*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5103*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (v2f64 (X86Movddup VR128:$src)))],
5104*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5105*9880d681SAndroid Build Coastguard Workerdef rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5106*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5107*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
5108*9880d681SAndroid Build Coastguard Worker                      (v2f64 (X86Movddup
5109*9880d681SAndroid Build Coastguard Worker                              (scalar_to_vector (loadf64 addr:$src)))))],
5110*9880d681SAndroid Build Coastguard Worker                              IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5111*9880d681SAndroid Build Coastguard Worker}
5112*9880d681SAndroid Build Coastguard Worker
5113*9880d681SAndroid Build Coastguard Worker// FIXME: Merge with above classe when there're patterns for the ymm version
5114*9880d681SAndroid Build Coastguard Workermulticlass sse3_replicate_dfp_y<string OpcodeStr> {
5115*9880d681SAndroid Build Coastguard Workerdef rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5116*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5117*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
5118*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteFShuffle]>;
5119*9880d681SAndroid Build Coastguard Workerdef rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5120*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5121*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst,
5122*9880d681SAndroid Build Coastguard Worker                      (v4f64 (X86Movddup (loadv4f64 addr:$src))))]>,
5123*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteLoad]>;
5124*9880d681SAndroid Build Coastguard Worker}
5125*9880d681SAndroid Build Coastguard Worker
5126*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
5127*9880d681SAndroid Build Coastguard Worker  defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
5128*9880d681SAndroid Build Coastguard Worker  defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX, VEX_L;
5129*9880d681SAndroid Build Coastguard Worker}
5130*9880d681SAndroid Build Coastguard Worker
5131*9880d681SAndroid Build Coastguard Workerdefm MOVDDUP : sse3_replicate_dfp<"movddup">;
5132*9880d681SAndroid Build Coastguard Worker
5133*9880d681SAndroid Build Coastguard Worker
5134*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
5135*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (loadv2f64 addr:$src)),
5136*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5137*9880d681SAndroid Build Coastguard Worker
5138*9880d681SAndroid Build Coastguard Worker  // 256-bit version
5139*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (loadv4i64 addr:$src)),
5140*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPYrm addr:$src)>;
5141*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (v4i64 VR256:$src)),
5142*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPYrr VR256:$src)>;
5143*9880d681SAndroid Build Coastguard Worker}
5144*9880d681SAndroid Build Coastguard Worker
5145*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5146*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64 (loadv4f32 addr:$src))),
5147*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5148*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64 (loadv2i64 addr:$src))),
5149*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5150*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64
5151*9880d681SAndroid Build Coastguard Worker                             (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5152*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5153*9880d681SAndroid Build Coastguard Worker}
5154*9880d681SAndroid Build Coastguard Worker
5155*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX, OptForSize] in {
5156*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
5157*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>;
5158*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
5159*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrm addr:$src)>;
5160*9880d681SAndroid Build Coastguard Worker}
5161*9880d681SAndroid Build Coastguard Worker
5162*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE3] in {
5163*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5164*9880d681SAndroid Build Coastguard Worker            (MOVDDUPrm addr:$src)>;
5165*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5166*9880d681SAndroid Build Coastguard Worker            (MOVDDUPrm addr:$src)>;
5167*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5168*9880d681SAndroid Build Coastguard Worker            (MOVDDUPrm addr:$src)>;
5169*9880d681SAndroid Build Coastguard Worker  def : Pat<(X86Movddup (bc_v2f64
5170*9880d681SAndroid Build Coastguard Worker                             (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5171*9880d681SAndroid Build Coastguard Worker            (MOVDDUPrm addr:$src)>;
5172*9880d681SAndroid Build Coastguard Worker}
5173*9880d681SAndroid Build Coastguard Worker
5174*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5175*9880d681SAndroid Build Coastguard Worker// SSE3 - Move Unaligned Integer
5176*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5177*9880d681SAndroid Build Coastguard Worker
5178*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteLoad] in {
5179*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5180*9880d681SAndroid Build Coastguard Worker  def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5181*9880d681SAndroid Build Coastguard Worker                   "vlddqu\t{$src, $dst|$dst, $src}",
5182*9880d681SAndroid Build Coastguard Worker                   [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5183*9880d681SAndroid Build Coastguard Worker  def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5184*9880d681SAndroid Build Coastguard Worker                   "vlddqu\t{$src, $dst|$dst, $src}",
5185*9880d681SAndroid Build Coastguard Worker                   [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
5186*9880d681SAndroid Build Coastguard Worker                   VEX, VEX_L;
5187*9880d681SAndroid Build Coastguard Worker}
5188*9880d681SAndroid Build Coastguard Workerdef LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5189*9880d681SAndroid Build Coastguard Worker                   "lddqu\t{$src, $dst|$dst, $src}",
5190*9880d681SAndroid Build Coastguard Worker                   [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))],
5191*9880d681SAndroid Build Coastguard Worker                   IIC_SSE_LDDQU>;
5192*9880d681SAndroid Build Coastguard Worker}
5193*9880d681SAndroid Build Coastguard Worker
5194*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5195*9880d681SAndroid Build Coastguard Worker// SSE3 - Arithmetic
5196*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5197*9880d681SAndroid Build Coastguard Worker
5198*9880d681SAndroid Build Coastguard Workermulticlass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5199*9880d681SAndroid Build Coastguard Worker                       X86MemOperand x86memop, OpndItins itins,
5200*9880d681SAndroid Build Coastguard Worker                       PatFrag ld_frag, bit Is2Addr = 1> {
5201*9880d681SAndroid Build Coastguard Worker  def rr : I<0xD0, MRMSrcReg,
5202*9880d681SAndroid Build Coastguard Worker       (outs RC:$dst), (ins RC:$src1, RC:$src2),
5203*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5204*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5205*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5206*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (Int RC:$src1, RC:$src2))], itins.rr>,
5207*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
5208*9880d681SAndroid Build Coastguard Worker  def rm : I<0xD0, MRMSrcMem,
5209*9880d681SAndroid Build Coastguard Worker       (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5210*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5211*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5212*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5213*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))], itins.rr>,
5214*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
5215*9880d681SAndroid Build Coastguard Worker}
5216*9880d681SAndroid Build Coastguard Worker
5217*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5218*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in {
5219*9880d681SAndroid Build Coastguard Worker    defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5220*9880d681SAndroid Build Coastguard Worker                               f128mem, SSE_ALU_F32P, loadv4f32, 0>, XD, VEX_4V;
5221*9880d681SAndroid Build Coastguard Worker    defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5222*9880d681SAndroid Build Coastguard Worker                        f256mem, SSE_ALU_F32P, loadv8f32, 0>, XD, VEX_4V, VEX_L;
5223*9880d681SAndroid Build Coastguard Worker  }
5224*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in {
5225*9880d681SAndroid Build Coastguard Worker    defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5226*9880d681SAndroid Build Coastguard Worker                               f128mem, SSE_ALU_F64P, loadv2f64, 0>, PD, VEX_4V;
5227*9880d681SAndroid Build Coastguard Worker    defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5228*9880d681SAndroid Build Coastguard Worker                        f256mem, SSE_ALU_F64P, loadv4f64, 0>, PD, VEX_4V, VEX_L;
5229*9880d681SAndroid Build Coastguard Worker  }
5230*9880d681SAndroid Build Coastguard Worker}
5231*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
5232*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in
5233*9880d681SAndroid Build Coastguard Worker  defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5234*9880d681SAndroid Build Coastguard Worker                              f128mem, SSE_ALU_F32P, memopv4f32>, XD;
5235*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in
5236*9880d681SAndroid Build Coastguard Worker  defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5237*9880d681SAndroid Build Coastguard Worker                              f128mem, SSE_ALU_F64P, memopv2f64>, PD;
5238*9880d681SAndroid Build Coastguard Worker}
5239*9880d681SAndroid Build Coastguard Worker
5240*9880d681SAndroid Build Coastguard Worker// Patterns used to select 'addsub' instructions.
5241*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5242*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5243*9880d681SAndroid Build Coastguard Worker            (VADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5244*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (loadv4f32 addr:$rhs))),
5245*9880d681SAndroid Build Coastguard Worker            (VADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5246*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5247*9880d681SAndroid Build Coastguard Worker            (VADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5248*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (loadv2f64 addr:$rhs))),
5249*9880d681SAndroid Build Coastguard Worker            (VADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5250*9880d681SAndroid Build Coastguard Worker
5251*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 VR256:$rhs))),
5252*9880d681SAndroid Build Coastguard Worker            (VADDSUBPSYrr VR256:$lhs, VR256:$rhs)>;
5253*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (loadv8f32 addr:$rhs))),
5254*9880d681SAndroid Build Coastguard Worker            (VADDSUBPSYrm VR256:$lhs, f256mem:$rhs)>;
5255*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 VR256:$rhs))),
5256*9880d681SAndroid Build Coastguard Worker            (VADDSUBPDYrr VR256:$lhs, VR256:$rhs)>;
5257*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (loadv4f64 addr:$rhs))),
5258*9880d681SAndroid Build Coastguard Worker            (VADDSUBPDYrm VR256:$lhs, f256mem:$rhs)>;
5259*9880d681SAndroid Build Coastguard Worker}
5260*9880d681SAndroid Build Coastguard Worker
5261*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE3] in {
5262*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5263*9880d681SAndroid Build Coastguard Worker            (ADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5264*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (memopv4f32 addr:$rhs))),
5265*9880d681SAndroid Build Coastguard Worker            (ADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5266*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5267*9880d681SAndroid Build Coastguard Worker            (ADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5268*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (memopv2f64 addr:$rhs))),
5269*9880d681SAndroid Build Coastguard Worker            (ADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5270*9880d681SAndroid Build Coastguard Worker}
5271*9880d681SAndroid Build Coastguard Worker
5272*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5273*9880d681SAndroid Build Coastguard Worker// SSE3 Instructions
5274*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5275*9880d681SAndroid Build Coastguard Worker
5276*9880d681SAndroid Build Coastguard Worker// Horizontal ops
5277*9880d681SAndroid Build Coastguard Workermulticlass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5278*9880d681SAndroid Build Coastguard Worker                   X86MemOperand x86memop, SDNode OpNode, PatFrag ld_frag,
5279*9880d681SAndroid Build Coastguard Worker                   bit Is2Addr = 1> {
5280*9880d681SAndroid Build Coastguard Worker  def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5281*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5282*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5283*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5284*9880d681SAndroid Build Coastguard Worker      [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5285*9880d681SAndroid Build Coastguard Worker      Sched<[WriteFAdd]>;
5286*9880d681SAndroid Build Coastguard Worker
5287*9880d681SAndroid Build Coastguard Worker  def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5288*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5289*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5290*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5291*9880d681SAndroid Build Coastguard Worker      [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))],
5292*9880d681SAndroid Build Coastguard Worker        IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5293*9880d681SAndroid Build Coastguard Worker}
5294*9880d681SAndroid Build Coastguard Workermulticlass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5295*9880d681SAndroid Build Coastguard Worker                  X86MemOperand x86memop, SDNode OpNode, PatFrag ld_frag,
5296*9880d681SAndroid Build Coastguard Worker                  bit Is2Addr = 1> {
5297*9880d681SAndroid Build Coastguard Worker  def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5298*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5299*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5300*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5301*9880d681SAndroid Build Coastguard Worker      [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5302*9880d681SAndroid Build Coastguard Worker      Sched<[WriteFAdd]>;
5303*9880d681SAndroid Build Coastguard Worker
5304*9880d681SAndroid Build Coastguard Worker  def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5305*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5306*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5307*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5308*9880d681SAndroid Build Coastguard Worker      [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))],
5309*9880d681SAndroid Build Coastguard Worker        IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5310*9880d681SAndroid Build Coastguard Worker}
5311*9880d681SAndroid Build Coastguard Worker
5312*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5313*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in {
5314*9880d681SAndroid Build Coastguard Worker    defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5315*9880d681SAndroid Build Coastguard Worker                            X86fhadd, loadv4f32, 0>, VEX_4V;
5316*9880d681SAndroid Build Coastguard Worker    defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5317*9880d681SAndroid Build Coastguard Worker                            X86fhsub, loadv4f32, 0>, VEX_4V;
5318*9880d681SAndroid Build Coastguard Worker    defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5319*9880d681SAndroid Build Coastguard Worker                            X86fhadd, loadv8f32, 0>, VEX_4V, VEX_L;
5320*9880d681SAndroid Build Coastguard Worker    defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5321*9880d681SAndroid Build Coastguard Worker                            X86fhsub, loadv8f32, 0>, VEX_4V, VEX_L;
5322*9880d681SAndroid Build Coastguard Worker  }
5323*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in {
5324*9880d681SAndroid Build Coastguard Worker    defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5325*9880d681SAndroid Build Coastguard Worker                            X86fhadd, loadv2f64, 0>, VEX_4V;
5326*9880d681SAndroid Build Coastguard Worker    defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5327*9880d681SAndroid Build Coastguard Worker                            X86fhsub, loadv2f64, 0>, VEX_4V;
5328*9880d681SAndroid Build Coastguard Worker    defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5329*9880d681SAndroid Build Coastguard Worker                            X86fhadd, loadv4f64, 0>, VEX_4V, VEX_L;
5330*9880d681SAndroid Build Coastguard Worker    defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5331*9880d681SAndroid Build Coastguard Worker                            X86fhsub, loadv4f64, 0>, VEX_4V, VEX_L;
5332*9880d681SAndroid Build Coastguard Worker  }
5333*9880d681SAndroid Build Coastguard Worker}
5334*9880d681SAndroid Build Coastguard Worker
5335*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
5336*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in {
5337*9880d681SAndroid Build Coastguard Worker    defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd,
5338*9880d681SAndroid Build Coastguard Worker                          memopv4f32>;
5339*9880d681SAndroid Build Coastguard Worker    defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub,
5340*9880d681SAndroid Build Coastguard Worker                          memopv4f32>;
5341*9880d681SAndroid Build Coastguard Worker  }
5342*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in {
5343*9880d681SAndroid Build Coastguard Worker    defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd,
5344*9880d681SAndroid Build Coastguard Worker                         memopv2f64>;
5345*9880d681SAndroid Build Coastguard Worker    defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub,
5346*9880d681SAndroid Build Coastguard Worker                         memopv2f64>;
5347*9880d681SAndroid Build Coastguard Worker  }
5348*9880d681SAndroid Build Coastguard Worker}
5349*9880d681SAndroid Build Coastguard Worker
5350*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5351*9880d681SAndroid Build Coastguard Worker// SSSE3 - Packed Absolute Instructions
5352*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5353*9880d681SAndroid Build Coastguard Worker
5354*9880d681SAndroid Build Coastguard Worker
5355*9880d681SAndroid Build Coastguard Worker/// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5356*9880d681SAndroid Build Coastguard Workermulticlass SS3I_unop_rm<bits<8> opc, string OpcodeStr, ValueType vt,
5357*9880d681SAndroid Build Coastguard Worker                        SDNode OpNode, PatFrag ld_frag> {
5358*9880d681SAndroid Build Coastguard Worker  def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5359*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src),
5360*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5361*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (vt (OpNode VR128:$src)))],
5362*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_PABS_RR>, Sched<[WriteVecALU]>;
5363*9880d681SAndroid Build Coastguard Worker
5364*9880d681SAndroid Build Coastguard Worker  def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5365*9880d681SAndroid Build Coastguard Worker                    (ins i128mem:$src),
5366*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5367*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
5368*9880d681SAndroid Build Coastguard Worker                      (vt (OpNode (bitconvert (ld_frag addr:$src)))))],
5369*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_PABS_RM>, Sched<[WriteVecALULd]>;
5370*9880d681SAndroid Build Coastguard Worker}
5371*9880d681SAndroid Build Coastguard Worker
5372*9880d681SAndroid Build Coastguard Worker/// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5373*9880d681SAndroid Build Coastguard Workermulticlass SS3I_unop_rm_y<bits<8> opc, string OpcodeStr, ValueType vt,
5374*9880d681SAndroid Build Coastguard Worker                          SDNode OpNode> {
5375*9880d681SAndroid Build Coastguard Worker  def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5376*9880d681SAndroid Build Coastguard Worker                    (ins VR256:$src),
5377*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5378*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst, (vt (OpNode VR256:$src)))]>,
5379*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteVecALU]>;
5380*9880d681SAndroid Build Coastguard Worker
5381*9880d681SAndroid Build Coastguard Worker  def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5382*9880d681SAndroid Build Coastguard Worker                    (ins i256mem:$src),
5383*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5384*9880d681SAndroid Build Coastguard Worker                    [(set VR256:$dst,
5385*9880d681SAndroid Build Coastguard Worker                      (vt (OpNode (bitconvert (loadv4i64 addr:$src)))))]>,
5386*9880d681SAndroid Build Coastguard Worker                    Sched<[WriteVecALULd]>;
5387*9880d681SAndroid Build Coastguard Worker}
5388*9880d681SAndroid Build Coastguard Worker
5389*9880d681SAndroid Build Coastguard Worker// Helper fragments to match sext vXi1 to vXiY.
5390*9880d681SAndroid Build Coastguard Workerdef v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
5391*9880d681SAndroid Build Coastguard Worker                                               VR128:$src))>;
5392*9880d681SAndroid Build Coastguard Workerdef v8i1sextv8i16  : PatLeaf<(v8i16 (X86vsrai VR128:$src, (i8 15)))>;
5393*9880d681SAndroid Build Coastguard Workerdef v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128:$src, (i8 31)))>;
5394*9880d681SAndroid Build Coastguard Workerdef v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
5395*9880d681SAndroid Build Coastguard Worker                                               VR256:$src))>;
5396*9880d681SAndroid Build Coastguard Workerdef v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256:$src, (i8 15)))>;
5397*9880d681SAndroid Build Coastguard Workerdef v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256:$src, (i8 31)))>;
5398*9880d681SAndroid Build Coastguard Worker
5399*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5400*9880d681SAndroid Build Coastguard Worker  defm VPABSB  : SS3I_unop_rm<0x1C, "vpabsb", v16i8, X86Abs, loadv2i64>, VEX;
5401*9880d681SAndroid Build Coastguard Worker  defm VPABSW  : SS3I_unop_rm<0x1D, "vpabsw", v8i16, X86Abs, loadv2i64>, VEX;
5402*9880d681SAndroid Build Coastguard Worker}
5403*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
5404*9880d681SAndroid Build Coastguard Worker  defm VPABSD  : SS3I_unop_rm<0x1E, "vpabsd", v4i32, X86Abs, loadv2i64>, VEX;
5405*9880d681SAndroid Build Coastguard Worker}
5406*9880d681SAndroid Build Coastguard Worker
5407*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
5408*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5409*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v16i1sextv16i8)),
5410*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5411*9880d681SAndroid Build Coastguard Worker            (VPABSBrr128 VR128:$src)>;
5412*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5413*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v8i1sextv8i16)),
5414*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5415*9880d681SAndroid Build Coastguard Worker            (VPABSWrr128 VR128:$src)>;
5416*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5417*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v4i1sextv4i32)),
5418*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5419*9880d681SAndroid Build Coastguard Worker            (VPABSDrr128 VR128:$src)>;
5420*9880d681SAndroid Build Coastguard Worker}
5421*9880d681SAndroid Build Coastguard Worker
5422*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
5423*9880d681SAndroid Build Coastguard Worker  defm VPABSB  : SS3I_unop_rm_y<0x1C, "vpabsb", v32i8, X86Abs>, VEX, VEX_L;
5424*9880d681SAndroid Build Coastguard Worker  defm VPABSW  : SS3I_unop_rm_y<0x1D, "vpabsw", v16i16, X86Abs>, VEX, VEX_L;
5425*9880d681SAndroid Build Coastguard Worker}
5426*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
5427*9880d681SAndroid Build Coastguard Worker  defm VPABSD  : SS3I_unop_rm_y<0x1E, "vpabsd", v8i32, X86Abs>, VEX, VEX_L;
5428*9880d681SAndroid Build Coastguard Worker}
5429*9880d681SAndroid Build Coastguard Worker
5430*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
5431*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5432*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (v32i1sextv32i8)),
5433*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (add (v32i8 VR256:$src), (v32i1sextv32i8)))),
5434*9880d681SAndroid Build Coastguard Worker            (VPABSBrr256 VR256:$src)>;
5435*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5436*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (v16i1sextv16i16)),
5437*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (add (v16i16 VR256:$src), (v16i1sextv16i16)))),
5438*9880d681SAndroid Build Coastguard Worker            (VPABSWrr256 VR256:$src)>;
5439*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5440*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (v8i1sextv8i32)),
5441*9880d681SAndroid Build Coastguard Worker            (bc_v4i64 (add (v8i32 VR256:$src), (v8i1sextv8i32)))),
5442*9880d681SAndroid Build Coastguard Worker            (VPABSDrr256 VR256:$src)>;
5443*9880d681SAndroid Build Coastguard Worker}
5444*9880d681SAndroid Build Coastguard Worker
5445*9880d681SAndroid Build Coastguard Workerdefm PABSB : SS3I_unop_rm<0x1C, "pabsb", v16i8, X86Abs, memopv2i64>;
5446*9880d681SAndroid Build Coastguard Workerdefm PABSW : SS3I_unop_rm<0x1D, "pabsw", v8i16, X86Abs, memopv2i64>;
5447*9880d681SAndroid Build Coastguard Workerdefm PABSD : SS3I_unop_rm<0x1E, "pabsd", v4i32, X86Abs, memopv2i64>;
5448*9880d681SAndroid Build Coastguard Worker
5449*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSSE3] in {
5450*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5451*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v16i1sextv16i8)),
5452*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5453*9880d681SAndroid Build Coastguard Worker            (PABSBrr128 VR128:$src)>;
5454*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5455*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v8i1sextv8i16)),
5456*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5457*9880d681SAndroid Build Coastguard Worker            (PABSWrr128 VR128:$src)>;
5458*9880d681SAndroid Build Coastguard Worker  def : Pat<(xor
5459*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (v4i1sextv4i32)),
5460*9880d681SAndroid Build Coastguard Worker            (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5461*9880d681SAndroid Build Coastguard Worker            (PABSDrr128 VR128:$src)>;
5462*9880d681SAndroid Build Coastguard Worker}
5463*9880d681SAndroid Build Coastguard Worker
5464*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5465*9880d681SAndroid Build Coastguard Worker// SSSE3 - Packed Binary Operator Instructions
5466*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5467*9880d681SAndroid Build Coastguard Worker
5468*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecALU in {
5469*9880d681SAndroid Build Coastguard Workerdef SSE_PHADDSUBD : OpndItins<
5470*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PHADDSUBD_RR, IIC_SSE_PHADDSUBD_RM
5471*9880d681SAndroid Build Coastguard Worker>;
5472*9880d681SAndroid Build Coastguard Workerdef SSE_PHADDSUBSW : OpndItins<
5473*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PHADDSUBSW_RR, IIC_SSE_PHADDSUBSW_RM
5474*9880d681SAndroid Build Coastguard Worker>;
5475*9880d681SAndroid Build Coastguard Workerdef SSE_PHADDSUBW : OpndItins<
5476*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PHADDSUBW_RR, IIC_SSE_PHADDSUBW_RM
5477*9880d681SAndroid Build Coastguard Worker>;
5478*9880d681SAndroid Build Coastguard Worker}
5479*9880d681SAndroid Build Coastguard Workerlet Sched = WriteShuffle in
5480*9880d681SAndroid Build Coastguard Workerdef SSE_PSHUFB : OpndItins<
5481*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PSHUFB_RR, IIC_SSE_PSHUFB_RM
5482*9880d681SAndroid Build Coastguard Worker>;
5483*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecALU in
5484*9880d681SAndroid Build Coastguard Workerdef SSE_PSIGN : OpndItins<
5485*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PSIGN_RR, IIC_SSE_PSIGN_RM
5486*9880d681SAndroid Build Coastguard Worker>;
5487*9880d681SAndroid Build Coastguard Workerlet Sched = WriteVecIMul in
5488*9880d681SAndroid Build Coastguard Workerdef SSE_PMULHRSW : OpndItins<
5489*9880d681SAndroid Build Coastguard Worker  IIC_SSE_PMULHRSW, IIC_SSE_PMULHRSW
5490*9880d681SAndroid Build Coastguard Worker>;
5491*9880d681SAndroid Build Coastguard Worker
5492*9880d681SAndroid Build Coastguard Worker/// SS3I_binop_rm - Simple SSSE3 bin op
5493*9880d681SAndroid Build Coastguard Workermulticlass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5494*9880d681SAndroid Build Coastguard Worker                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5495*9880d681SAndroid Build Coastguard Worker                         X86MemOperand x86memop, OpndItins itins,
5496*9880d681SAndroid Build Coastguard Worker                         bit Is2Addr = 1> {
5497*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
5498*9880d681SAndroid Build Coastguard Worker  def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5499*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
5500*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5501*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5502*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5503*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
5504*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
5505*9880d681SAndroid Build Coastguard Worker  def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5506*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
5507*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5508*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5509*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5510*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst,
5511*9880d681SAndroid Build Coastguard Worker         (OpVT (OpNode RC:$src1,
5512*9880d681SAndroid Build Coastguard Worker          (bitconvert (memop_frag addr:$src2)))))], itins.rm>,
5513*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
5514*9880d681SAndroid Build Coastguard Worker}
5515*9880d681SAndroid Build Coastguard Worker
5516*9880d681SAndroid Build Coastguard Worker/// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5517*9880d681SAndroid Build Coastguard Workermulticlass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5518*9880d681SAndroid Build Coastguard Worker                             Intrinsic IntId128, OpndItins itins,
5519*9880d681SAndroid Build Coastguard Worker                             PatFrag ld_frag, bit Is2Addr = 1> {
5520*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
5521*9880d681SAndroid Build Coastguard Worker  def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5522*9880d681SAndroid Build Coastguard Worker       (ins VR128:$src1, VR128:$src2),
5523*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5524*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5525*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5526*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5527*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
5528*9880d681SAndroid Build Coastguard Worker  def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5529*9880d681SAndroid Build Coastguard Worker       (ins VR128:$src1, i128mem:$src2),
5530*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
5531*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5532*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5533*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst,
5534*9880d681SAndroid Build Coastguard Worker         (IntId128 VR128:$src1,
5535*9880d681SAndroid Build Coastguard Worker          (bitconvert (ld_frag addr:$src2))))]>,
5536*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
5537*9880d681SAndroid Build Coastguard Worker}
5538*9880d681SAndroid Build Coastguard Worker
5539*9880d681SAndroid Build Coastguard Workermulticlass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5540*9880d681SAndroid Build Coastguard Worker                               Intrinsic IntId256,
5541*9880d681SAndroid Build Coastguard Worker                               X86FoldableSchedWrite Sched> {
5542*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
5543*9880d681SAndroid Build Coastguard Worker  def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5544*9880d681SAndroid Build Coastguard Worker       (ins VR256:$src1, VR256:$src2),
5545*9880d681SAndroid Build Coastguard Worker       !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5546*9880d681SAndroid Build Coastguard Worker       [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5547*9880d681SAndroid Build Coastguard Worker       Sched<[Sched]>;
5548*9880d681SAndroid Build Coastguard Worker  def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5549*9880d681SAndroid Build Coastguard Worker       (ins VR256:$src1, i256mem:$src2),
5550*9880d681SAndroid Build Coastguard Worker       !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5551*9880d681SAndroid Build Coastguard Worker       [(set VR256:$dst,
5552*9880d681SAndroid Build Coastguard Worker         (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
5553*9880d681SAndroid Build Coastguard Worker       Sched<[Sched.Folded, ReadAfterLd]>;
5554*9880d681SAndroid Build Coastguard Worker}
5555*9880d681SAndroid Build Coastguard Worker
5556*9880d681SAndroid Build Coastguard Workerlet ImmT = NoImm, Predicates = [HasAVX] in {
5557*9880d681SAndroid Build Coastguard Workerlet isCommutable = 0 in {
5558*9880d681SAndroid Build Coastguard Worker  defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5559*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem,
5560*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V;
5561*9880d681SAndroid Build Coastguard Worker  defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5562*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem,
5563*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBD, 0>, VEX_4V;
5564*9880d681SAndroid Build Coastguard Worker  defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5565*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem,
5566*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V;
5567*9880d681SAndroid Build Coastguard Worker  defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5568*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem,
5569*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBD, 0>, VEX_4V;
5570*9880d681SAndroid Build Coastguard Worker  defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5571*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_psign_b_128,
5572*9880d681SAndroid Build Coastguard Worker                                      SSE_PSIGN, loadv2i64, 0>, VEX_4V;
5573*9880d681SAndroid Build Coastguard Worker  defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5574*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_psign_w_128,
5575*9880d681SAndroid Build Coastguard Worker                                      SSE_PSIGN, loadv2i64, 0>, VEX_4V;
5576*9880d681SAndroid Build Coastguard Worker  defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5577*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_psign_d_128,
5578*9880d681SAndroid Build Coastguard Worker                                      SSE_PSIGN, loadv2i64, 0>, VEX_4V;
5579*9880d681SAndroid Build Coastguard Worker  defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
5580*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem,
5581*9880d681SAndroid Build Coastguard Worker                                  SSE_PSHUFB, 0>, VEX_4V;
5582*9880d681SAndroid Build Coastguard Worker  defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5583*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_phadd_sw_128,
5584*9880d681SAndroid Build Coastguard Worker                                      SSE_PHADDSUBSW, loadv2i64, 0>, VEX_4V;
5585*9880d681SAndroid Build Coastguard Worker  defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5586*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_phsub_sw_128,
5587*9880d681SAndroid Build Coastguard Worker                                      SSE_PHADDSUBSW, loadv2i64, 0>, VEX_4V;
5588*9880d681SAndroid Build Coastguard Worker  defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5589*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_pmadd_ub_sw_128,
5590*9880d681SAndroid Build Coastguard Worker                                      SSE_PMADD, loadv2i64, 0>, VEX_4V;
5591*9880d681SAndroid Build Coastguard Worker}
5592*9880d681SAndroid Build Coastguard Workerdefm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5593*9880d681SAndroid Build Coastguard Worker                                      int_x86_ssse3_pmul_hr_sw_128,
5594*9880d681SAndroid Build Coastguard Worker                                      SSE_PMULHRSW, loadv2i64, 0>, VEX_4V;
5595*9880d681SAndroid Build Coastguard Worker}
5596*9880d681SAndroid Build Coastguard Worker
5597*9880d681SAndroid Build Coastguard Workerlet ImmT = NoImm, Predicates = [HasAVX2] in {
5598*9880d681SAndroid Build Coastguard Workerlet isCommutable = 0 in {
5599*9880d681SAndroid Build Coastguard Worker  defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5600*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem,
5601*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5602*9880d681SAndroid Build Coastguard Worker  defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5603*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem,
5604*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5605*9880d681SAndroid Build Coastguard Worker  defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5606*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem,
5607*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5608*9880d681SAndroid Build Coastguard Worker  defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5609*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem,
5610*9880d681SAndroid Build Coastguard Worker                                  SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5611*9880d681SAndroid Build Coastguard Worker  defm VPSIGNBY   : SS3I_binop_rm_int_y<0x08, "vpsignb", int_x86_avx2_psign_b,
5612*9880d681SAndroid Build Coastguard Worker                                        WriteVecALU>, VEX_4V, VEX_L;
5613*9880d681SAndroid Build Coastguard Worker  defm VPSIGNWY   : SS3I_binop_rm_int_y<0x09, "vpsignw", int_x86_avx2_psign_w,
5614*9880d681SAndroid Build Coastguard Worker                                        WriteVecALU>, VEX_4V, VEX_L;
5615*9880d681SAndroid Build Coastguard Worker  defm VPSIGNDY   : SS3I_binop_rm_int_y<0x0A, "vpsignd", int_x86_avx2_psign_d,
5616*9880d681SAndroid Build Coastguard Worker                                        WriteVecALU>, VEX_4V, VEX_L;
5617*9880d681SAndroid Build Coastguard Worker  defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
5618*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem,
5619*9880d681SAndroid Build Coastguard Worker                                  SSE_PSHUFB, 0>, VEX_4V, VEX_L;
5620*9880d681SAndroid Build Coastguard Worker  defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5621*9880d681SAndroid Build Coastguard Worker                                        int_x86_avx2_phadd_sw,
5622*9880d681SAndroid Build Coastguard Worker                                        WriteVecALU>, VEX_4V, VEX_L;
5623*9880d681SAndroid Build Coastguard Worker  defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5624*9880d681SAndroid Build Coastguard Worker                                        int_x86_avx2_phsub_sw,
5625*9880d681SAndroid Build Coastguard Worker                                        WriteVecALU>, VEX_4V, VEX_L;
5626*9880d681SAndroid Build Coastguard Worker  defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5627*9880d681SAndroid Build Coastguard Worker                                       int_x86_avx2_pmadd_ub_sw,
5628*9880d681SAndroid Build Coastguard Worker                                        WriteVecIMul>, VEX_4V, VEX_L;
5629*9880d681SAndroid Build Coastguard Worker}
5630*9880d681SAndroid Build Coastguard Workerdefm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5631*9880d681SAndroid Build Coastguard Worker                                        int_x86_avx2_pmul_hr_sw,
5632*9880d681SAndroid Build Coastguard Worker                                        WriteVecIMul>, VEX_4V, VEX_L;
5633*9880d681SAndroid Build Coastguard Worker}
5634*9880d681SAndroid Build Coastguard Worker
5635*9880d681SAndroid Build Coastguard Worker// None of these have i8 immediate fields.
5636*9880d681SAndroid Build Coastguard Workerlet ImmT = NoImm, Constraints = "$src1 = $dst" in {
5637*9880d681SAndroid Build Coastguard Workerlet isCommutable = 0 in {
5638*9880d681SAndroid Build Coastguard Worker  defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5639*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, SSE_PHADDSUBW>;
5640*9880d681SAndroid Build Coastguard Worker  defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5641*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, SSE_PHADDSUBD>;
5642*9880d681SAndroid Build Coastguard Worker  defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5643*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, SSE_PHADDSUBW>;
5644*9880d681SAndroid Build Coastguard Worker  defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5645*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, SSE_PHADDSUBD>;
5646*9880d681SAndroid Build Coastguard Worker  defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb", int_x86_ssse3_psign_b_128,
5647*9880d681SAndroid Build Coastguard Worker                                     SSE_PSIGN, memopv2i64>;
5648*9880d681SAndroid Build Coastguard Worker  defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw", int_x86_ssse3_psign_w_128,
5649*9880d681SAndroid Build Coastguard Worker                                     SSE_PSIGN, memopv2i64>;
5650*9880d681SAndroid Build Coastguard Worker  defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd", int_x86_ssse3_psign_d_128,
5651*9880d681SAndroid Build Coastguard Worker                                     SSE_PSIGN, memopv2i64>;
5652*9880d681SAndroid Build Coastguard Worker  defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
5653*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, SSE_PSHUFB>;
5654*9880d681SAndroid Build Coastguard Worker  defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5655*9880d681SAndroid Build Coastguard Worker                                     int_x86_ssse3_phadd_sw_128,
5656*9880d681SAndroid Build Coastguard Worker                                     SSE_PHADDSUBSW, memopv2i64>;
5657*9880d681SAndroid Build Coastguard Worker  defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5658*9880d681SAndroid Build Coastguard Worker                                     int_x86_ssse3_phsub_sw_128,
5659*9880d681SAndroid Build Coastguard Worker                                     SSE_PHADDSUBSW, memopv2i64>;
5660*9880d681SAndroid Build Coastguard Worker  defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5661*9880d681SAndroid Build Coastguard Worker                                     int_x86_ssse3_pmadd_ub_sw_128,
5662*9880d681SAndroid Build Coastguard Worker                                     SSE_PMADD, memopv2i64>;
5663*9880d681SAndroid Build Coastguard Worker}
5664*9880d681SAndroid Build Coastguard Workerdefm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5665*9880d681SAndroid Build Coastguard Worker                                     int_x86_ssse3_pmul_hr_sw_128,
5666*9880d681SAndroid Build Coastguard Worker                                     SSE_PMULHRSW, memopv2i64>;
5667*9880d681SAndroid Build Coastguard Worker}
5668*9880d681SAndroid Build Coastguard Worker
5669*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5670*9880d681SAndroid Build Coastguard Worker// SSSE3 - Packed Align Instruction Patterns
5671*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5672*9880d681SAndroid Build Coastguard Worker
5673*9880d681SAndroid Build Coastguard Workermulticlass ssse3_palignr<string asm, bit Is2Addr = 1> {
5674*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in {
5675*9880d681SAndroid Build Coastguard Worker  def rri : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5676*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, VR128:$src2, u8imm:$src3),
5677*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
5678*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5679*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
5680*9880d681SAndroid Build Coastguard Worker                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5681*9880d681SAndroid Build Coastguard Worker      [], IIC_SSE_PALIGNRR>, Sched<[WriteShuffle]>;
5682*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
5683*9880d681SAndroid Build Coastguard Worker  def rmi : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5684*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
5685*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
5686*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5687*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
5688*9880d681SAndroid Build Coastguard Worker                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5689*9880d681SAndroid Build Coastguard Worker      [], IIC_SSE_PALIGNRM>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5690*9880d681SAndroid Build Coastguard Worker  }
5691*9880d681SAndroid Build Coastguard Worker}
5692*9880d681SAndroid Build Coastguard Worker
5693*9880d681SAndroid Build Coastguard Workermulticlass ssse3_palignr_y<string asm, bit Is2Addr = 1> {
5694*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in {
5695*9880d681SAndroid Build Coastguard Worker  def Yrri : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5696*9880d681SAndroid Build Coastguard Worker      (ins VR256:$src1, VR256:$src2, u8imm:$src3),
5697*9880d681SAndroid Build Coastguard Worker      !strconcat(asm,
5698*9880d681SAndroid Build Coastguard Worker                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5699*9880d681SAndroid Build Coastguard Worker      []>, Sched<[WriteShuffle]>;
5700*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
5701*9880d681SAndroid Build Coastguard Worker  def Yrmi : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5702*9880d681SAndroid Build Coastguard Worker      (ins VR256:$src1, i256mem:$src2, u8imm:$src3),
5703*9880d681SAndroid Build Coastguard Worker      !strconcat(asm,
5704*9880d681SAndroid Build Coastguard Worker                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5705*9880d681SAndroid Build Coastguard Worker      []>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5706*9880d681SAndroid Build Coastguard Worker  }
5707*9880d681SAndroid Build Coastguard Worker}
5708*9880d681SAndroid Build Coastguard Worker
5709*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in
5710*9880d681SAndroid Build Coastguard Worker  defm VPALIGNR : ssse3_palignr<"vpalignr", 0>, VEX_4V;
5711*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in
5712*9880d681SAndroid Build Coastguard Worker  defm VPALIGNR : ssse3_palignr_y<"vpalignr", 0>, VEX_4V, VEX_L;
5713*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
5714*9880d681SAndroid Build Coastguard Worker  defm PALIGNR : ssse3_palignr<"palignr">;
5715*9880d681SAndroid Build Coastguard Worker
5716*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
5717*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5718*9880d681SAndroid Build Coastguard Worker          (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5719*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5720*9880d681SAndroid Build Coastguard Worker          (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5721*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5722*9880d681SAndroid Build Coastguard Worker          (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5723*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5724*9880d681SAndroid Build Coastguard Worker          (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5725*9880d681SAndroid Build Coastguard Worker}
5726*9880d681SAndroid Build Coastguard Worker
5727*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5728*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5729*9880d681SAndroid Build Coastguard Worker          (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5730*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5731*9880d681SAndroid Build Coastguard Worker          (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5732*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5733*9880d681SAndroid Build Coastguard Worker          (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5734*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5735*9880d681SAndroid Build Coastguard Worker          (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5736*9880d681SAndroid Build Coastguard Worker}
5737*9880d681SAndroid Build Coastguard Worker
5738*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSSE3] in {
5739*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5740*9880d681SAndroid Build Coastguard Worker          (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5741*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5742*9880d681SAndroid Build Coastguard Worker          (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5743*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5744*9880d681SAndroid Build Coastguard Worker          (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5745*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5746*9880d681SAndroid Build Coastguard Worker          (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5747*9880d681SAndroid Build Coastguard Worker}
5748*9880d681SAndroid Build Coastguard Worker
5749*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5750*9880d681SAndroid Build Coastguard Worker// SSSE3 - Thread synchronization
5751*9880d681SAndroid Build Coastguard Worker//===---------------------------------------------------------------------===//
5752*9880d681SAndroid Build Coastguard Worker
5753*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteSystem] in {
5754*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1 in {
5755*9880d681SAndroid Build Coastguard Workerdef MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5756*9880d681SAndroid Build Coastguard Worker                [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5757*9880d681SAndroid Build Coastguard Worker                Requires<[HasSSE3]>;
5758*9880d681SAndroid Build Coastguard Worker}
5759*9880d681SAndroid Build Coastguard Worker
5760*9880d681SAndroid Build Coastguard Workerlet Uses = [EAX, ECX, EDX] in
5761*9880d681SAndroid Build Coastguard Workerdef MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
5762*9880d681SAndroid Build Coastguard Worker                 TB, Requires<[HasSSE3]>;
5763*9880d681SAndroid Build Coastguard Worker
5764*9880d681SAndroid Build Coastguard Workerlet Uses = [ECX, EAX] in
5765*9880d681SAndroid Build Coastguard Workerdef MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
5766*9880d681SAndroid Build Coastguard Worker                [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
5767*9880d681SAndroid Build Coastguard Worker                TB, Requires<[HasSSE3]>;
5768*9880d681SAndroid Build Coastguard Worker} // SchedRW
5769*9880d681SAndroid Build Coastguard Worker
5770*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
5771*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
5772*9880d681SAndroid Build Coastguard Worker
5773*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
5774*9880d681SAndroid Build Coastguard Worker      Requires<[Not64BitMode]>;
5775*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
5776*9880d681SAndroid Build Coastguard Worker      Requires<[In64BitMode]>;
5777*9880d681SAndroid Build Coastguard Worker
5778*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
5779*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Packed Move with Sign/Zero Extend
5780*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
5781*9880d681SAndroid Build Coastguard Worker
5782*9880d681SAndroid Build Coastguard Workermulticlass SS41I_pmovx_rrrm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
5783*9880d681SAndroid Build Coastguard Worker                          RegisterClass OutRC, RegisterClass InRC,
5784*9880d681SAndroid Build Coastguard Worker                          OpndItins itins> {
5785*9880d681SAndroid Build Coastguard Worker  def rr : SS48I<opc, MRMSrcReg, (outs OutRC:$dst), (ins InRC:$src),
5786*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5787*9880d681SAndroid Build Coastguard Worker                 [], itins.rr>,
5788*9880d681SAndroid Build Coastguard Worker                 Sched<[itins.Sched]>;
5789*9880d681SAndroid Build Coastguard Worker
5790*9880d681SAndroid Build Coastguard Worker  def rm : SS48I<opc, MRMSrcMem, (outs OutRC:$dst), (ins MemOp:$src),
5791*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5792*9880d681SAndroid Build Coastguard Worker                 [],
5793*9880d681SAndroid Build Coastguard Worker                 itins.rm>, Sched<[itins.Sched.Folded]>;
5794*9880d681SAndroid Build Coastguard Worker}
5795*9880d681SAndroid Build Coastguard Worker
5796*9880d681SAndroid Build Coastguard Workermulticlass SS41I_pmovx_rm_all<bits<8> opc, string OpcodeStr,
5797*9880d681SAndroid Build Coastguard Worker                          X86MemOperand MemOp, X86MemOperand MemYOp,
5798*9880d681SAndroid Build Coastguard Worker                          OpndItins SSEItins, OpndItins AVXItins,
5799*9880d681SAndroid Build Coastguard Worker                          OpndItins AVX2Itins, Predicate prd> {
5800*9880d681SAndroid Build Coastguard Worker  defm NAME : SS41I_pmovx_rrrm<opc, OpcodeStr, MemOp, VR128, VR128, SSEItins>;
5801*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, prd] in
5802*9880d681SAndroid Build Coastguard Worker    defm V#NAME   : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemOp,
5803*9880d681SAndroid Build Coastguard Worker                                     VR128, VR128, AVXItins>, VEX;
5804*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX2, prd] in
5805*9880d681SAndroid Build Coastguard Worker    defm V#NAME#Y : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemYOp,
5806*9880d681SAndroid Build Coastguard Worker                                     VR256, VR128, AVX2Itins>, VEX, VEX_L;
5807*9880d681SAndroid Build Coastguard Worker}
5808*9880d681SAndroid Build Coastguard Worker
5809*9880d681SAndroid Build Coastguard Workermulticlass SS41I_pmovx_rm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
5810*9880d681SAndroid Build Coastguard Worker                          X86MemOperand MemYOp, Predicate prd> {
5811*9880d681SAndroid Build Coastguard Worker  defm PMOVSX#NAME : SS41I_pmovx_rm_all<opc, !strconcat("pmovsx", OpcodeStr),
5812*9880d681SAndroid Build Coastguard Worker                                        MemOp, MemYOp,
5813*9880d681SAndroid Build Coastguard Worker                                        SSE_INTALU_ITINS_SHUFF_P,
5814*9880d681SAndroid Build Coastguard Worker                                        DEFAULT_ITINS_SHUFFLESCHED,
5815*9880d681SAndroid Build Coastguard Worker                                        DEFAULT_ITINS_SHUFFLESCHED, prd>;
5816*9880d681SAndroid Build Coastguard Worker  defm PMOVZX#NAME : SS41I_pmovx_rm_all<!add(opc, 0x10),
5817*9880d681SAndroid Build Coastguard Worker                                        !strconcat("pmovzx", OpcodeStr),
5818*9880d681SAndroid Build Coastguard Worker                                        MemOp, MemYOp,
5819*9880d681SAndroid Build Coastguard Worker                                        SSE_INTALU_ITINS_SHUFF_P,
5820*9880d681SAndroid Build Coastguard Worker                                        DEFAULT_ITINS_SHUFFLESCHED,
5821*9880d681SAndroid Build Coastguard Worker                                        DEFAULT_ITINS_SHUFFLESCHED, prd>;
5822*9880d681SAndroid Build Coastguard Worker}
5823*9880d681SAndroid Build Coastguard Worker
5824*9880d681SAndroid Build Coastguard Workerdefm BW : SS41I_pmovx_rm<0x20, "bw", i64mem, i128mem, NoVLX_Or_NoBWI>;
5825*9880d681SAndroid Build Coastguard Workerdefm WD : SS41I_pmovx_rm<0x23, "wd", i64mem, i128mem, NoVLX>;
5826*9880d681SAndroid Build Coastguard Workerdefm DQ : SS41I_pmovx_rm<0x25, "dq", i64mem, i128mem, NoVLX>;
5827*9880d681SAndroid Build Coastguard Worker
5828*9880d681SAndroid Build Coastguard Workerdefm BD : SS41I_pmovx_rm<0x21, "bd", i32mem, i64mem, NoVLX>;
5829*9880d681SAndroid Build Coastguard Workerdefm WQ : SS41I_pmovx_rm<0x24, "wq", i32mem, i64mem, NoVLX>;
5830*9880d681SAndroid Build Coastguard Worker
5831*9880d681SAndroid Build Coastguard Workerdefm BQ : SS41I_pmovx_rm<0x22, "bq", i16mem, i32mem, NoVLX>;
5832*9880d681SAndroid Build Coastguard Worker
5833*9880d681SAndroid Build Coastguard Worker// AVX2 Patterns
5834*9880d681SAndroid Build Coastguard Workermulticlass SS41I_pmovx_avx2_patterns<string OpcPrefix, string ExtTy, SDNode ExtOp> {
5835*9880d681SAndroid Build Coastguard Worker  // Register-Register patterns
5836*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5837*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (ExtOp (v16i8 VR128:$src))),
5838*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrr) VR128:$src)>;
5839*9880d681SAndroid Build Coastguard Worker  }
5840*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5841*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v16i8 VR128:$src))),
5842*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrr) VR128:$src)>;
5843*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v16i8 VR128:$src))),
5844*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrr) VR128:$src)>;
5845*9880d681SAndroid Build Coastguard Worker
5846*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v8i16 VR128:$src))),
5847*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrr) VR128:$src)>;
5848*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v8i16 VR128:$src))),
5849*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrr) VR128:$src)>;
5850*9880d681SAndroid Build Coastguard Worker
5851*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v4i32 VR128:$src))),
5852*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrr) VR128:$src)>;
5853*9880d681SAndroid Build Coastguard Worker  }
5854*9880d681SAndroid Build Coastguard Worker
5855*9880d681SAndroid Build Coastguard Worker  // Simple Register-Memory patterns
5856*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5857*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5858*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5859*9880d681SAndroid Build Coastguard Worker  }
5860*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5861*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5862*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5863*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5864*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5865*9880d681SAndroid Build Coastguard Worker
5866*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5867*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5868*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5869*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5870*9880d681SAndroid Build Coastguard Worker
5871*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
5872*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5873*9880d681SAndroid Build Coastguard Worker  }
5874*9880d681SAndroid Build Coastguard Worker
5875*9880d681SAndroid Build Coastguard Worker  // AVX2 Register-Memory patterns
5876*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5877*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5878*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5879*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5880*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5881*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5882*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5883*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5884*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5885*9880d681SAndroid Build Coastguard Worker  }
5886*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5887*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5888*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5889*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5890*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5891*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5892*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5893*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5894*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5895*9880d681SAndroid Build Coastguard Worker
5896*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5897*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5898*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5899*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5900*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5901*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5902*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5903*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5904*9880d681SAndroid Build Coastguard Worker
5905*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5906*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5907*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5908*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5909*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5910*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5911*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5912*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5913*9880d681SAndroid Build Coastguard Worker
5914*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5915*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5916*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5917*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5918*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5919*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5920*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5921*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5922*9880d681SAndroid Build Coastguard Worker
5923*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5924*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5925*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
5926*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5927*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
5928*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5929*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5930*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5931*9880d681SAndroid Build Coastguard Worker  }
5932*9880d681SAndroid Build Coastguard Worker}
5933*9880d681SAndroid Build Coastguard Worker
5934*9880d681SAndroid Build Coastguard Workerdefm : SS41I_pmovx_avx2_patterns<"VPMOVSX", "s", X86vsext>;
5935*9880d681SAndroid Build Coastguard Workerdefm : SS41I_pmovx_avx2_patterns<"VPMOVZX", "z", X86vzext>;
5936*9880d681SAndroid Build Coastguard Worker
5937*9880d681SAndroid Build Coastguard Worker// SSE4.1/AVX patterns.
5938*9880d681SAndroid Build Coastguard Workermulticlass SS41I_pmovx_patterns<string OpcPrefix, string ExtTy,
5939*9880d681SAndroid Build Coastguard Worker                                SDNode ExtOp, PatFrag ExtLoad16> {
5940*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5941*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (v16i8 VR128:$src))),
5942*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrr) VR128:$src)>;
5943*9880d681SAndroid Build Coastguard Worker  }
5944*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5945*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v16i8 VR128:$src))),
5946*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrr) VR128:$src)>;
5947*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v16i8 VR128:$src))),
5948*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrr) VR128:$src)>;
5949*9880d681SAndroid Build Coastguard Worker
5950*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v8i16 VR128:$src))),
5951*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrr) VR128:$src)>;
5952*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v8i16 VR128:$src))),
5953*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrr) VR128:$src)>;
5954*9880d681SAndroid Build Coastguard Worker
5955*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v4i32 VR128:$src))),
5956*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrr) VR128:$src)>;
5957*9880d681SAndroid Build Coastguard Worker  }
5958*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5959*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5960*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5961*9880d681SAndroid Build Coastguard Worker  }
5962*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5963*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5964*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5965*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5966*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5967*9880d681SAndroid Build Coastguard Worker
5968*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5969*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5970*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5971*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5972*9880d681SAndroid Build Coastguard Worker
5973*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
5974*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5975*9880d681SAndroid Build Coastguard Worker  }
5976*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5977*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5978*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5979*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5980*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5981*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5982*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5983*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5984*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5985*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5986*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5987*9880d681SAndroid Build Coastguard Worker  }
5988*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
5989*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5990*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5991*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5992*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5993*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5994*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5995*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5996*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5997*9880d681SAndroid Build Coastguard Worker
5998*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (ExtLoad16 addr:$src)))))),
5999*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
6000*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
6001*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
6002*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
6003*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
6004*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
6005*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
6006*9880d681SAndroid Build Coastguard Worker
6007*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
6008*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
6009*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
6010*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
6011*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
6012*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
6013*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
6014*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
6015*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
6016*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
6017*9880d681SAndroid Build Coastguard Worker
6018*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
6019*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
6020*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v8i16 (vzmovl_v4i32 addr:$src)))),
6021*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
6022*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
6023*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
6024*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
6025*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
6026*9880d681SAndroid Build Coastguard Worker
6027*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
6028*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
6029*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
6030*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
6031*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
6032*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
6033*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
6034*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
6035*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
6036*9880d681SAndroid Build Coastguard Worker            (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
6037*9880d681SAndroid Build Coastguard Worker  }
6038*9880d681SAndroid Build Coastguard Worker}
6039*9880d681SAndroid Build Coastguard Worker
6040*9880d681SAndroid Build Coastguard Workerdefm : SS41I_pmovx_patterns<"VPMOVSX", "s", X86vsext, extloadi32i16>;
6041*9880d681SAndroid Build Coastguard Workerdefm : SS41I_pmovx_patterns<"VPMOVZX", "z", X86vzext, loadi16_anyext>;
6042*9880d681SAndroid Build Coastguard Worker
6043*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41] in {
6044*9880d681SAndroid Build Coastguard Worker  defm : SS41I_pmovx_patterns<"PMOVSX", "s", X86vsext, extloadi32i16>;
6045*9880d681SAndroid Build Coastguard Worker  defm : SS41I_pmovx_patterns<"PMOVZX", "z", X86vzext, loadi16_anyext>;
6046*9880d681SAndroid Build Coastguard Worker}
6047*9880d681SAndroid Build Coastguard Worker
6048*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6049*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Extract Instructions
6050*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6051*9880d681SAndroid Build Coastguard Worker
6052*9880d681SAndroid Build Coastguard Worker/// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
6053*9880d681SAndroid Build Coastguard Workermulticlass SS41I_extract8<bits<8> opc, string OpcodeStr> {
6054*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6055*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src1, u8imm:$src2),
6056*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6057*9880d681SAndroid Build Coastguard Worker                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6058*9880d681SAndroid Build Coastguard Worker                 [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
6059*9880d681SAndroid Build Coastguard Worker                                         imm:$src2))]>,
6060*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffle]>;
6061*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0, mayStore = 1,
6062*9880d681SAndroid Build Coastguard Worker      SchedRW = [WriteShuffleLd, WriteRMW] in
6063*9880d681SAndroid Build Coastguard Worker  def mr : SS4AIi8<opc, MRMDestMem, (outs),
6064*9880d681SAndroid Build Coastguard Worker                 (ins i8mem:$dst, VR128:$src1, u8imm:$src2),
6065*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6066*9880d681SAndroid Build Coastguard Worker                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6067*9880d681SAndroid Build Coastguard Worker                 [(store (i8 (trunc (assertzext (X86pextrb (v16i8 VR128:$src1),
6068*9880d681SAndroid Build Coastguard Worker                                                 imm:$src2)))), addr:$dst)]>;
6069*9880d681SAndroid Build Coastguard Worker}
6070*9880d681SAndroid Build Coastguard Worker
6071*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoBWI] in
6072*9880d681SAndroid Build Coastguard Worker  defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
6073*9880d681SAndroid Build Coastguard Worker
6074*9880d681SAndroid Build Coastguard Workerdefm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
6075*9880d681SAndroid Build Coastguard Worker
6076*9880d681SAndroid Build Coastguard Worker
6077*9880d681SAndroid Build Coastguard Worker/// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
6078*9880d681SAndroid Build Coastguard Workermulticlass SS41I_extract16<bits<8> opc, string OpcodeStr> {
6079*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
6080*9880d681SAndroid Build Coastguard Worker  def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6081*9880d681SAndroid Build Coastguard Worker                   (ins VR128:$src1, u8imm:$src2),
6082*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr,
6083*9880d681SAndroid Build Coastguard Worker                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6084*9880d681SAndroid Build Coastguard Worker                   []>, Sched<[WriteShuffle]>;
6085*9880d681SAndroid Build Coastguard Worker
6086*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0, mayStore = 1,
6087*9880d681SAndroid Build Coastguard Worker      SchedRW = [WriteShuffleLd, WriteRMW] in
6088*9880d681SAndroid Build Coastguard Worker  def mr : SS4AIi8<opc, MRMDestMem, (outs),
6089*9880d681SAndroid Build Coastguard Worker                 (ins i16mem:$dst, VR128:$src1, u8imm:$src2),
6090*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6091*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6092*9880d681SAndroid Build Coastguard Worker                 [(store (i16 (trunc (assertzext (X86pextrw (v8i16 VR128:$src1),
6093*9880d681SAndroid Build Coastguard Worker                                                  imm:$src2)))), addr:$dst)]>;
6094*9880d681SAndroid Build Coastguard Worker}
6095*9880d681SAndroid Build Coastguard Worker
6096*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoBWI] in
6097*9880d681SAndroid Build Coastguard Worker  defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
6098*9880d681SAndroid Build Coastguard Worker
6099*9880d681SAndroid Build Coastguard Workerdefm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
6100*9880d681SAndroid Build Coastguard Worker
6101*9880d681SAndroid Build Coastguard Worker
6102*9880d681SAndroid Build Coastguard Worker/// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6103*9880d681SAndroid Build Coastguard Workermulticlass SS41I_extract32<bits<8> opc, string OpcodeStr> {
6104*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6105*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src1, u8imm:$src2),
6106*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6107*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6108*9880d681SAndroid Build Coastguard Worker                 [(set GR32:$dst,
6109*9880d681SAndroid Build Coastguard Worker                  (extractelt (v4i32 VR128:$src1), imm:$src2))]>,
6110*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffle]>;
6111*9880d681SAndroid Build Coastguard Worker  let SchedRW = [WriteShuffleLd, WriteRMW] in
6112*9880d681SAndroid Build Coastguard Worker  def mr : SS4AIi8<opc, MRMDestMem, (outs),
6113*9880d681SAndroid Build Coastguard Worker                 (ins i32mem:$dst, VR128:$src1, u8imm:$src2),
6114*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6115*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6116*9880d681SAndroid Build Coastguard Worker                 [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
6117*9880d681SAndroid Build Coastguard Worker                          addr:$dst)]>;
6118*9880d681SAndroid Build Coastguard Worker}
6119*9880d681SAndroid Build Coastguard Worker
6120*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoDQI] in
6121*9880d681SAndroid Build Coastguard Worker  defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
6122*9880d681SAndroid Build Coastguard Worker
6123*9880d681SAndroid Build Coastguard Workerdefm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
6124*9880d681SAndroid Build Coastguard Worker
6125*9880d681SAndroid Build Coastguard Worker/// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6126*9880d681SAndroid Build Coastguard Workermulticlass SS41I_extract64<bits<8> opc, string OpcodeStr> {
6127*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
6128*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src1, u8imm:$src2),
6129*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6130*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6131*9880d681SAndroid Build Coastguard Worker                 [(set GR64:$dst,
6132*9880d681SAndroid Build Coastguard Worker                  (extractelt (v2i64 VR128:$src1), imm:$src2))]>,
6133*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffle]>, REX_W;
6134*9880d681SAndroid Build Coastguard Worker  let SchedRW = [WriteShuffleLd, WriteRMW] in
6135*9880d681SAndroid Build Coastguard Worker  def mr : SS4AIi8<opc, MRMDestMem, (outs),
6136*9880d681SAndroid Build Coastguard Worker                 (ins i64mem:$dst, VR128:$src1, u8imm:$src2),
6137*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6138*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6139*9880d681SAndroid Build Coastguard Worker                 [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
6140*9880d681SAndroid Build Coastguard Worker                          addr:$dst)]>, REX_W;
6141*9880d681SAndroid Build Coastguard Worker}
6142*9880d681SAndroid Build Coastguard Worker
6143*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoDQI] in
6144*9880d681SAndroid Build Coastguard Worker  defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
6145*9880d681SAndroid Build Coastguard Worker
6146*9880d681SAndroid Build Coastguard Workerdefm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
6147*9880d681SAndroid Build Coastguard Worker
6148*9880d681SAndroid Build Coastguard Worker/// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
6149*9880d681SAndroid Build Coastguard Worker/// destination
6150*9880d681SAndroid Build Coastguard Workermulticlass SS41I_extractf32<bits<8> opc, string OpcodeStr,
6151*9880d681SAndroid Build Coastguard Worker                            OpndItins itins = DEFAULT_ITINS> {
6152*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6153*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src1, u8imm:$src2),
6154*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6155*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6156*9880d681SAndroid Build Coastguard Worker                 [(set GR32orGR64:$dst,
6157*9880d681SAndroid Build Coastguard Worker                    (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))],
6158*9880d681SAndroid Build Coastguard Worker                    itins.rr>, Sched<[WriteFBlend]>;
6159*9880d681SAndroid Build Coastguard Worker  let SchedRW = [WriteFBlendLd, WriteRMW] in
6160*9880d681SAndroid Build Coastguard Worker  def mr : SS4AIi8<opc, MRMDestMem, (outs),
6161*9880d681SAndroid Build Coastguard Worker                 (ins f32mem:$dst, VR128:$src1, u8imm:$src2),
6162*9880d681SAndroid Build Coastguard Worker                 !strconcat(OpcodeStr,
6163*9880d681SAndroid Build Coastguard Worker                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6164*9880d681SAndroid Build Coastguard Worker                 [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6165*9880d681SAndroid Build Coastguard Worker                          addr:$dst)], itins.rm>;
6166*9880d681SAndroid Build Coastguard Worker}
6167*9880d681SAndroid Build Coastguard Worker
6168*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
6169*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in
6170*9880d681SAndroid Build Coastguard Worker    defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
6171*9880d681SAndroid Build Coastguard Worker  defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps", SSE_EXTRACT_ITINS>;
6172*9880d681SAndroid Build Coastguard Worker}
6173*9880d681SAndroid Build Coastguard Worker
6174*9880d681SAndroid Build Coastguard Worker// Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6175*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6176*9880d681SAndroid Build Coastguard Worker                                              imm:$src2))),
6177*9880d681SAndroid Build Coastguard Worker                 addr:$dst),
6178*9880d681SAndroid Build Coastguard Worker          (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6179*9880d681SAndroid Build Coastguard Worker          Requires<[HasAVX]>;
6180*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6181*9880d681SAndroid Build Coastguard Worker                                              imm:$src2))),
6182*9880d681SAndroid Build Coastguard Worker                 addr:$dst),
6183*9880d681SAndroid Build Coastguard Worker          (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6184*9880d681SAndroid Build Coastguard Worker          Requires<[UseSSE41]>;
6185*9880d681SAndroid Build Coastguard Worker
6186*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6187*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Insert Instructions
6188*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6189*9880d681SAndroid Build Coastguard Worker
6190*9880d681SAndroid Build Coastguard Workermulticlass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6191*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6192*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, GR32orGR64:$src2, u8imm:$src3),
6193*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6194*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6195*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6196*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6197*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6198*9880d681SAndroid Build Coastguard Worker        (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
6199*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffle]>;
6200*9880d681SAndroid Build Coastguard Worker  def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6201*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, i8mem:$src2, u8imm:$src3),
6202*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6203*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6204*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6205*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6206*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6207*9880d681SAndroid Build Coastguard Worker        (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6208*9880d681SAndroid Build Coastguard Worker                   imm:$src3))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6209*9880d681SAndroid Build Coastguard Worker}
6210*9880d681SAndroid Build Coastguard Worker
6211*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoBWI] in
6212*9880d681SAndroid Build Coastguard Worker  defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6213*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
6214*9880d681SAndroid Build Coastguard Worker  defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6215*9880d681SAndroid Build Coastguard Worker
6216*9880d681SAndroid Build Coastguard Workermulticlass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6217*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6218*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, GR32:$src2, u8imm:$src3),
6219*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6220*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6221*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6222*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6223*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6224*9880d681SAndroid Build Coastguard Worker        (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6225*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffle]>;
6226*9880d681SAndroid Build Coastguard Worker  def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6227*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, i32mem:$src2, u8imm:$src3),
6228*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6229*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6230*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6231*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6232*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6233*9880d681SAndroid Build Coastguard Worker        (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6234*9880d681SAndroid Build Coastguard Worker                          imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6235*9880d681SAndroid Build Coastguard Worker}
6236*9880d681SAndroid Build Coastguard Worker
6237*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoDQI] in
6238*9880d681SAndroid Build Coastguard Worker  defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6239*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
6240*9880d681SAndroid Build Coastguard Worker  defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6241*9880d681SAndroid Build Coastguard Worker
6242*9880d681SAndroid Build Coastguard Workermulticlass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6243*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6244*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, GR64:$src2, u8imm:$src3),
6245*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6246*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6247*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6248*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6249*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6250*9880d681SAndroid Build Coastguard Worker        (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6251*9880d681SAndroid Build Coastguard Worker      Sched<[WriteShuffle]>;
6252*9880d681SAndroid Build Coastguard Worker  def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6253*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, i64mem:$src2, u8imm:$src3),
6254*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6255*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6256*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6257*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6258*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6259*9880d681SAndroid Build Coastguard Worker        (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6260*9880d681SAndroid Build Coastguard Worker                          imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6261*9880d681SAndroid Build Coastguard Worker}
6262*9880d681SAndroid Build Coastguard Worker
6263*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoDQI] in
6264*9880d681SAndroid Build Coastguard Worker  defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6265*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
6266*9880d681SAndroid Build Coastguard Worker  defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6267*9880d681SAndroid Build Coastguard Worker
6268*9880d681SAndroid Build Coastguard Worker// insertps has a few different modes, there's the first two here below which
6269*9880d681SAndroid Build Coastguard Worker// are optimized inserts that won't zero arbitrary elements in the destination
6270*9880d681SAndroid Build Coastguard Worker// vector. The next one matches the intrinsic and could zero arbitrary elements
6271*9880d681SAndroid Build Coastguard Worker// in the target vector.
6272*9880d681SAndroid Build Coastguard Workermulticlass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1,
6273*9880d681SAndroid Build Coastguard Worker                           OpndItins itins = DEFAULT_ITINS> {
6274*9880d681SAndroid Build Coastguard Worker  def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6275*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6276*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6277*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6278*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6279*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6280*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6281*9880d681SAndroid Build Coastguard Worker        (X86insertps VR128:$src1, VR128:$src2, imm:$src3))], itins.rr>,
6282*9880d681SAndroid Build Coastguard Worker      Sched<[WriteFShuffle]>;
6283*9880d681SAndroid Build Coastguard Worker  def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6284*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, f32mem:$src2, u8imm:$src3),
6285*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6286*9880d681SAndroid Build Coastguard Worker        !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6287*9880d681SAndroid Build Coastguard Worker        !strconcat(asm,
6288*9880d681SAndroid Build Coastguard Worker                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6289*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
6290*9880d681SAndroid Build Coastguard Worker        (X86insertps VR128:$src1,
6291*9880d681SAndroid Build Coastguard Worker                   (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6292*9880d681SAndroid Build Coastguard Worker                    imm:$src3))], itins.rm>,
6293*9880d681SAndroid Build Coastguard Worker      Sched<[WriteFShuffleLd, ReadAfterLd]>;
6294*9880d681SAndroid Build Coastguard Worker}
6295*9880d681SAndroid Build Coastguard Worker
6296*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
6297*9880d681SAndroid Build Coastguard Worker  let Predicates = [UseAVX] in
6298*9880d681SAndroid Build Coastguard Worker    defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6299*9880d681SAndroid Build Coastguard Worker  let Constraints = "$src1 = $dst" in
6300*9880d681SAndroid Build Coastguard Worker    defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1, SSE_INSERT_ITINS>;
6301*9880d681SAndroid Build Coastguard Worker}
6302*9880d681SAndroid Build Coastguard Worker
6303*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41] in {
6304*9880d681SAndroid Build Coastguard Worker  // If we're inserting an element from a load or a null pshuf of a load,
6305*9880d681SAndroid Build Coastguard Worker  // fold the load into the insertps instruction.
6306*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd (v4f32
6307*9880d681SAndroid Build Coastguard Worker                       (scalar_to_vector (loadf32 addr:$src2))), (i8 0)),
6308*9880d681SAndroid Build Coastguard Worker                   imm:$src3)),
6309*9880d681SAndroid Build Coastguard Worker            (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6310*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd
6311*9880d681SAndroid Build Coastguard Worker                      (loadv4f32 addr:$src2), (i8 0)), imm:$src3)),
6312*9880d681SAndroid Build Coastguard Worker            (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6313*9880d681SAndroid Build Coastguard Worker}
6314*9880d681SAndroid Build Coastguard Worker
6315*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
6316*9880d681SAndroid Build Coastguard Worker  // If we're inserting an element from a vbroadcast of a load, fold the
6317*9880d681SAndroid Build Coastguard Worker  // load into the X86insertps instruction.
6318*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6319*9880d681SAndroid Build Coastguard Worker                (X86VBroadcast (loadf32 addr:$src2)), imm:$src3)),
6320*9880d681SAndroid Build Coastguard Worker            (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6321*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6322*9880d681SAndroid Build Coastguard Worker                (X86VBroadcast (loadv4f32 addr:$src2)), imm:$src3)),
6323*9880d681SAndroid Build Coastguard Worker            (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6324*9880d681SAndroid Build Coastguard Worker}
6325*9880d681SAndroid Build Coastguard Worker
6326*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6327*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Round Instructions
6328*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6329*9880d681SAndroid Build Coastguard Worker
6330*9880d681SAndroid Build Coastguard Workermulticlass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6331*9880d681SAndroid Build Coastguard Worker                            X86MemOperand x86memop, RegisterClass RC,
6332*9880d681SAndroid Build Coastguard Worker                            PatFrag mem_frag32, PatFrag mem_frag64,
6333*9880d681SAndroid Build Coastguard Worker                            Intrinsic V4F32Int, Intrinsic V2F64Int> {
6334*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
6335*9880d681SAndroid Build Coastguard Worker  // Intrinsic operation, reg.
6336*9880d681SAndroid Build Coastguard Worker  // Vector intrinsic operation, reg
6337*9880d681SAndroid Build Coastguard Worker  def PSr : SS4AIi8<opcps, MRMSrcReg,
6338*9880d681SAndroid Build Coastguard Worker                    (outs RC:$dst), (ins RC:$src1, i32u8imm:$src2),
6339*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
6340*9880d681SAndroid Build Coastguard Worker                    "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6341*9880d681SAndroid Build Coastguard Worker                    [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))],
6342*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6343*9880d681SAndroid Build Coastguard Worker
6344*9880d681SAndroid Build Coastguard Worker  // Vector intrinsic operation, mem
6345*9880d681SAndroid Build Coastguard Worker  def PSm : SS4AIi8<opcps, MRMSrcMem,
6346*9880d681SAndroid Build Coastguard Worker                    (outs RC:$dst), (ins x86memop:$src1, i32u8imm:$src2),
6347*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
6348*9880d681SAndroid Build Coastguard Worker                    "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6349*9880d681SAndroid Build Coastguard Worker                    [(set RC:$dst,
6350*9880d681SAndroid Build Coastguard Worker                          (V4F32Int (mem_frag32 addr:$src1),imm:$src2))],
6351*9880d681SAndroid Build Coastguard Worker                          IIC_SSE_ROUNDPS_MEM>, Sched<[WriteFAddLd]>;
6352*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedSingle
6353*9880d681SAndroid Build Coastguard Worker
6354*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in {
6355*9880d681SAndroid Build Coastguard Worker  // Vector intrinsic operation, reg
6356*9880d681SAndroid Build Coastguard Worker  def PDr : SS4AIi8<opcpd, MRMSrcReg,
6357*9880d681SAndroid Build Coastguard Worker                    (outs RC:$dst), (ins RC:$src1, i32u8imm:$src2),
6358*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
6359*9880d681SAndroid Build Coastguard Worker                    "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6360*9880d681SAndroid Build Coastguard Worker                    [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))],
6361*9880d681SAndroid Build Coastguard Worker                    IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6362*9880d681SAndroid Build Coastguard Worker
6363*9880d681SAndroid Build Coastguard Worker  // Vector intrinsic operation, mem
6364*9880d681SAndroid Build Coastguard Worker  def PDm : SS4AIi8<opcpd, MRMSrcMem,
6365*9880d681SAndroid Build Coastguard Worker                    (outs RC:$dst), (ins x86memop:$src1, i32u8imm:$src2),
6366*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
6367*9880d681SAndroid Build Coastguard Worker                    "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6368*9880d681SAndroid Build Coastguard Worker                    [(set RC:$dst,
6369*9880d681SAndroid Build Coastguard Worker                          (V2F64Int (mem_frag64 addr:$src1),imm:$src2))],
6370*9880d681SAndroid Build Coastguard Worker                          IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAddLd]>;
6371*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedDouble
6372*9880d681SAndroid Build Coastguard Worker}
6373*9880d681SAndroid Build Coastguard Worker
6374*9880d681SAndroid Build Coastguard Workermulticlass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6375*9880d681SAndroid Build Coastguard Worker                            string OpcodeStr,
6376*9880d681SAndroid Build Coastguard Worker                            Intrinsic F32Int,
6377*9880d681SAndroid Build Coastguard Worker                            Intrinsic F64Int, bit Is2Addr = 1> {
6378*9880d681SAndroid Build Coastguard Workerlet ExeDomain = GenericDomain in {
6379*9880d681SAndroid Build Coastguard Worker  // Operation, reg.
6380*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in
6381*9880d681SAndroid Build Coastguard Worker  def SSr : SS4AIi8<opcss, MRMSrcReg,
6382*9880d681SAndroid Build Coastguard Worker      (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32u8imm:$src3),
6383*9880d681SAndroid Build Coastguard Worker      !if(Is2Addr,
6384*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,
6385*9880d681SAndroid Build Coastguard Worker              "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6386*9880d681SAndroid Build Coastguard Worker          !strconcat(OpcodeStr,
6387*9880d681SAndroid Build Coastguard Worker              "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6388*9880d681SAndroid Build Coastguard Worker      []>, Sched<[WriteFAdd]>;
6389*9880d681SAndroid Build Coastguard Worker
6390*9880d681SAndroid Build Coastguard Worker  // Intrinsic operation, reg.
6391*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in
6392*9880d681SAndroid Build Coastguard Worker  def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6393*9880d681SAndroid Build Coastguard Worker        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
6394*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6395*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6396*9880d681SAndroid Build Coastguard Worker                "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6397*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6398*9880d681SAndroid Build Coastguard Worker                "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6399*9880d681SAndroid Build Coastguard Worker        [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6400*9880d681SAndroid Build Coastguard Worker        Sched<[WriteFAdd]>;
6401*9880d681SAndroid Build Coastguard Worker
6402*9880d681SAndroid Build Coastguard Worker  // Intrinsic operation, mem.
6403*9880d681SAndroid Build Coastguard Worker  def SSm : SS4AIi8<opcss, MRMSrcMem,
6404*9880d681SAndroid Build Coastguard Worker        (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32u8imm:$src3),
6405*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6406*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6407*9880d681SAndroid Build Coastguard Worker                "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6408*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6409*9880d681SAndroid Build Coastguard Worker                "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6410*9880d681SAndroid Build Coastguard Worker        [(set VR128:$dst,
6411*9880d681SAndroid Build Coastguard Worker             (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6412*9880d681SAndroid Build Coastguard Worker        Sched<[WriteFAddLd, ReadAfterLd]>;
6413*9880d681SAndroid Build Coastguard Worker
6414*9880d681SAndroid Build Coastguard Worker  // Operation, reg.
6415*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in
6416*9880d681SAndroid Build Coastguard Worker  def SDr : SS4AIi8<opcsd, MRMSrcReg,
6417*9880d681SAndroid Build Coastguard Worker        (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32u8imm:$src3),
6418*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6419*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6420*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6421*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6422*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6423*9880d681SAndroid Build Coastguard Worker        []>, Sched<[WriteFAdd]>;
6424*9880d681SAndroid Build Coastguard Worker
6425*9880d681SAndroid Build Coastguard Worker  // Intrinsic operation, reg.
6426*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in
6427*9880d681SAndroid Build Coastguard Worker  def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6428*9880d681SAndroid Build Coastguard Worker        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
6429*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6430*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6431*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6432*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6433*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6434*9880d681SAndroid Build Coastguard Worker        [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6435*9880d681SAndroid Build Coastguard Worker        Sched<[WriteFAdd]>;
6436*9880d681SAndroid Build Coastguard Worker
6437*9880d681SAndroid Build Coastguard Worker  // Intrinsic operation, mem.
6438*9880d681SAndroid Build Coastguard Worker  def SDm : SS4AIi8<opcsd, MRMSrcMem,
6439*9880d681SAndroid Build Coastguard Worker        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32u8imm:$src3),
6440*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6441*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6442*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6443*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6444*9880d681SAndroid Build Coastguard Worker                "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6445*9880d681SAndroid Build Coastguard Worker        [(set VR128:$dst,
6446*9880d681SAndroid Build Coastguard Worker              (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6447*9880d681SAndroid Build Coastguard Worker        Sched<[WriteFAddLd, ReadAfterLd]>;
6448*9880d681SAndroid Build Coastguard Worker} // ExeDomain = GenericDomain
6449*9880d681SAndroid Build Coastguard Worker}
6450*9880d681SAndroid Build Coastguard Worker
6451*9880d681SAndroid Build Coastguard Worker// FP round - roundss, roundps, roundsd, roundpd
6452*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
6453*9880d681SAndroid Build Coastguard Worker  // Intrinsic form
6454*9880d681SAndroid Build Coastguard Worker  defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6455*9880d681SAndroid Build Coastguard Worker                                  loadv4f32, loadv2f64,
6456*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_round_ps,
6457*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_round_pd>, VEX;
6458*9880d681SAndroid Build Coastguard Worker  defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6459*9880d681SAndroid Build Coastguard Worker                                  loadv8f32, loadv4f64,
6460*9880d681SAndroid Build Coastguard Worker                                  int_x86_avx_round_ps_256,
6461*9880d681SAndroid Build Coastguard Worker                                  int_x86_avx_round_pd_256>, VEX, VEX_L;
6462*9880d681SAndroid Build Coastguard Worker  defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6463*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_round_ss,
6464*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6465*9880d681SAndroid Build Coastguard Worker}
6466*9880d681SAndroid Build Coastguard Worker
6467*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
6468*9880d681SAndroid Build Coastguard Worker  def : Pat<(ffloor FR32:$src),
6469*9880d681SAndroid Build Coastguard Worker            (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x9))>;
6470*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (ffloor FR64:$src)),
6471*9880d681SAndroid Build Coastguard Worker            (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x9))>;
6472*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (fnearbyint FR32:$src)),
6473*9880d681SAndroid Build Coastguard Worker            (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6474*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (fnearbyint FR64:$src)),
6475*9880d681SAndroid Build Coastguard Worker            (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6476*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (fceil FR32:$src)),
6477*9880d681SAndroid Build Coastguard Worker            (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xA))>;
6478*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (fceil FR64:$src)),
6479*9880d681SAndroid Build Coastguard Worker            (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xA))>;
6480*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (frint FR32:$src)),
6481*9880d681SAndroid Build Coastguard Worker            (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6482*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (frint FR64:$src)),
6483*9880d681SAndroid Build Coastguard Worker            (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6484*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (ftrunc FR32:$src)),
6485*9880d681SAndroid Build Coastguard Worker            (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xB))>;
6486*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (ftrunc FR64:$src)),
6487*9880d681SAndroid Build Coastguard Worker            (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xB))>;
6488*9880d681SAndroid Build Coastguard Worker}
6489*9880d681SAndroid Build Coastguard Worker
6490*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
6491*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (ffloor VR128:$src)),
6492*9880d681SAndroid Build Coastguard Worker            (VROUNDPSr VR128:$src, (i32 0x9))>;
6493*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fnearbyint VR128:$src)),
6494*9880d681SAndroid Build Coastguard Worker            (VROUNDPSr VR128:$src, (i32 0xC))>;
6495*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fceil VR128:$src)),
6496*9880d681SAndroid Build Coastguard Worker            (VROUNDPSr VR128:$src, (i32 0xA))>;
6497*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (frint VR128:$src)),
6498*9880d681SAndroid Build Coastguard Worker            (VROUNDPSr VR128:$src, (i32 0x4))>;
6499*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (ftrunc VR128:$src)),
6500*9880d681SAndroid Build Coastguard Worker            (VROUNDPSr VR128:$src, (i32 0xB))>;
6501*9880d681SAndroid Build Coastguard Worker
6502*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (ffloor VR128:$src)),
6503*9880d681SAndroid Build Coastguard Worker            (VROUNDPDr VR128:$src, (i32 0x9))>;
6504*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (fnearbyint VR128:$src)),
6505*9880d681SAndroid Build Coastguard Worker            (VROUNDPDr VR128:$src, (i32 0xC))>;
6506*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (fceil VR128:$src)),
6507*9880d681SAndroid Build Coastguard Worker            (VROUNDPDr VR128:$src, (i32 0xA))>;
6508*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (frint VR128:$src)),
6509*9880d681SAndroid Build Coastguard Worker            (VROUNDPDr VR128:$src, (i32 0x4))>;
6510*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (ftrunc VR128:$src)),
6511*9880d681SAndroid Build Coastguard Worker            (VROUNDPDr VR128:$src, (i32 0xB))>;
6512*9880d681SAndroid Build Coastguard Worker
6513*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (ffloor VR256:$src)),
6514*9880d681SAndroid Build Coastguard Worker            (VROUNDYPSr VR256:$src, (i32 0x9))>;
6515*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (fnearbyint VR256:$src)),
6516*9880d681SAndroid Build Coastguard Worker            (VROUNDYPSr VR256:$src, (i32 0xC))>;
6517*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (fceil VR256:$src)),
6518*9880d681SAndroid Build Coastguard Worker            (VROUNDYPSr VR256:$src, (i32 0xA))>;
6519*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (frint VR256:$src)),
6520*9880d681SAndroid Build Coastguard Worker            (VROUNDYPSr VR256:$src, (i32 0x4))>;
6521*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (ftrunc VR256:$src)),
6522*9880d681SAndroid Build Coastguard Worker            (VROUNDYPSr VR256:$src, (i32 0xB))>;
6523*9880d681SAndroid Build Coastguard Worker
6524*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (ffloor VR256:$src)),
6525*9880d681SAndroid Build Coastguard Worker            (VROUNDYPDr VR256:$src, (i32 0x9))>;
6526*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (fnearbyint VR256:$src)),
6527*9880d681SAndroid Build Coastguard Worker            (VROUNDYPDr VR256:$src, (i32 0xC))>;
6528*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (fceil VR256:$src)),
6529*9880d681SAndroid Build Coastguard Worker            (VROUNDYPDr VR256:$src, (i32 0xA))>;
6530*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (frint VR256:$src)),
6531*9880d681SAndroid Build Coastguard Worker            (VROUNDYPDr VR256:$src, (i32 0x4))>;
6532*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (ftrunc VR256:$src)),
6533*9880d681SAndroid Build Coastguard Worker            (VROUNDYPDr VR256:$src, (i32 0xB))>;
6534*9880d681SAndroid Build Coastguard Worker}
6535*9880d681SAndroid Build Coastguard Worker
6536*9880d681SAndroid Build Coastguard Workerdefm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6537*9880d681SAndroid Build Coastguard Worker                               memopv4f32, memopv2f64,
6538*9880d681SAndroid Build Coastguard Worker                               int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6539*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
6540*9880d681SAndroid Build Coastguard Workerdefm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6541*9880d681SAndroid Build Coastguard Worker                               int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6542*9880d681SAndroid Build Coastguard Worker
6543*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41] in {
6544*9880d681SAndroid Build Coastguard Worker  def : Pat<(ffloor FR32:$src),
6545*9880d681SAndroid Build Coastguard Worker            (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x9))>;
6546*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (ffloor FR64:$src)),
6547*9880d681SAndroid Build Coastguard Worker            (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x9))>;
6548*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (fnearbyint FR32:$src)),
6549*9880d681SAndroid Build Coastguard Worker            (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6550*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (fnearbyint FR64:$src)),
6551*9880d681SAndroid Build Coastguard Worker            (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6552*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (fceil FR32:$src)),
6553*9880d681SAndroid Build Coastguard Worker            (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xA))>;
6554*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (fceil FR64:$src)),
6555*9880d681SAndroid Build Coastguard Worker            (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xA))>;
6556*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (frint FR32:$src)),
6557*9880d681SAndroid Build Coastguard Worker            (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6558*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (frint FR64:$src)),
6559*9880d681SAndroid Build Coastguard Worker            (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6560*9880d681SAndroid Build Coastguard Worker  def : Pat<(f32 (ftrunc FR32:$src)),
6561*9880d681SAndroid Build Coastguard Worker            (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xB))>;
6562*9880d681SAndroid Build Coastguard Worker  def : Pat<(f64 (ftrunc FR64:$src)),
6563*9880d681SAndroid Build Coastguard Worker            (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xB))>;
6564*9880d681SAndroid Build Coastguard Worker
6565*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (ffloor VR128:$src)),
6566*9880d681SAndroid Build Coastguard Worker            (ROUNDPSr VR128:$src, (i32 0x9))>;
6567*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fnearbyint VR128:$src)),
6568*9880d681SAndroid Build Coastguard Worker            (ROUNDPSr VR128:$src, (i32 0xC))>;
6569*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (fceil VR128:$src)),
6570*9880d681SAndroid Build Coastguard Worker            (ROUNDPSr VR128:$src, (i32 0xA))>;
6571*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (frint VR128:$src)),
6572*9880d681SAndroid Build Coastguard Worker            (ROUNDPSr VR128:$src, (i32 0x4))>;
6573*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (ftrunc VR128:$src)),
6574*9880d681SAndroid Build Coastguard Worker            (ROUNDPSr VR128:$src, (i32 0xB))>;
6575*9880d681SAndroid Build Coastguard Worker
6576*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (ffloor VR128:$src)),
6577*9880d681SAndroid Build Coastguard Worker            (ROUNDPDr VR128:$src, (i32 0x9))>;
6578*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (fnearbyint VR128:$src)),
6579*9880d681SAndroid Build Coastguard Worker            (ROUNDPDr VR128:$src, (i32 0xC))>;
6580*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (fceil VR128:$src)),
6581*9880d681SAndroid Build Coastguard Worker            (ROUNDPDr VR128:$src, (i32 0xA))>;
6582*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (frint VR128:$src)),
6583*9880d681SAndroid Build Coastguard Worker            (ROUNDPDr VR128:$src, (i32 0x4))>;
6584*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (ftrunc VR128:$src)),
6585*9880d681SAndroid Build Coastguard Worker            (ROUNDPDr VR128:$src, (i32 0xB))>;
6586*9880d681SAndroid Build Coastguard Worker}
6587*9880d681SAndroid Build Coastguard Worker
6588*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6589*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Packed Bit Test
6590*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6591*9880d681SAndroid Build Coastguard Worker
6592*9880d681SAndroid Build Coastguard Worker// ptest instruction we'll lower to this in X86ISelLowering primarily from
6593*9880d681SAndroid Build Coastguard Worker// the intel intrinsic that corresponds to this.
6594*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], Predicates = [HasAVX] in {
6595*9880d681SAndroid Build Coastguard Workerdef VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6596*9880d681SAndroid Build Coastguard Worker                "vptest\t{$src2, $src1|$src1, $src2}",
6597*9880d681SAndroid Build Coastguard Worker                [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6598*9880d681SAndroid Build Coastguard Worker                Sched<[WriteVecLogic]>, VEX;
6599*9880d681SAndroid Build Coastguard Workerdef VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6600*9880d681SAndroid Build Coastguard Worker                "vptest\t{$src2, $src1|$src1, $src2}",
6601*9880d681SAndroid Build Coastguard Worker                [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
6602*9880d681SAndroid Build Coastguard Worker                Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
6603*9880d681SAndroid Build Coastguard Worker
6604*9880d681SAndroid Build Coastguard Workerdef VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6605*9880d681SAndroid Build Coastguard Worker                "vptest\t{$src2, $src1|$src1, $src2}",
6606*9880d681SAndroid Build Coastguard Worker                [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6607*9880d681SAndroid Build Coastguard Worker                Sched<[WriteVecLogic]>, VEX, VEX_L;
6608*9880d681SAndroid Build Coastguard Workerdef VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6609*9880d681SAndroid Build Coastguard Worker                "vptest\t{$src2, $src1|$src1, $src2}",
6610*9880d681SAndroid Build Coastguard Worker                [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
6611*9880d681SAndroid Build Coastguard Worker                Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX, VEX_L;
6612*9880d681SAndroid Build Coastguard Worker}
6613*9880d681SAndroid Build Coastguard Worker
6614*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in {
6615*9880d681SAndroid Build Coastguard Workerdef PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6616*9880d681SAndroid Build Coastguard Worker              "ptest\t{$src2, $src1|$src1, $src2}",
6617*9880d681SAndroid Build Coastguard Worker              [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6618*9880d681SAndroid Build Coastguard Worker              Sched<[WriteVecLogic]>;
6619*9880d681SAndroid Build Coastguard Workerdef PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6620*9880d681SAndroid Build Coastguard Worker              "ptest\t{$src2, $src1|$src1, $src2}",
6621*9880d681SAndroid Build Coastguard Worker              [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
6622*9880d681SAndroid Build Coastguard Worker              Sched<[WriteVecLogicLd, ReadAfterLd]>;
6623*9880d681SAndroid Build Coastguard Worker}
6624*9880d681SAndroid Build Coastguard Worker
6625*9880d681SAndroid Build Coastguard Worker// The bit test instructions below are AVX only
6626*9880d681SAndroid Build Coastguard Workermulticlass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6627*9880d681SAndroid Build Coastguard Worker                       X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6628*9880d681SAndroid Build Coastguard Worker  def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6629*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6630*9880d681SAndroid Build Coastguard Worker            [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>,
6631*9880d681SAndroid Build Coastguard Worker            Sched<[WriteVecLogic]>, VEX;
6632*9880d681SAndroid Build Coastguard Worker  def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6633*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6634*9880d681SAndroid Build Coastguard Worker            [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6635*9880d681SAndroid Build Coastguard Worker            Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
6636*9880d681SAndroid Build Coastguard Worker}
6637*9880d681SAndroid Build Coastguard Worker
6638*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], Predicates = [HasAVX] in {
6639*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
6640*9880d681SAndroid Build Coastguard Workerdefm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32>;
6641*9880d681SAndroid Build Coastguard Workerdefm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32>,
6642*9880d681SAndroid Build Coastguard Worker                            VEX_L;
6643*9880d681SAndroid Build Coastguard Worker}
6644*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in {
6645*9880d681SAndroid Build Coastguard Workerdefm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64>;
6646*9880d681SAndroid Build Coastguard Workerdefm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64>,
6647*9880d681SAndroid Build Coastguard Worker                            VEX_L;
6648*9880d681SAndroid Build Coastguard Worker}
6649*9880d681SAndroid Build Coastguard Worker}
6650*9880d681SAndroid Build Coastguard Worker
6651*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6652*9880d681SAndroid Build Coastguard Worker// SSE4.1 - Misc Instructions
6653*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
6654*9880d681SAndroid Build Coastguard Worker
6655*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6656*9880d681SAndroid Build Coastguard Worker  def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6657*9880d681SAndroid Build Coastguard Worker                     "popcnt{w}\t{$src, $dst|$dst, $src}",
6658*9880d681SAndroid Build Coastguard Worker                     [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)],
6659*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
6660*9880d681SAndroid Build Coastguard Worker                     OpSize16, XS;
6661*9880d681SAndroid Build Coastguard Worker  def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6662*9880d681SAndroid Build Coastguard Worker                     "popcnt{w}\t{$src, $dst|$dst, $src}",
6663*9880d681SAndroid Build Coastguard Worker                     [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6664*9880d681SAndroid Build Coastguard Worker                      (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6665*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteFAddLd]>, OpSize16, XS;
6666*9880d681SAndroid Build Coastguard Worker
6667*9880d681SAndroid Build Coastguard Worker  def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6668*9880d681SAndroid Build Coastguard Worker                     "popcnt{l}\t{$src, $dst|$dst, $src}",
6669*9880d681SAndroid Build Coastguard Worker                     [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)],
6670*9880d681SAndroid Build Coastguard Worker                     IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
6671*9880d681SAndroid Build Coastguard Worker                     OpSize32, XS;
6672*9880d681SAndroid Build Coastguard Worker
6673*9880d681SAndroid Build Coastguard Worker  def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6674*9880d681SAndroid Build Coastguard Worker                     "popcnt{l}\t{$src, $dst|$dst, $src}",
6675*9880d681SAndroid Build Coastguard Worker                     [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6676*9880d681SAndroid Build Coastguard Worker                      (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6677*9880d681SAndroid Build Coastguard Worker                      Sched<[WriteFAddLd]>, OpSize32, XS;
6678*9880d681SAndroid Build Coastguard Worker
6679*9880d681SAndroid Build Coastguard Worker  def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6680*9880d681SAndroid Build Coastguard Worker                      "popcnt{q}\t{$src, $dst|$dst, $src}",
6681*9880d681SAndroid Build Coastguard Worker                      [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)],
6682*9880d681SAndroid Build Coastguard Worker                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>, XS;
6683*9880d681SAndroid Build Coastguard Worker  def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6684*9880d681SAndroid Build Coastguard Worker                      "popcnt{q}\t{$src, $dst|$dst, $src}",
6685*9880d681SAndroid Build Coastguard Worker                      [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6686*9880d681SAndroid Build Coastguard Worker                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6687*9880d681SAndroid Build Coastguard Worker                       Sched<[WriteFAddLd]>, XS;
6688*9880d681SAndroid Build Coastguard Worker}
6689*9880d681SAndroid Build Coastguard Worker
6690*9880d681SAndroid Build Coastguard Worker
6691*9880d681SAndroid Build Coastguard Worker
6692*9880d681SAndroid Build Coastguard Worker// SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6693*9880d681SAndroid Build Coastguard Workermulticlass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6694*9880d681SAndroid Build Coastguard Worker                                 Intrinsic IntId128, PatFrag ld_frag,
6695*9880d681SAndroid Build Coastguard Worker                                 X86FoldableSchedWrite Sched> {
6696*9880d681SAndroid Build Coastguard Worker  def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6697*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src),
6698*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6699*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (IntId128 VR128:$src))]>,
6700*9880d681SAndroid Build Coastguard Worker                    Sched<[Sched]>;
6701*9880d681SAndroid Build Coastguard Worker  def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6702*9880d681SAndroid Build Coastguard Worker                     (ins i128mem:$src),
6703*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6704*9880d681SAndroid Build Coastguard Worker                     [(set VR128:$dst,
6705*9880d681SAndroid Build Coastguard Worker                       (IntId128 (bitconvert (ld_frag addr:$src))))]>,
6706*9880d681SAndroid Build Coastguard Worker                    Sched<[Sched.Folded]>;
6707*9880d681SAndroid Build Coastguard Worker}
6708*9880d681SAndroid Build Coastguard Worker
6709*9880d681SAndroid Build Coastguard Worker// PHMIN has the same profile as PSAD, thus we use the same scheduling
6710*9880d681SAndroid Build Coastguard Worker// model, although the naming is misleading.
6711*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in
6712*9880d681SAndroid Build Coastguard Workerdefm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6713*9880d681SAndroid Build Coastguard Worker                                         int_x86_sse41_phminposuw, loadv2i64,
6714*9880d681SAndroid Build Coastguard Worker                                         WriteVecIMul>, VEX;
6715*9880d681SAndroid Build Coastguard Workerdefm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6716*9880d681SAndroid Build Coastguard Worker                                         int_x86_sse41_phminposuw, memopv2i64,
6717*9880d681SAndroid Build Coastguard Worker                                         WriteVecIMul>;
6718*9880d681SAndroid Build Coastguard Worker
6719*9880d681SAndroid Build Coastguard Worker/// SS48I_binop_rm - Simple SSE41 binary operator.
6720*9880d681SAndroid Build Coastguard Workermulticlass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6721*9880d681SAndroid Build Coastguard Worker                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6722*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, bit Is2Addr = 1,
6723*9880d681SAndroid Build Coastguard Worker                          OpndItins itins = SSE_INTALU_ITINS_P> {
6724*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
6725*9880d681SAndroid Build Coastguard Worker  def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6726*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
6727*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
6728*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6729*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6730*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6731*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
6732*9880d681SAndroid Build Coastguard Worker  def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6733*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
6734*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
6735*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6736*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6737*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst,
6738*9880d681SAndroid Build Coastguard Worker         (OpVT (OpNode RC:$src1, (bitconvert (memop_frag addr:$src2)))))]>,
6739*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
6740*9880d681SAndroid Build Coastguard Worker}
6741*9880d681SAndroid Build Coastguard Worker
6742*9880d681SAndroid Build Coastguard Worker/// SS48I_binop_rm2 - Simple SSE41 binary operator with different src and dst
6743*9880d681SAndroid Build Coastguard Worker/// types.
6744*9880d681SAndroid Build Coastguard Workermulticlass SS48I_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
6745*9880d681SAndroid Build Coastguard Worker                         ValueType DstVT, ValueType SrcVT, RegisterClass RC,
6746*9880d681SAndroid Build Coastguard Worker                         PatFrag memop_frag, X86MemOperand x86memop,
6747*9880d681SAndroid Build Coastguard Worker                         OpndItins itins,
6748*9880d681SAndroid Build Coastguard Worker                         bit IsCommutable = 0, bit Is2Addr = 1> {
6749*9880d681SAndroid Build Coastguard Worker  let isCommutable = IsCommutable in
6750*9880d681SAndroid Build Coastguard Worker  def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6751*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
6752*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
6753*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6754*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6755*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
6756*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched]>;
6757*9880d681SAndroid Build Coastguard Worker  def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6758*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
6759*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
6760*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6761*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6762*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
6763*9880d681SAndroid Build Coastguard Worker                                     (bitconvert (memop_frag addr:$src2)))))]>,
6764*9880d681SAndroid Build Coastguard Worker       Sched<[itins.Sched.Folded, ReadAfterLd]>;
6765*9880d681SAndroid Build Coastguard Worker}
6766*9880d681SAndroid Build Coastguard Worker
6767*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
6768*9880d681SAndroid Build Coastguard Worker  defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", smin, v4i32, VR128,
6769*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6770*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6771*9880d681SAndroid Build Coastguard Worker  defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", umin, v4i32, VR128,
6772*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6773*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6774*9880d681SAndroid Build Coastguard Worker  defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v4i32, VR128,
6775*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6776*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6777*9880d681SAndroid Build Coastguard Worker  defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", umax, v4i32, VR128,
6778*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6779*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6780*9880d681SAndroid Build Coastguard Worker  defm VPMULDQ   : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v2i64, v4i32,
6781*9880d681SAndroid Build Coastguard Worker                                   VR128, loadv2i64, i128mem,
6782*9880d681SAndroid Build Coastguard Worker                                   SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V;
6783*9880d681SAndroid Build Coastguard Worker}
6784*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
6785*9880d681SAndroid Build Coastguard Worker  defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", smin, v16i8, VR128,
6786*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6787*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6788*9880d681SAndroid Build Coastguard Worker  defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", umin, v8i16, VR128,
6789*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6790*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6791*9880d681SAndroid Build Coastguard Worker  defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v16i8, VR128,
6792*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6793*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6794*9880d681SAndroid Build Coastguard Worker  defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v8i16, VR128,
6795*9880d681SAndroid Build Coastguard Worker                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6796*9880d681SAndroid Build Coastguard Worker                                  VEX_4V;
6797*9880d681SAndroid Build Coastguard Worker}
6798*9880d681SAndroid Build Coastguard Worker
6799*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
6800*9880d681SAndroid Build Coastguard Worker  defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", smin, v8i32, VR256,
6801*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6802*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6803*9880d681SAndroid Build Coastguard Worker  defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", umin, v8i32, VR256,
6804*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6805*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6806*9880d681SAndroid Build Coastguard Worker  defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v8i32, VR256,
6807*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6808*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6809*9880d681SAndroid Build Coastguard Worker  defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", umax, v8i32, VR256,
6810*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6811*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6812*9880d681SAndroid Build Coastguard Worker  defm VPMULDQY : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v4i64, v8i32,
6813*9880d681SAndroid Build Coastguard Worker                                  VR256, loadv4i64, i256mem,
6814*9880d681SAndroid Build Coastguard Worker                                  SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
6815*9880d681SAndroid Build Coastguard Worker}
6816*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
6817*9880d681SAndroid Build Coastguard Worker  defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", smin, v32i8, VR256,
6818*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6819*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6820*9880d681SAndroid Build Coastguard Worker  defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", umin, v16i16, VR256,
6821*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6822*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6823*9880d681SAndroid Build Coastguard Worker  defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v32i8, VR256,
6824*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6825*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6826*9880d681SAndroid Build Coastguard Worker  defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v16i16, VR256,
6827*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6828*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6829*9880d681SAndroid Build Coastguard Worker}
6830*9880d681SAndroid Build Coastguard Worker
6831*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
6832*9880d681SAndroid Build Coastguard Worker  defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", smin, v16i8, VR128,
6833*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6834*9880d681SAndroid Build Coastguard Worker  defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", smin, v4i32, VR128,
6835*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6836*9880d681SAndroid Build Coastguard Worker  defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", umin, v4i32, VR128,
6837*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6838*9880d681SAndroid Build Coastguard Worker  defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", umin, v8i16, VR128,
6839*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6840*9880d681SAndroid Build Coastguard Worker  defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", smax, v16i8, VR128,
6841*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6842*9880d681SAndroid Build Coastguard Worker  defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", smax, v4i32, VR128,
6843*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6844*9880d681SAndroid Build Coastguard Worker  defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", umax, v4i32, VR128,
6845*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6846*9880d681SAndroid Build Coastguard Worker  defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", umax, v8i16, VR128,
6847*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6848*9880d681SAndroid Build Coastguard Worker  defm PMULDQ   : SS48I_binop_rm2<0x28, "pmuldq", X86pmuldq, v2i64, v4i32,
6849*9880d681SAndroid Build Coastguard Worker                                  VR128, memopv2i64, i128mem,
6850*9880d681SAndroid Build Coastguard Worker                                  SSE_INTMUL_ITINS_P, 1>;
6851*9880d681SAndroid Build Coastguard Worker}
6852*9880d681SAndroid Build Coastguard Worker
6853*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
6854*9880d681SAndroid Build Coastguard Worker  defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6855*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 0, SSE_PMULLD_ITINS>,
6856*9880d681SAndroid Build Coastguard Worker                                 VEX_4V;
6857*9880d681SAndroid Build Coastguard Worker  defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6858*9880d681SAndroid Build Coastguard Worker                                 memopv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6859*9880d681SAndroid Build Coastguard Worker                                 VEX_4V;
6860*9880d681SAndroid Build Coastguard Worker}
6861*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
6862*9880d681SAndroid Build Coastguard Worker  defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6863*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_PMULLD_ITINS>,
6864*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6865*9880d681SAndroid Build Coastguard Worker  defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6866*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6867*9880d681SAndroid Build Coastguard Worker                                  VEX_4V, VEX_L;
6868*9880d681SAndroid Build Coastguard Worker}
6869*9880d681SAndroid Build Coastguard Worker
6870*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
6871*9880d681SAndroid Build Coastguard Worker  defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6872*9880d681SAndroid Build Coastguard Worker                                memopv2i64, i128mem, 1, SSE_PMULLD_ITINS>;
6873*9880d681SAndroid Build Coastguard Worker  defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6874*9880d681SAndroid Build Coastguard Worker                                memopv2i64, i128mem, 1, SSE_INTALUQ_ITINS_P>;
6875*9880d681SAndroid Build Coastguard Worker}
6876*9880d681SAndroid Build Coastguard Worker
6877*9880d681SAndroid Build Coastguard Worker/// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6878*9880d681SAndroid Build Coastguard Workermulticlass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6879*9880d681SAndroid Build Coastguard Worker                 Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6880*9880d681SAndroid Build Coastguard Worker                 X86MemOperand x86memop, bit Is2Addr = 1,
6881*9880d681SAndroid Build Coastguard Worker                 OpndItins itins = DEFAULT_ITINS> {
6882*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
6883*9880d681SAndroid Build Coastguard Worker  def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6884*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, RC:$src2, u8imm:$src3),
6885*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6886*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6887*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6888*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6889*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6890*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))], itins.rr>,
6891*9880d681SAndroid Build Coastguard Worker        Sched<[itins.Sched]>;
6892*9880d681SAndroid Build Coastguard Worker  def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6893*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6894*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6895*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6896*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6897*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6898*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6899*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst,
6900*9880d681SAndroid Build Coastguard Worker          (IntId RC:$src1,
6901*9880d681SAndroid Build Coastguard Worker           (bitconvert (memop_frag addr:$src2)), imm:$src3))], itins.rm>,
6902*9880d681SAndroid Build Coastguard Worker        Sched<[itins.Sched.Folded, ReadAfterLd]>;
6903*9880d681SAndroid Build Coastguard Worker}
6904*9880d681SAndroid Build Coastguard Worker
6905*9880d681SAndroid Build Coastguard Worker/// SS41I_binop_rmi - SSE 4.1 binary operator with 8-bit immediate
6906*9880d681SAndroid Build Coastguard Workermulticlass SS41I_binop_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
6907*9880d681SAndroid Build Coastguard Worker                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6908*9880d681SAndroid Build Coastguard Worker                           X86MemOperand x86memop, bit Is2Addr = 1,
6909*9880d681SAndroid Build Coastguard Worker                           OpndItins itins = DEFAULT_ITINS> {
6910*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
6911*9880d681SAndroid Build Coastguard Worker  def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6912*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, RC:$src2, u8imm:$src3),
6913*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6914*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6915*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6916*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6917*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6918*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))],
6919*9880d681SAndroid Build Coastguard Worker        itins.rr>, Sched<[itins.Sched]>;
6920*9880d681SAndroid Build Coastguard Worker  def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6921*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6922*9880d681SAndroid Build Coastguard Worker        !if(Is2Addr,
6923*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6924*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6925*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
6926*9880d681SAndroid Build Coastguard Worker                "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6927*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst,
6928*9880d681SAndroid Build Coastguard Worker          (OpVT (OpNode RC:$src1,
6929*9880d681SAndroid Build Coastguard Worker                 (bitconvert (memop_frag addr:$src2)), imm:$src3)))], itins.rm>,
6930*9880d681SAndroid Build Coastguard Worker        Sched<[itins.Sched.Folded, ReadAfterLd]>;
6931*9880d681SAndroid Build Coastguard Worker}
6932*9880d681SAndroid Build Coastguard Worker
6933*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
6934*9880d681SAndroid Build Coastguard Worker  let isCommutable = 0 in {
6935*9880d681SAndroid Build Coastguard Worker    defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6936*9880d681SAndroid Build Coastguard Worker                                        VR128, loadv2i64, i128mem, 0,
6937*9880d681SAndroid Build Coastguard Worker                                        DEFAULT_ITINS_MPSADSCHED>, VEX_4V;
6938*9880d681SAndroid Build Coastguard Worker  }
6939*9880d681SAndroid Build Coastguard Worker
6940*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in {
6941*9880d681SAndroid Build Coastguard Worker  defm VBLENDPS : SS41I_binop_rmi<0x0C, "vblendps", X86Blendi, v4f32,
6942*9880d681SAndroid Build Coastguard Worker                                  VR128, loadv4f32, f128mem, 0,
6943*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
6944*9880d681SAndroid Build Coastguard Worker  defm VBLENDPSY : SS41I_binop_rmi<0x0C, "vblendps", X86Blendi, v8f32,
6945*9880d681SAndroid Build Coastguard Worker                                   VR256, loadv8f32, f256mem, 0,
6946*9880d681SAndroid Build Coastguard Worker                                   DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_L;
6947*9880d681SAndroid Build Coastguard Worker  }
6948*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in {
6949*9880d681SAndroid Build Coastguard Worker  defm VBLENDPD : SS41I_binop_rmi<0x0D, "vblendpd", X86Blendi, v2f64,
6950*9880d681SAndroid Build Coastguard Worker                                  VR128, loadv2f64, f128mem, 0,
6951*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
6952*9880d681SAndroid Build Coastguard Worker  defm VBLENDPDY : SS41I_binop_rmi<0x0D, "vblendpd", X86Blendi, v4f64,
6953*9880d681SAndroid Build Coastguard Worker                                   VR256, loadv4f64, f256mem, 0,
6954*9880d681SAndroid Build Coastguard Worker                                   DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_L;
6955*9880d681SAndroid Build Coastguard Worker  }
6956*9880d681SAndroid Build Coastguard Worker  defm VPBLENDW : SS41I_binop_rmi<0x0E, "vpblendw", X86Blendi, v8i16,
6957*9880d681SAndroid Build Coastguard Worker                                  VR128, loadv2i64, i128mem, 0,
6958*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_BLENDSCHED>, VEX_4V;
6959*9880d681SAndroid Build Coastguard Worker
6960*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in
6961*9880d681SAndroid Build Coastguard Worker  defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6962*9880d681SAndroid Build Coastguard Worker                                   VR128, loadv4f32, f128mem, 0,
6963*9880d681SAndroid Build Coastguard Worker                                   SSE_DPPS_ITINS>, VEX_4V;
6964*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in
6965*9880d681SAndroid Build Coastguard Worker  defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6966*9880d681SAndroid Build Coastguard Worker                                   VR128, loadv2f64, f128mem, 0,
6967*9880d681SAndroid Build Coastguard Worker                                   SSE_DPPS_ITINS>, VEX_4V;
6968*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in
6969*9880d681SAndroid Build Coastguard Worker  defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6970*9880d681SAndroid Build Coastguard Worker                                    VR256, loadv8f32, i256mem, 0,
6971*9880d681SAndroid Build Coastguard Worker                                    SSE_DPPS_ITINS>, VEX_4V, VEX_L;
6972*9880d681SAndroid Build Coastguard Worker}
6973*9880d681SAndroid Build Coastguard Worker
6974*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
6975*9880d681SAndroid Build Coastguard Worker  let isCommutable = 0 in {
6976*9880d681SAndroid Build Coastguard Worker  defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6977*9880d681SAndroid Build Coastguard Worker                                  VR256, loadv4i64, i256mem, 0,
6978*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_MPSADSCHED>, VEX_4V, VEX_L;
6979*9880d681SAndroid Build Coastguard Worker  }
6980*9880d681SAndroid Build Coastguard Worker  defm VPBLENDWY : SS41I_binop_rmi<0x0E, "vpblendw", X86Blendi, v16i16,
6981*9880d681SAndroid Build Coastguard Worker                                   VR256, loadv4i64, i256mem, 0,
6982*9880d681SAndroid Build Coastguard Worker                                   DEFAULT_ITINS_BLENDSCHED>, VEX_4V, VEX_L;
6983*9880d681SAndroid Build Coastguard Worker}
6984*9880d681SAndroid Build Coastguard Worker
6985*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
6986*9880d681SAndroid Build Coastguard Worker  let isCommutable = 0 in {
6987*9880d681SAndroid Build Coastguard Worker  defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6988*9880d681SAndroid Build Coastguard Worker                                     VR128, memopv2i64, i128mem,
6989*9880d681SAndroid Build Coastguard Worker                                     1, SSE_MPSADBW_ITINS>;
6990*9880d681SAndroid Build Coastguard Worker  }
6991*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in
6992*9880d681SAndroid Build Coastguard Worker  defm BLENDPS : SS41I_binop_rmi<0x0C, "blendps", X86Blendi, v4f32,
6993*9880d681SAndroid Build Coastguard Worker                                 VR128, memopv4f32, f128mem,
6994*9880d681SAndroid Build Coastguard Worker                                 1, SSE_INTALU_ITINS_FBLEND_P>;
6995*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in
6996*9880d681SAndroid Build Coastguard Worker  defm BLENDPD : SS41I_binop_rmi<0x0D, "blendpd", X86Blendi, v2f64,
6997*9880d681SAndroid Build Coastguard Worker                                 VR128, memopv2f64, f128mem,
6998*9880d681SAndroid Build Coastguard Worker                                 1, SSE_INTALU_ITINS_FBLEND_P>;
6999*9880d681SAndroid Build Coastguard Worker  defm PBLENDW : SS41I_binop_rmi<0x0E, "pblendw", X86Blendi, v8i16,
7000*9880d681SAndroid Build Coastguard Worker                                 VR128, memopv2i64, i128mem,
7001*9880d681SAndroid Build Coastguard Worker                                 1, SSE_INTALU_ITINS_BLEND_P>;
7002*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in
7003*9880d681SAndroid Build Coastguard Worker  defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
7004*9880d681SAndroid Build Coastguard Worker                                  VR128, memopv4f32, f128mem, 1,
7005*9880d681SAndroid Build Coastguard Worker                                  SSE_DPPS_ITINS>;
7006*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in
7007*9880d681SAndroid Build Coastguard Worker  defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
7008*9880d681SAndroid Build Coastguard Worker                                  VR128, memopv2f64, f128mem, 1,
7009*9880d681SAndroid Build Coastguard Worker                                  SSE_DPPD_ITINS>;
7010*9880d681SAndroid Build Coastguard Worker}
7011*9880d681SAndroid Build Coastguard Worker
7012*9880d681SAndroid Build Coastguard Worker/// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
7013*9880d681SAndroid Build Coastguard Workermulticlass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
7014*9880d681SAndroid Build Coastguard Worker                                    RegisterClass RC, X86MemOperand x86memop,
7015*9880d681SAndroid Build Coastguard Worker                                    PatFrag mem_frag, Intrinsic IntId,
7016*9880d681SAndroid Build Coastguard Worker                                    X86FoldableSchedWrite Sched> {
7017*9880d681SAndroid Build Coastguard Worker  def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
7018*9880d681SAndroid Build Coastguard Worker                  (ins RC:$src1, RC:$src2, RC:$src3),
7019*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr,
7020*9880d681SAndroid Build Coastguard Worker                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7021*9880d681SAndroid Build Coastguard Worker                  [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
7022*9880d681SAndroid Build Coastguard Worker                  NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7023*9880d681SAndroid Build Coastguard Worker                Sched<[Sched]>;
7024*9880d681SAndroid Build Coastguard Worker
7025*9880d681SAndroid Build Coastguard Worker  def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
7026*9880d681SAndroid Build Coastguard Worker                  (ins RC:$src1, x86memop:$src2, RC:$src3),
7027*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr,
7028*9880d681SAndroid Build Coastguard Worker                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7029*9880d681SAndroid Build Coastguard Worker                  [(set RC:$dst,
7030*9880d681SAndroid Build Coastguard Worker                        (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
7031*9880d681SAndroid Build Coastguard Worker                               RC:$src3))],
7032*9880d681SAndroid Build Coastguard Worker                  NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7033*9880d681SAndroid Build Coastguard Worker                Sched<[Sched.Folded, ReadAfterLd]>;
7034*9880d681SAndroid Build Coastguard Worker}
7035*9880d681SAndroid Build Coastguard Worker
7036*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
7037*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in {
7038*9880d681SAndroid Build Coastguard Workerdefm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
7039*9880d681SAndroid Build Coastguard Worker                                           loadv2f64, int_x86_sse41_blendvpd,
7040*9880d681SAndroid Build Coastguard Worker                                           WriteFVarBlend>;
7041*9880d681SAndroid Build Coastguard Workerdefm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
7042*9880d681SAndroid Build Coastguard Worker                                  loadv4f64, int_x86_avx_blendv_pd_256,
7043*9880d681SAndroid Build Coastguard Worker                                  WriteFVarBlend>, VEX_L;
7044*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedDouble
7045*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
7046*9880d681SAndroid Build Coastguard Workerdefm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
7047*9880d681SAndroid Build Coastguard Worker                                           loadv4f32, int_x86_sse41_blendvps,
7048*9880d681SAndroid Build Coastguard Worker                                           WriteFVarBlend>;
7049*9880d681SAndroid Build Coastguard Workerdefm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
7050*9880d681SAndroid Build Coastguard Worker                                  loadv8f32, int_x86_avx_blendv_ps_256,
7051*9880d681SAndroid Build Coastguard Worker                                  WriteFVarBlend>, VEX_L;
7052*9880d681SAndroid Build Coastguard Worker} // ExeDomain = SSEPackedSingle
7053*9880d681SAndroid Build Coastguard Workerdefm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
7054*9880d681SAndroid Build Coastguard Worker                                           loadv2i64, int_x86_sse41_pblendvb,
7055*9880d681SAndroid Build Coastguard Worker                                           WriteVarBlend>;
7056*9880d681SAndroid Build Coastguard Worker}
7057*9880d681SAndroid Build Coastguard Worker
7058*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
7059*9880d681SAndroid Build Coastguard Workerdefm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
7060*9880d681SAndroid Build Coastguard Worker                                      loadv4i64, int_x86_avx2_pblendvb,
7061*9880d681SAndroid Build Coastguard Worker                                      WriteVarBlend>, VEX_L;
7062*9880d681SAndroid Build Coastguard Worker}
7063*9880d681SAndroid Build Coastguard Worker
7064*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
7065*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
7066*9880d681SAndroid Build Coastguard Worker                            (v16i8 VR128:$src2))),
7067*9880d681SAndroid Build Coastguard Worker            (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7068*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
7069*9880d681SAndroid Build Coastguard Worker                            (v4i32 VR128:$src2))),
7070*9880d681SAndroid Build Coastguard Worker            (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7071*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
7072*9880d681SAndroid Build Coastguard Worker                            (v4f32 VR128:$src2))),
7073*9880d681SAndroid Build Coastguard Worker            (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7074*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
7075*9880d681SAndroid Build Coastguard Worker                            (v2i64 VR128:$src2))),
7076*9880d681SAndroid Build Coastguard Worker            (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7077*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
7078*9880d681SAndroid Build Coastguard Worker                            (v2f64 VR128:$src2))),
7079*9880d681SAndroid Build Coastguard Worker            (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7080*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
7081*9880d681SAndroid Build Coastguard Worker                            (v8i32 VR256:$src2))),
7082*9880d681SAndroid Build Coastguard Worker            (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7083*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
7084*9880d681SAndroid Build Coastguard Worker                            (v8f32 VR256:$src2))),
7085*9880d681SAndroid Build Coastguard Worker            (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7086*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
7087*9880d681SAndroid Build Coastguard Worker                            (v4i64 VR256:$src2))),
7088*9880d681SAndroid Build Coastguard Worker            (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7089*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
7090*9880d681SAndroid Build Coastguard Worker                            (v4f64 VR256:$src2))),
7091*9880d681SAndroid Build Coastguard Worker            (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7092*9880d681SAndroid Build Coastguard Worker}
7093*9880d681SAndroid Build Coastguard Worker
7094*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
7095*9880d681SAndroid Build Coastguard Worker  def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
7096*9880d681SAndroid Build Coastguard Worker                            (v32i8 VR256:$src2))),
7097*9880d681SAndroid Build Coastguard Worker            (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7098*9880d681SAndroid Build Coastguard Worker}
7099*9880d681SAndroid Build Coastguard Worker
7100*9880d681SAndroid Build Coastguard Worker// Patterns
7101*9880d681SAndroid Build Coastguard Worker// FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
7102*9880d681SAndroid Build Coastguard Worker// on targets where they have equal performance. These were changed to use
7103*9880d681SAndroid Build Coastguard Worker// blends because blends have better throughput on SandyBridge and Haswell, but
7104*9880d681SAndroid Build Coastguard Worker// movs[s/d] are 1-2 byte shorter instructions.
7105*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseAVX] in {
7106*9880d681SAndroid Build Coastguard Worker  let AddedComplexity = 15 in {
7107*9880d681SAndroid Build Coastguard Worker  // Move scalar to XMM zero-extended, zeroing a VR128 then do a
7108*9880d681SAndroid Build Coastguard Worker  // MOVS{S,D} to the lower bits.
7109*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
7110*9880d681SAndroid Build Coastguard Worker            (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
7111*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
7112*9880d681SAndroid Build Coastguard Worker            (VBLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
7113*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
7114*9880d681SAndroid Build Coastguard Worker            (VPBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
7115*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
7116*9880d681SAndroid Build Coastguard Worker            (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
7117*9880d681SAndroid Build Coastguard Worker
7118*9880d681SAndroid Build Coastguard Worker  // Move low f32 and clear high bits.
7119*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
7120*9880d681SAndroid Build Coastguard Worker            (VBLENDPSYrri (v8f32 (AVX_SET0)), VR256:$src, (i8 1))>;
7121*9880d681SAndroid Build Coastguard Worker
7122*9880d681SAndroid Build Coastguard Worker  // Move low f64 and clear high bits.
7123*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
7124*9880d681SAndroid Build Coastguard Worker            (VBLENDPDYrri (v4f64 (AVX_SET0)), VR256:$src, (i8 1))>;
7125*9880d681SAndroid Build Coastguard Worker  }
7126*9880d681SAndroid Build Coastguard Worker
7127*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
7128*9880d681SAndroid Build Coastguard Worker                   (v4f32 (scalar_to_vector FR32:$src)), (iPTR 0)))),
7129*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i32 0),
7130*9880d681SAndroid Build Coastguard Worker                           (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
7131*9880d681SAndroid Build Coastguard Worker                           sub_xmm)>;
7132*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
7133*9880d681SAndroid Build Coastguard Worker                   (v2f64 (scalar_to_vector FR64:$src)), (iPTR 0)))),
7134*9880d681SAndroid Build Coastguard Worker            (SUBREG_TO_REG (i64 0),
7135*9880d681SAndroid Build Coastguard Worker                           (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
7136*9880d681SAndroid Build Coastguard Worker                           sub_xmm)>;
7137*9880d681SAndroid Build Coastguard Worker
7138*9880d681SAndroid Build Coastguard Worker  // These will incur an FP/int domain crossing penalty, but it may be the only
7139*9880d681SAndroid Build Coastguard Worker  // way without AVX2. Do not add any complexity because we may be able to match
7140*9880d681SAndroid Build Coastguard Worker  // more optimal patterns defined earlier in this file.
7141*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
7142*9880d681SAndroid Build Coastguard Worker            (VBLENDPSYrri (v8i32 (AVX_SET0)), VR256:$src, (i8 1))>;
7143*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
7144*9880d681SAndroid Build Coastguard Worker            (VBLENDPDYrri (v4i64 (AVX_SET0)), VR256:$src, (i8 1))>;
7145*9880d681SAndroid Build Coastguard Worker}
7146*9880d681SAndroid Build Coastguard Worker
7147*9880d681SAndroid Build Coastguard Worker// FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
7148*9880d681SAndroid Build Coastguard Worker// on targets where they have equal performance. These were changed to use
7149*9880d681SAndroid Build Coastguard Worker// blends because blends have better throughput on SandyBridge and Haswell, but
7150*9880d681SAndroid Build Coastguard Worker// movs[s/d] are 1-2 byte shorter instructions.
7151*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41], AddedComplexity = 15 in {
7152*9880d681SAndroid Build Coastguard Worker  // With SSE41 we can use blends for these patterns.
7153*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
7154*9880d681SAndroid Build Coastguard Worker            (BLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
7155*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
7156*9880d681SAndroid Build Coastguard Worker            (PBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
7157*9880d681SAndroid Build Coastguard Worker}
7158*9880d681SAndroid Build Coastguard Worker
7159*9880d681SAndroid Build Coastguard Worker
7160*9880d681SAndroid Build Coastguard Worker/// SS41I_ternary_int - SSE 4.1 ternary operator
7161*9880d681SAndroid Build Coastguard Workerlet Uses = [XMM0], Constraints = "$src1 = $dst" in {
7162*9880d681SAndroid Build Coastguard Worker  multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7163*9880d681SAndroid Build Coastguard Worker                               X86MemOperand x86memop, Intrinsic IntId,
7164*9880d681SAndroid Build Coastguard Worker                               OpndItins itins = DEFAULT_ITINS> {
7165*9880d681SAndroid Build Coastguard Worker    def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7166*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, VR128:$src2),
7167*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
7168*9880d681SAndroid Build Coastguard Worker                     "\t{$src2, $dst|$dst, $src2}"),
7169*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))],
7170*9880d681SAndroid Build Coastguard Worker                    itins.rr>, Sched<[itins.Sched]>;
7171*9880d681SAndroid Build Coastguard Worker
7172*9880d681SAndroid Build Coastguard Worker    def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7173*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, x86memop:$src2),
7174*9880d681SAndroid Build Coastguard Worker                    !strconcat(OpcodeStr,
7175*9880d681SAndroid Build Coastguard Worker                     "\t{$src2, $dst|$dst, $src2}"),
7176*9880d681SAndroid Build Coastguard Worker                    [(set VR128:$dst,
7177*9880d681SAndroid Build Coastguard Worker                      (IntId VR128:$src1,
7178*9880d681SAndroid Build Coastguard Worker                       (bitconvert (mem_frag addr:$src2)), XMM0))],
7179*9880d681SAndroid Build Coastguard Worker                       itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7180*9880d681SAndroid Build Coastguard Worker  }
7181*9880d681SAndroid Build Coastguard Worker}
7182*9880d681SAndroid Build Coastguard Worker
7183*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in
7184*9880d681SAndroid Build Coastguard Workerdefm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
7185*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_blendvpd,
7186*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_FBLENDSCHED>;
7187*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in
7188*9880d681SAndroid Build Coastguard Workerdefm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
7189*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_blendvps,
7190*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_FBLENDSCHED>;
7191*9880d681SAndroid Build Coastguard Workerdefm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
7192*9880d681SAndroid Build Coastguard Worker                                  int_x86_sse41_pblendvb,
7193*9880d681SAndroid Build Coastguard Worker                                  DEFAULT_ITINS_VARBLENDSCHED>;
7194*9880d681SAndroid Build Coastguard Worker
7195*9880d681SAndroid Build Coastguard Worker// Aliases with the implicit xmm0 argument
7196*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7197*9880d681SAndroid Build Coastguard Worker                (BLENDVPDrr0 VR128:$dst, VR128:$src2)>;
7198*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7199*9880d681SAndroid Build Coastguard Worker                (BLENDVPDrm0 VR128:$dst, f128mem:$src2)>;
7200*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7201*9880d681SAndroid Build Coastguard Worker                (BLENDVPSrr0 VR128:$dst, VR128:$src2)>;
7202*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7203*9880d681SAndroid Build Coastguard Worker                (BLENDVPSrm0 VR128:$dst, f128mem:$src2)>;
7204*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7205*9880d681SAndroid Build Coastguard Worker                (PBLENDVBrr0 VR128:$dst, VR128:$src2)>;
7206*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7207*9880d681SAndroid Build Coastguard Worker                (PBLENDVBrm0 VR128:$dst, i128mem:$src2)>;
7208*9880d681SAndroid Build Coastguard Worker
7209*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41] in {
7210*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
7211*9880d681SAndroid Build Coastguard Worker                            (v16i8 VR128:$src2))),
7212*9880d681SAndroid Build Coastguard Worker            (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
7213*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
7214*9880d681SAndroid Build Coastguard Worker                            (v4i32 VR128:$src2))),
7215*9880d681SAndroid Build Coastguard Worker            (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7216*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
7217*9880d681SAndroid Build Coastguard Worker                            (v4f32 VR128:$src2))),
7218*9880d681SAndroid Build Coastguard Worker            (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7219*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
7220*9880d681SAndroid Build Coastguard Worker                            (v2i64 VR128:$src2))),
7221*9880d681SAndroid Build Coastguard Worker            (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7222*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
7223*9880d681SAndroid Build Coastguard Worker                            (v2f64 VR128:$src2))),
7224*9880d681SAndroid Build Coastguard Worker            (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7225*9880d681SAndroid Build Coastguard Worker}
7226*9880d681SAndroid Build Coastguard Worker
7227*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 400 in { // Prefer non-temporal versions
7228*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteLoad] in {
7229*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in
7230*9880d681SAndroid Build Coastguard Workerdef VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7231*9880d681SAndroid Build Coastguard Worker                       "vmovntdqa\t{$src, $dst|$dst, $src}",
7232*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
7233*9880d681SAndroid Build Coastguard Worker                       VEX;
7234*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in
7235*9880d681SAndroid Build Coastguard Workerdef VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
7236*9880d681SAndroid Build Coastguard Worker                         "vmovntdqa\t{$src, $dst|$dst, $src}",
7237*9880d681SAndroid Build Coastguard Worker                         [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
7238*9880d681SAndroid Build Coastguard Worker                         VEX, VEX_L;
7239*9880d681SAndroid Build Coastguard Workerdef MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7240*9880d681SAndroid Build Coastguard Worker                       "movntdqa\t{$src, $dst|$dst, $src}",
7241*9880d681SAndroid Build Coastguard Worker                       [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>;
7242*9880d681SAndroid Build Coastguard Worker} // SchedRW
7243*9880d681SAndroid Build Coastguard Worker
7244*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
7245*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (alignednontemporalload addr:$src)),
7246*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQAYrm addr:$src)>;
7247*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (alignednontemporalload addr:$src)),
7248*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQAYrm addr:$src)>;
7249*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (alignednontemporalload addr:$src)),
7250*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQAYrm addr:$src)>;
7251*9880d681SAndroid Build Coastguard Worker}
7252*9880d681SAndroid Build Coastguard Worker
7253*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
7254*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (alignednontemporalload addr:$src)),
7255*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQArm addr:$src)>;
7256*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (alignednontemporalload addr:$src)),
7257*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQArm addr:$src)>;
7258*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (alignednontemporalload addr:$src)),
7259*9880d681SAndroid Build Coastguard Worker            (VMOVNTDQArm addr:$src)>;
7260*9880d681SAndroid Build Coastguard Worker}
7261*9880d681SAndroid Build Coastguard Worker
7262*9880d681SAndroid Build Coastguard Workerlet Predicates = [UseSSE41] in {
7263*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (alignednontemporalload addr:$src)),
7264*9880d681SAndroid Build Coastguard Worker            (MOVNTDQArm addr:$src)>;
7265*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (alignednontemporalload addr:$src)),
7266*9880d681SAndroid Build Coastguard Worker            (MOVNTDQArm addr:$src)>;
7267*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (alignednontemporalload addr:$src)),
7268*9880d681SAndroid Build Coastguard Worker            (MOVNTDQArm addr:$src)>;
7269*9880d681SAndroid Build Coastguard Worker}
7270*9880d681SAndroid Build Coastguard Worker
7271*9880d681SAndroid Build Coastguard Worker} // AddedComplexity
7272*9880d681SAndroid Build Coastguard Worker
7273*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7274*9880d681SAndroid Build Coastguard Worker// SSE4.2 - Compare Instructions
7275*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7276*9880d681SAndroid Build Coastguard Worker
7277*9880d681SAndroid Build Coastguard Worker/// SS42I_binop_rm - Simple SSE 4.2 binary operator
7278*9880d681SAndroid Build Coastguard Workermulticlass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7279*9880d681SAndroid Build Coastguard Worker                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7280*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, bit Is2Addr = 1> {
7281*9880d681SAndroid Build Coastguard Worker  def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
7282*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, RC:$src2),
7283*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
7284*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7285*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7286*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
7287*9880d681SAndroid Build Coastguard Worker  def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
7288*9880d681SAndroid Build Coastguard Worker       (ins RC:$src1, x86memop:$src2),
7289*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
7290*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7291*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7292*9880d681SAndroid Build Coastguard Worker       [(set RC:$dst,
7293*9880d681SAndroid Build Coastguard Worker         (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>;
7294*9880d681SAndroid Build Coastguard Worker}
7295*9880d681SAndroid Build Coastguard Worker
7296*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in
7297*9880d681SAndroid Build Coastguard Worker  defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
7298*9880d681SAndroid Build Coastguard Worker                                 loadv2i64, i128mem, 0>, VEX_4V;
7299*9880d681SAndroid Build Coastguard Worker
7300*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in
7301*9880d681SAndroid Build Coastguard Worker  defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
7302*9880d681SAndroid Build Coastguard Worker                                  loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7303*9880d681SAndroid Build Coastguard Worker
7304*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in
7305*9880d681SAndroid Build Coastguard Worker  defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
7306*9880d681SAndroid Build Coastguard Worker                                memopv2i64, i128mem>;
7307*9880d681SAndroid Build Coastguard Worker
7308*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7309*9880d681SAndroid Build Coastguard Worker// SSE4.2 - String/text Processing Instructions
7310*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7311*9880d681SAndroid Build Coastguard Worker
7312*9880d681SAndroid Build Coastguard Worker// Packed Compare Implicit Length Strings, Return Mask
7313*9880d681SAndroid Build Coastguard Workermulticlass pseudo_pcmpistrm<string asm, PatFrag ld_frag> {
7314*9880d681SAndroid Build Coastguard Worker  def REG : PseudoI<(outs VR128:$dst),
7315*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7316*9880d681SAndroid Build Coastguard Worker    [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
7317*9880d681SAndroid Build Coastguard Worker                                                  imm:$src3))]>;
7318*9880d681SAndroid Build Coastguard Worker  def MEM : PseudoI<(outs VR128:$dst),
7319*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7320*9880d681SAndroid Build Coastguard Worker    [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1,
7321*9880d681SAndroid Build Coastguard Worker                       (bc_v16i8 (ld_frag addr:$src2)), imm:$src3))]>;
7322*9880d681SAndroid Build Coastguard Worker}
7323*9880d681SAndroid Build Coastguard Worker
7324*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], usesCustomInserter = 1 in {
7325*9880d681SAndroid Build Coastguard Worker  defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128", loadv2i64>,
7326*9880d681SAndroid Build Coastguard Worker                         Requires<[HasAVX]>;
7327*9880d681SAndroid Build Coastguard Worker  defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128", memopv2i64>,
7328*9880d681SAndroid Build Coastguard Worker                         Requires<[UseSSE42]>;
7329*9880d681SAndroid Build Coastguard Worker}
7330*9880d681SAndroid Build Coastguard Worker
7331*9880d681SAndroid Build Coastguard Workermulticlass pcmpistrm_SS42AI<string asm> {
7332*9880d681SAndroid Build Coastguard Worker  def rr : SS42AI<0x62, MRMSrcReg, (outs),
7333*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7334*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7335*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpIStrM]>;
7336*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
7337*9880d681SAndroid Build Coastguard Worker  def rm :SS42AI<0x62, MRMSrcMem, (outs),
7338*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7339*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7340*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpIStrMLd, ReadAfterLd]>;
7341*9880d681SAndroid Build Coastguard Worker}
7342*9880d681SAndroid Build Coastguard Worker
7343*9880d681SAndroid Build Coastguard Workerlet Defs = [XMM0, EFLAGS], hasSideEffects = 0 in {
7344*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in
7345*9880d681SAndroid Build Coastguard Worker  defm VPCMPISTRM128 : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
7346*9880d681SAndroid Build Coastguard Worker  defm PCMPISTRM128  : pcmpistrm_SS42AI<"pcmpistrm"> ;
7347*9880d681SAndroid Build Coastguard Worker}
7348*9880d681SAndroid Build Coastguard Worker
7349*9880d681SAndroid Build Coastguard Worker// Packed Compare Explicit Length Strings, Return Mask
7350*9880d681SAndroid Build Coastguard Workermulticlass pseudo_pcmpestrm<string asm, PatFrag ld_frag> {
7351*9880d681SAndroid Build Coastguard Worker  def REG : PseudoI<(outs VR128:$dst),
7352*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7353*9880d681SAndroid Build Coastguard Worker    [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7354*9880d681SAndroid Build Coastguard Worker                       VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7355*9880d681SAndroid Build Coastguard Worker  def MEM : PseudoI<(outs VR128:$dst),
7356*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7357*9880d681SAndroid Build Coastguard Worker    [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 VR128:$src1, EAX,
7358*9880d681SAndroid Build Coastguard Worker                       (bc_v16i8 (ld_frag addr:$src3)), EDX, imm:$src5))]>;
7359*9880d681SAndroid Build Coastguard Worker}
7360*9880d681SAndroid Build Coastguard Worker
7361*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7362*9880d681SAndroid Build Coastguard Worker  defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128", loadv2i64>,
7363*9880d681SAndroid Build Coastguard Worker                         Requires<[HasAVX]>;
7364*9880d681SAndroid Build Coastguard Worker  defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128", memopv2i64>,
7365*9880d681SAndroid Build Coastguard Worker                         Requires<[UseSSE42]>;
7366*9880d681SAndroid Build Coastguard Worker}
7367*9880d681SAndroid Build Coastguard Worker
7368*9880d681SAndroid Build Coastguard Workermulticlass SS42AI_pcmpestrm<string asm> {
7369*9880d681SAndroid Build Coastguard Worker  def rr : SS42AI<0x60, MRMSrcReg, (outs),
7370*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7371*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7372*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpEStrM]>;
7373*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
7374*9880d681SAndroid Build Coastguard Worker  def rm : SS42AI<0x60, MRMSrcMem, (outs),
7375*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7376*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7377*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpEStrMLd, ReadAfterLd]>;
7378*9880d681SAndroid Build Coastguard Worker}
7379*9880d681SAndroid Build Coastguard Worker
7380*9880d681SAndroid Build Coastguard Workerlet Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
7381*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in
7382*9880d681SAndroid Build Coastguard Worker  defm VPCMPESTRM128 : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
7383*9880d681SAndroid Build Coastguard Worker  defm PCMPESTRM128 :  SS42AI_pcmpestrm<"pcmpestrm">;
7384*9880d681SAndroid Build Coastguard Worker}
7385*9880d681SAndroid Build Coastguard Worker
7386*9880d681SAndroid Build Coastguard Worker// Packed Compare Implicit Length Strings, Return Index
7387*9880d681SAndroid Build Coastguard Workermulticlass pseudo_pcmpistri<string asm, PatFrag ld_frag> {
7388*9880d681SAndroid Build Coastguard Worker  def REG : PseudoI<(outs GR32:$dst),
7389*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7390*9880d681SAndroid Build Coastguard Worker    [(set GR32:$dst, EFLAGS,
7391*9880d681SAndroid Build Coastguard Worker      (X86pcmpistri VR128:$src1, VR128:$src2, imm:$src3))]>;
7392*9880d681SAndroid Build Coastguard Worker  def MEM : PseudoI<(outs GR32:$dst),
7393*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7394*9880d681SAndroid Build Coastguard Worker    [(set GR32:$dst, EFLAGS, (X86pcmpistri VR128:$src1,
7395*9880d681SAndroid Build Coastguard Worker                              (bc_v16i8 (ld_frag addr:$src2)), imm:$src3))]>;
7396*9880d681SAndroid Build Coastguard Worker}
7397*9880d681SAndroid Build Coastguard Worker
7398*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], usesCustomInserter = 1 in {
7399*9880d681SAndroid Build Coastguard Worker  defm VPCMPISTRI : pseudo_pcmpistri<"#VPCMPISTRI", loadv2i64>,
7400*9880d681SAndroid Build Coastguard Worker                      Requires<[HasAVX]>;
7401*9880d681SAndroid Build Coastguard Worker  defm PCMPISTRI  : pseudo_pcmpistri<"#PCMPISTRI", memopv2i64>,
7402*9880d681SAndroid Build Coastguard Worker                      Requires<[UseSSE42]>;
7403*9880d681SAndroid Build Coastguard Worker}
7404*9880d681SAndroid Build Coastguard Worker
7405*9880d681SAndroid Build Coastguard Workermulticlass SS42AI_pcmpistri<string asm> {
7406*9880d681SAndroid Build Coastguard Worker  def rr : SS42AI<0x63, MRMSrcReg, (outs),
7407*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7408*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7409*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpIStrI]>;
7410*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
7411*9880d681SAndroid Build Coastguard Worker  def rm : SS42AI<0x63, MRMSrcMem, (outs),
7412*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7413*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7414*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpIStrILd, ReadAfterLd]>;
7415*9880d681SAndroid Build Coastguard Worker}
7416*9880d681SAndroid Build Coastguard Worker
7417*9880d681SAndroid Build Coastguard Workerlet Defs = [ECX, EFLAGS], hasSideEffects = 0 in {
7418*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in
7419*9880d681SAndroid Build Coastguard Worker  defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
7420*9880d681SAndroid Build Coastguard Worker  defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
7421*9880d681SAndroid Build Coastguard Worker}
7422*9880d681SAndroid Build Coastguard Worker
7423*9880d681SAndroid Build Coastguard Worker// Packed Compare Explicit Length Strings, Return Index
7424*9880d681SAndroid Build Coastguard Workermulticlass pseudo_pcmpestri<string asm, PatFrag ld_frag> {
7425*9880d681SAndroid Build Coastguard Worker  def REG : PseudoI<(outs GR32:$dst),
7426*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7427*9880d681SAndroid Build Coastguard Worker    [(set GR32:$dst, EFLAGS,
7428*9880d681SAndroid Build Coastguard Worker      (X86pcmpestri VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7429*9880d681SAndroid Build Coastguard Worker  def MEM : PseudoI<(outs GR32:$dst),
7430*9880d681SAndroid Build Coastguard Worker                    (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7431*9880d681SAndroid Build Coastguard Worker    [(set GR32:$dst, EFLAGS,
7432*9880d681SAndroid Build Coastguard Worker      (X86pcmpestri VR128:$src1, EAX, (bc_v16i8 (ld_frag addr:$src3)), EDX,
7433*9880d681SAndroid Build Coastguard Worker       imm:$src5))]>;
7434*9880d681SAndroid Build Coastguard Worker}
7435*9880d681SAndroid Build Coastguard Worker
7436*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7437*9880d681SAndroid Build Coastguard Worker  defm VPCMPESTRI : pseudo_pcmpestri<"#VPCMPESTRI", loadv2i64>,
7438*9880d681SAndroid Build Coastguard Worker                      Requires<[HasAVX]>;
7439*9880d681SAndroid Build Coastguard Worker  defm PCMPESTRI  : pseudo_pcmpestri<"#PCMPESTRI", memopv2i64>,
7440*9880d681SAndroid Build Coastguard Worker                      Requires<[UseSSE42]>;
7441*9880d681SAndroid Build Coastguard Worker}
7442*9880d681SAndroid Build Coastguard Worker
7443*9880d681SAndroid Build Coastguard Workermulticlass SS42AI_pcmpestri<string asm> {
7444*9880d681SAndroid Build Coastguard Worker  def rr : SS42AI<0x61, MRMSrcReg, (outs),
7445*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7446*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7447*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpEStrI]>;
7448*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1 in
7449*9880d681SAndroid Build Coastguard Worker  def rm : SS42AI<0x61, MRMSrcMem, (outs),
7450*9880d681SAndroid Build Coastguard Worker    (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7451*9880d681SAndroid Build Coastguard Worker    !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7452*9880d681SAndroid Build Coastguard Worker    []>, Sched<[WritePCmpEStrILd, ReadAfterLd]>;
7453*9880d681SAndroid Build Coastguard Worker}
7454*9880d681SAndroid Build Coastguard Worker
7455*9880d681SAndroid Build Coastguard Workerlet Defs = [ECX, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
7456*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX] in
7457*9880d681SAndroid Build Coastguard Worker  defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
7458*9880d681SAndroid Build Coastguard Worker  defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
7459*9880d681SAndroid Build Coastguard Worker}
7460*9880d681SAndroid Build Coastguard Worker
7461*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7462*9880d681SAndroid Build Coastguard Worker// SSE4.2 - CRC Instructions
7463*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7464*9880d681SAndroid Build Coastguard Worker
7465*9880d681SAndroid Build Coastguard Worker// No CRC instructions have AVX equivalents
7466*9880d681SAndroid Build Coastguard Worker
7467*9880d681SAndroid Build Coastguard Worker// crc intrinsic instruction
7468*9880d681SAndroid Build Coastguard Worker// This set of instructions are only rm, the only difference is the size
7469*9880d681SAndroid Build Coastguard Worker// of r and m.
7470*9880d681SAndroid Build Coastguard Workerclass SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
7471*9880d681SAndroid Build Coastguard Worker                   RegisterClass RCIn, SDPatternOperator Int> :
7472*9880d681SAndroid Build Coastguard Worker  SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
7473*9880d681SAndroid Build Coastguard Worker         !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7474*9880d681SAndroid Build Coastguard Worker         [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))], IIC_CRC32_REG>,
7475*9880d681SAndroid Build Coastguard Worker         Sched<[WriteFAdd]>;
7476*9880d681SAndroid Build Coastguard Worker
7477*9880d681SAndroid Build Coastguard Workerclass SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
7478*9880d681SAndroid Build Coastguard Worker                   X86MemOperand x86memop, SDPatternOperator Int> :
7479*9880d681SAndroid Build Coastguard Worker  SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
7480*9880d681SAndroid Build Coastguard Worker         !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7481*9880d681SAndroid Build Coastguard Worker         [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))],
7482*9880d681SAndroid Build Coastguard Worker         IIC_CRC32_MEM>, Sched<[WriteFAddLd, ReadAfterLd]>;
7483*9880d681SAndroid Build Coastguard Worker
7484*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
7485*9880d681SAndroid Build Coastguard Worker  def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
7486*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_8>;
7487*9880d681SAndroid Build Coastguard Worker  def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
7488*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_8>;
7489*9880d681SAndroid Build Coastguard Worker  def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
7490*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_16>, OpSize16;
7491*9880d681SAndroid Build Coastguard Worker  def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
7492*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_16>, OpSize16;
7493*9880d681SAndroid Build Coastguard Worker  def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
7494*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_32>, OpSize32;
7495*9880d681SAndroid Build Coastguard Worker  def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
7496*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_32_32>, OpSize32;
7497*9880d681SAndroid Build Coastguard Worker  def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
7498*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_64_64>, REX_W;
7499*9880d681SAndroid Build Coastguard Worker  def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
7500*9880d681SAndroid Build Coastguard Worker                                 int_x86_sse42_crc32_64_64>, REX_W;
7501*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0 in {
7502*9880d681SAndroid Build Coastguard Worker    let mayLoad = 1 in
7503*9880d681SAndroid Build Coastguard Worker    def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
7504*9880d681SAndroid Build Coastguard Worker                                   null_frag>, REX_W;
7505*9880d681SAndroid Build Coastguard Worker    def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
7506*9880d681SAndroid Build Coastguard Worker                                   null_frag>, REX_W;
7507*9880d681SAndroid Build Coastguard Worker  }
7508*9880d681SAndroid Build Coastguard Worker}
7509*9880d681SAndroid Build Coastguard Worker
7510*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7511*9880d681SAndroid Build Coastguard Worker// SHA-NI Instructions
7512*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7513*9880d681SAndroid Build Coastguard Worker
7514*9880d681SAndroid Build Coastguard Workermulticlass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
7515*9880d681SAndroid Build Coastguard Worker                      bit UsesXMM0 = 0> {
7516*9880d681SAndroid Build Coastguard Worker  def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
7517*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, VR128:$src2),
7518*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7519*9880d681SAndroid Build Coastguard Worker             [!if(UsesXMM0,
7520*9880d681SAndroid Build Coastguard Worker                  (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
7521*9880d681SAndroid Build Coastguard Worker                  (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>, T8;
7522*9880d681SAndroid Build Coastguard Worker
7523*9880d681SAndroid Build Coastguard Worker  def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
7524*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, i128mem:$src2),
7525*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7526*9880d681SAndroid Build Coastguard Worker             [!if(UsesXMM0,
7527*9880d681SAndroid Build Coastguard Worker                  (set VR128:$dst, (IntId VR128:$src1,
7528*9880d681SAndroid Build Coastguard Worker                    (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
7529*9880d681SAndroid Build Coastguard Worker                  (set VR128:$dst, (IntId VR128:$src1,
7530*9880d681SAndroid Build Coastguard Worker                    (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8;
7531*9880d681SAndroid Build Coastguard Worker}
7532*9880d681SAndroid Build Coastguard Worker
7533*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
7534*9880d681SAndroid Build Coastguard Worker  def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
7535*9880d681SAndroid Build Coastguard Worker                         (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7536*9880d681SAndroid Build Coastguard Worker                         "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7537*9880d681SAndroid Build Coastguard Worker                         [(set VR128:$dst,
7538*9880d681SAndroid Build Coastguard Worker                           (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
7539*9880d681SAndroid Build Coastguard Worker                            (i8 imm:$src3)))]>, TA;
7540*9880d681SAndroid Build Coastguard Worker  def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
7541*9880d681SAndroid Build Coastguard Worker                         (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7542*9880d681SAndroid Build Coastguard Worker                         "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7543*9880d681SAndroid Build Coastguard Worker                         [(set VR128:$dst,
7544*9880d681SAndroid Build Coastguard Worker                           (int_x86_sha1rnds4 VR128:$src1,
7545*9880d681SAndroid Build Coastguard Worker                            (bc_v4i32 (memopv2i64 addr:$src2)),
7546*9880d681SAndroid Build Coastguard Worker                            (i8 imm:$src3)))]>, TA;
7547*9880d681SAndroid Build Coastguard Worker
7548*9880d681SAndroid Build Coastguard Worker  defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte>;
7549*9880d681SAndroid Build Coastguard Worker  defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1>;
7550*9880d681SAndroid Build Coastguard Worker  defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2>;
7551*9880d681SAndroid Build Coastguard Worker
7552*9880d681SAndroid Build Coastguard Worker  let Uses=[XMM0] in
7553*9880d681SAndroid Build Coastguard Worker  defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2, 1>;
7554*9880d681SAndroid Build Coastguard Worker
7555*9880d681SAndroid Build Coastguard Worker  defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1>;
7556*9880d681SAndroid Build Coastguard Worker  defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2>;
7557*9880d681SAndroid Build Coastguard Worker}
7558*9880d681SAndroid Build Coastguard Worker
7559*9880d681SAndroid Build Coastguard Worker// Aliases with explicit %xmm0
7560*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7561*9880d681SAndroid Build Coastguard Worker                (SHA256RNDS2rr VR128:$dst, VR128:$src2)>;
7562*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7563*9880d681SAndroid Build Coastguard Worker                (SHA256RNDS2rm VR128:$dst, i128mem:$src2)>;
7564*9880d681SAndroid Build Coastguard Worker
7565*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7566*9880d681SAndroid Build Coastguard Worker// AES-NI Instructions
7567*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7568*9880d681SAndroid Build Coastguard Worker
7569*9880d681SAndroid Build Coastguard Workermulticlass AESI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
7570*9880d681SAndroid Build Coastguard Worker                             PatFrag ld_frag, bit Is2Addr = 1> {
7571*9880d681SAndroid Build Coastguard Worker  def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7572*9880d681SAndroid Build Coastguard Worker       (ins VR128:$src1, VR128:$src2),
7573*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
7574*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7575*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7576*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7577*9880d681SAndroid Build Coastguard Worker       Sched<[WriteAESDecEnc]>;
7578*9880d681SAndroid Build Coastguard Worker  def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7579*9880d681SAndroid Build Coastguard Worker       (ins VR128:$src1, i128mem:$src2),
7580*9880d681SAndroid Build Coastguard Worker       !if(Is2Addr,
7581*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7582*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7583*9880d681SAndroid Build Coastguard Worker       [(set VR128:$dst,
7584*9880d681SAndroid Build Coastguard Worker         (IntId128 VR128:$src1, (ld_frag addr:$src2)))]>,
7585*9880d681SAndroid Build Coastguard Worker       Sched<[WriteAESDecEncLd, ReadAfterLd]>;
7586*9880d681SAndroid Build Coastguard Worker}
7587*9880d681SAndroid Build Coastguard Worker
7588*9880d681SAndroid Build Coastguard Worker// Perform One Round of an AES Encryption/Decryption Flow
7589*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, HasAES] in {
7590*9880d681SAndroid Build Coastguard Worker  defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7591*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesenc, loadv2i64, 0>, VEX_4V;
7592*9880d681SAndroid Build Coastguard Worker  defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7593*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesenclast, loadv2i64, 0>, VEX_4V;
7594*9880d681SAndroid Build Coastguard Worker  defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7595*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesdec, loadv2i64, 0>, VEX_4V;
7596*9880d681SAndroid Build Coastguard Worker  defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7597*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesdeclast, loadv2i64, 0>, VEX_4V;
7598*9880d681SAndroid Build Coastguard Worker}
7599*9880d681SAndroid Build Coastguard Worker
7600*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
7601*9880d681SAndroid Build Coastguard Worker  defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7602*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesenc, memopv2i64>;
7603*9880d681SAndroid Build Coastguard Worker  defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7604*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesenclast, memopv2i64>;
7605*9880d681SAndroid Build Coastguard Worker  defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7606*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesdec, memopv2i64>;
7607*9880d681SAndroid Build Coastguard Worker  defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7608*9880d681SAndroid Build Coastguard Worker                         int_x86_aesni_aesdeclast, memopv2i64>;
7609*9880d681SAndroid Build Coastguard Worker}
7610*9880d681SAndroid Build Coastguard Worker
7611*9880d681SAndroid Build Coastguard Worker// Perform the AES InvMixColumn Transformation
7612*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, HasAES] in {
7613*9880d681SAndroid Build Coastguard Worker  def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7614*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1),
7615*9880d681SAndroid Build Coastguard Worker      "vaesimc\t{$src1, $dst|$dst, $src1}",
7616*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
7617*9880d681SAndroid Build Coastguard Worker        (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>,
7618*9880d681SAndroid Build Coastguard Worker      VEX;
7619*9880d681SAndroid Build Coastguard Worker  def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7620*9880d681SAndroid Build Coastguard Worker      (ins i128mem:$src1),
7621*9880d681SAndroid Build Coastguard Worker      "vaesimc\t{$src1, $dst|$dst, $src1}",
7622*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
7623*9880d681SAndroid Build Coastguard Worker      Sched<[WriteAESIMCLd]>, VEX;
7624*9880d681SAndroid Build Coastguard Worker}
7625*9880d681SAndroid Build Coastguard Workerdef AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7626*9880d681SAndroid Build Coastguard Worker  (ins VR128:$src1),
7627*9880d681SAndroid Build Coastguard Worker  "aesimc\t{$src1, $dst|$dst, $src1}",
7628*9880d681SAndroid Build Coastguard Worker  [(set VR128:$dst,
7629*9880d681SAndroid Build Coastguard Worker    (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>;
7630*9880d681SAndroid Build Coastguard Workerdef AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7631*9880d681SAndroid Build Coastguard Worker  (ins i128mem:$src1),
7632*9880d681SAndroid Build Coastguard Worker  "aesimc\t{$src1, $dst|$dst, $src1}",
7633*9880d681SAndroid Build Coastguard Worker  [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7634*9880d681SAndroid Build Coastguard Worker  Sched<[WriteAESIMCLd]>;
7635*9880d681SAndroid Build Coastguard Worker
7636*9880d681SAndroid Build Coastguard Worker// AES Round Key Generation Assist
7637*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, HasAES] in {
7638*9880d681SAndroid Build Coastguard Worker  def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7639*9880d681SAndroid Build Coastguard Worker      (ins VR128:$src1, u8imm:$src2),
7640*9880d681SAndroid Build Coastguard Worker      "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7641*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
7642*9880d681SAndroid Build Coastguard Worker        (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7643*9880d681SAndroid Build Coastguard Worker      Sched<[WriteAESKeyGen]>, VEX;
7644*9880d681SAndroid Build Coastguard Worker  def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7645*9880d681SAndroid Build Coastguard Worker      (ins i128mem:$src1, u8imm:$src2),
7646*9880d681SAndroid Build Coastguard Worker      "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7647*9880d681SAndroid Build Coastguard Worker      [(set VR128:$dst,
7648*9880d681SAndroid Build Coastguard Worker        (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
7649*9880d681SAndroid Build Coastguard Worker      Sched<[WriteAESKeyGenLd]>, VEX;
7650*9880d681SAndroid Build Coastguard Worker}
7651*9880d681SAndroid Build Coastguard Workerdef AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7652*9880d681SAndroid Build Coastguard Worker  (ins VR128:$src1, u8imm:$src2),
7653*9880d681SAndroid Build Coastguard Worker  "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7654*9880d681SAndroid Build Coastguard Worker  [(set VR128:$dst,
7655*9880d681SAndroid Build Coastguard Worker    (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7656*9880d681SAndroid Build Coastguard Worker  Sched<[WriteAESKeyGen]>;
7657*9880d681SAndroid Build Coastguard Workerdef AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7658*9880d681SAndroid Build Coastguard Worker  (ins i128mem:$src1, u8imm:$src2),
7659*9880d681SAndroid Build Coastguard Worker  "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7660*9880d681SAndroid Build Coastguard Worker  [(set VR128:$dst,
7661*9880d681SAndroid Build Coastguard Worker    (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7662*9880d681SAndroid Build Coastguard Worker  Sched<[WriteAESKeyGenLd]>;
7663*9880d681SAndroid Build Coastguard Worker
7664*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7665*9880d681SAndroid Build Coastguard Worker// PCLMUL Instructions
7666*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7667*9880d681SAndroid Build Coastguard Worker
7668*9880d681SAndroid Build Coastguard Worker// AVX carry-less Multiplication instructions
7669*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
7670*9880d681SAndroid Build Coastguard Workerdef VPCLMULQDQrr : AVXPCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7671*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7672*9880d681SAndroid Build Coastguard Worker           "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7673*9880d681SAndroid Build Coastguard Worker           [(set VR128:$dst,
7674*9880d681SAndroid Build Coastguard Worker             (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>,
7675*9880d681SAndroid Build Coastguard Worker           Sched<[WriteCLMul]>;
7676*9880d681SAndroid Build Coastguard Worker
7677*9880d681SAndroid Build Coastguard Workerdef VPCLMULQDQrm : AVXPCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7678*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7679*9880d681SAndroid Build Coastguard Worker           "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7680*9880d681SAndroid Build Coastguard Worker           [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7681*9880d681SAndroid Build Coastguard Worker                              (loadv2i64 addr:$src2), imm:$src3))]>,
7682*9880d681SAndroid Build Coastguard Worker           Sched<[WriteCLMulLd, ReadAfterLd]>;
7683*9880d681SAndroid Build Coastguard Worker
7684*9880d681SAndroid Build Coastguard Worker// Carry-less Multiplication instructions
7685*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src1 = $dst" in {
7686*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
7687*9880d681SAndroid Build Coastguard Workerdef PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7688*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7689*9880d681SAndroid Build Coastguard Worker           "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7690*9880d681SAndroid Build Coastguard Worker           [(set VR128:$dst,
7691*9880d681SAndroid Build Coastguard Worker             (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
7692*9880d681SAndroid Build Coastguard Worker             IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
7693*9880d681SAndroid Build Coastguard Worker
7694*9880d681SAndroid Build Coastguard Workerdef PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7695*9880d681SAndroid Build Coastguard Worker           (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7696*9880d681SAndroid Build Coastguard Worker           "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7697*9880d681SAndroid Build Coastguard Worker           [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7698*9880d681SAndroid Build Coastguard Worker                              (memopv2i64 addr:$src2), imm:$src3))],
7699*9880d681SAndroid Build Coastguard Worker                              IIC_SSE_PCLMULQDQ_RM>,
7700*9880d681SAndroid Build Coastguard Worker           Sched<[WriteCLMulLd, ReadAfterLd]>;
7701*9880d681SAndroid Build Coastguard Worker} // Constraints = "$src1 = $dst"
7702*9880d681SAndroid Build Coastguard Worker
7703*9880d681SAndroid Build Coastguard Worker
7704*9880d681SAndroid Build Coastguard Workermulticlass pclmul_alias<string asm, int immop> {
7705*9880d681SAndroid Build Coastguard Worker  def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7706*9880d681SAndroid Build Coastguard Worker                  (PCLMULQDQrr VR128:$dst, VR128:$src, immop), 0>;
7707*9880d681SAndroid Build Coastguard Worker
7708*9880d681SAndroid Build Coastguard Worker  def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7709*9880d681SAndroid Build Coastguard Worker                  (PCLMULQDQrm VR128:$dst, i128mem:$src, immop), 0>;
7710*9880d681SAndroid Build Coastguard Worker
7711*9880d681SAndroid Build Coastguard Worker  def : InstAlias<!strconcat("vpclmul", asm,
7712*9880d681SAndroid Build Coastguard Worker                             "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7713*9880d681SAndroid Build Coastguard Worker                  (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop),
7714*9880d681SAndroid Build Coastguard Worker                  0>;
7715*9880d681SAndroid Build Coastguard Worker
7716*9880d681SAndroid Build Coastguard Worker  def : InstAlias<!strconcat("vpclmul", asm,
7717*9880d681SAndroid Build Coastguard Worker                             "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7718*9880d681SAndroid Build Coastguard Worker                  (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop),
7719*9880d681SAndroid Build Coastguard Worker                  0>;
7720*9880d681SAndroid Build Coastguard Worker}
7721*9880d681SAndroid Build Coastguard Workerdefm : pclmul_alias<"hqhq", 0x11>;
7722*9880d681SAndroid Build Coastguard Workerdefm : pclmul_alias<"hqlq", 0x01>;
7723*9880d681SAndroid Build Coastguard Workerdefm : pclmul_alias<"lqhq", 0x10>;
7724*9880d681SAndroid Build Coastguard Workerdefm : pclmul_alias<"lqlq", 0x00>;
7725*9880d681SAndroid Build Coastguard Worker
7726*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7727*9880d681SAndroid Build Coastguard Worker// SSE4A Instructions
7728*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7729*9880d681SAndroid Build Coastguard Worker
7730*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasSSE4A] in {
7731*9880d681SAndroid Build Coastguard Worker
7732*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $dst" in {
7733*9880d681SAndroid Build Coastguard Workerdef EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst),
7734*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src, u8imm:$len, u8imm:$idx),
7735*9880d681SAndroid Build Coastguard Worker                 "extrq\t{$idx, $len, $src|$src, $len, $idx}",
7736*9880d681SAndroid Build Coastguard Worker                 [(set VR128:$dst, (X86extrqi VR128:$src, imm:$len,
7737*9880d681SAndroid Build Coastguard Worker                                    imm:$idx))]>, PD;
7738*9880d681SAndroid Build Coastguard Workerdef EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7739*9880d681SAndroid Build Coastguard Worker              (ins VR128:$src, VR128:$mask),
7740*9880d681SAndroid Build Coastguard Worker              "extrq\t{$mask, $src|$src, $mask}",
7741*9880d681SAndroid Build Coastguard Worker              [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
7742*9880d681SAndroid Build Coastguard Worker                                 VR128:$mask))]>, PD;
7743*9880d681SAndroid Build Coastguard Worker
7744*9880d681SAndroid Build Coastguard Workerdef INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
7745*9880d681SAndroid Build Coastguard Worker                   (ins VR128:$src, VR128:$src2, u8imm:$len, u8imm:$idx),
7746*9880d681SAndroid Build Coastguard Worker                   "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
7747*9880d681SAndroid Build Coastguard Worker                   [(set VR128:$dst, (X86insertqi VR128:$src, VR128:$src2,
7748*9880d681SAndroid Build Coastguard Worker                                      imm:$len, imm:$idx))]>, XD;
7749*9880d681SAndroid Build Coastguard Workerdef INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7750*9880d681SAndroid Build Coastguard Worker                 (ins VR128:$src, VR128:$mask),
7751*9880d681SAndroid Build Coastguard Worker                 "insertq\t{$mask, $src|$src, $mask}",
7752*9880d681SAndroid Build Coastguard Worker                 [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
7753*9880d681SAndroid Build Coastguard Worker                                    VR128:$mask))]>, XD;
7754*9880d681SAndroid Build Coastguard Worker}
7755*9880d681SAndroid Build Coastguard Worker
7756*9880d681SAndroid Build Coastguard Worker// Non-temporal (unaligned) scalar stores.
7757*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 400 in { // Prefer non-temporal versions
7758*9880d681SAndroid Build Coastguard Workerlet mayStore = 1, SchedRW = [WriteStore] in {
7759*9880d681SAndroid Build Coastguard Workerdef MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
7760*9880d681SAndroid Build Coastguard Worker                "movntss\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVNT>, XS;
7761*9880d681SAndroid Build Coastguard Worker
7762*9880d681SAndroid Build Coastguard Workerdef MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
7763*9880d681SAndroid Build Coastguard Worker                "movntsd\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVNT>, XD;
7764*9880d681SAndroid Build Coastguard Worker} // SchedRW
7765*9880d681SAndroid Build Coastguard Worker
7766*9880d681SAndroid Build Coastguard Workerdef : Pat<(nontemporalstore FR32:$src, addr:$dst),
7767*9880d681SAndroid Build Coastguard Worker          (MOVNTSS addr:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
7768*9880d681SAndroid Build Coastguard Worker
7769*9880d681SAndroid Build Coastguard Workerdef : Pat<(nontemporalstore FR64:$src, addr:$dst),
7770*9880d681SAndroid Build Coastguard Worker          (MOVNTSD addr:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
7771*9880d681SAndroid Build Coastguard Worker
7772*9880d681SAndroid Build Coastguard Worker} // AddedComplexity
7773*9880d681SAndroid Build Coastguard Worker} // HasSSE4A
7774*9880d681SAndroid Build Coastguard Worker
7775*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7776*9880d681SAndroid Build Coastguard Worker// AVX Instructions
7777*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7778*9880d681SAndroid Build Coastguard Worker
7779*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7780*9880d681SAndroid Build Coastguard Worker// VBROADCAST - Load from memory and broadcast to all elements of the
7781*9880d681SAndroid Build Coastguard Worker//              destination operand
7782*9880d681SAndroid Build Coastguard Worker//
7783*9880d681SAndroid Build Coastguard Workerclass avx_broadcast_rm<bits<8> opc, string OpcodeStr, RegisterClass RC,
7784*9880d681SAndroid Build Coastguard Worker                           X86MemOperand x86memop, ValueType VT,
7785*9880d681SAndroid Build Coastguard Worker                           PatFrag ld_frag, SchedWrite Sched> :
7786*9880d681SAndroid Build Coastguard Worker  AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7787*9880d681SAndroid Build Coastguard Worker        !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7788*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst, (VT (X86VBroadcast (ld_frag addr:$src))))]>,
7789*9880d681SAndroid Build Coastguard Worker        Sched<[Sched]>, VEX;
7790*9880d681SAndroid Build Coastguard Worker
7791*9880d681SAndroid Build Coastguard Worker// AVX2 adds register forms
7792*9880d681SAndroid Build Coastguard Workerclass avx2_broadcast_rr<bits<8> opc, string OpcodeStr, RegisterClass RC,
7793*9880d681SAndroid Build Coastguard Worker                        ValueType ResVT, ValueType OpVT, SchedWrite Sched> :
7794*9880d681SAndroid Build Coastguard Worker  AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7795*9880d681SAndroid Build Coastguard Worker         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7796*9880d681SAndroid Build Coastguard Worker         [(set RC:$dst, (ResVT (X86VBroadcast (OpVT VR128:$src))))]>,
7797*9880d681SAndroid Build Coastguard Worker         Sched<[Sched]>, VEX;
7798*9880d681SAndroid Build Coastguard Worker
7799*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle, Predicates = [HasAVX, NoVLX] in {
7800*9880d681SAndroid Build Coastguard Worker  def VBROADCASTSSrm  : avx_broadcast_rm<0x18, "vbroadcastss", VR128,
7801*9880d681SAndroid Build Coastguard Worker                                             f32mem, v4f32, loadf32, WriteLoad>;
7802*9880d681SAndroid Build Coastguard Worker  def VBROADCASTSSYrm : avx_broadcast_rm<0x18, "vbroadcastss", VR256,
7803*9880d681SAndroid Build Coastguard Worker                                             f32mem, v8f32, loadf32,
7804*9880d681SAndroid Build Coastguard Worker                                             WriteFShuffleLd>, VEX_L;
7805*9880d681SAndroid Build Coastguard Worker}
7806*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble, Predicates = [HasAVX, NoVLX] in
7807*9880d681SAndroid Build Coastguard Workerdef VBROADCASTSDYrm  : avx_broadcast_rm<0x19, "vbroadcastsd", VR256, f64mem,
7808*9880d681SAndroid Build Coastguard Worker                                    v4f64, loadf64, WriteFShuffleLd>, VEX_L;
7809*9880d681SAndroid Build Coastguard Worker
7810*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle, Predicates = [HasAVX2, NoVLX] in {
7811*9880d681SAndroid Build Coastguard Worker  def VBROADCASTSSrr  : avx2_broadcast_rr<0x18, "vbroadcastss", VR128,
7812*9880d681SAndroid Build Coastguard Worker                                          v4f32, v4f32, WriteFShuffle>;
7813*9880d681SAndroid Build Coastguard Worker  def VBROADCASTSSYrr : avx2_broadcast_rr<0x18, "vbroadcastss", VR256,
7814*9880d681SAndroid Build Coastguard Worker                                          v8f32, v4f32, WriteFShuffle256>, VEX_L;
7815*9880d681SAndroid Build Coastguard Worker}
7816*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble, Predicates = [HasAVX2, NoVLX] in
7817*9880d681SAndroid Build Coastguard Workerdef VBROADCASTSDYrr  : avx2_broadcast_rr<0x19, "vbroadcastsd", VR256,
7818*9880d681SAndroid Build Coastguard Worker                                         v4f64, v2f64, WriteFShuffle256>, VEX_L;
7819*9880d681SAndroid Build Coastguard Worker
7820*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, hasSideEffects = 0, Predicates = [HasAVX2] in
7821*9880d681SAndroid Build Coastguard Workerdef VBROADCASTI128 : AVX8I<0x5A, MRMSrcMem, (outs VR256:$dst),
7822*9880d681SAndroid Build Coastguard Worker                           (ins i128mem:$src),
7823*9880d681SAndroid Build Coastguard Worker                           "vbroadcasti128\t{$src, $dst|$dst, $src}", []>,
7824*9880d681SAndroid Build Coastguard Worker                           Sched<[WriteLoad]>, VEX, VEX_L;
7825*9880d681SAndroid Build Coastguard Worker
7826*9880d681SAndroid Build Coastguard Workerdef VBROADCASTF128 : AVX8I<0x1A, MRMSrcMem, (outs VR256:$dst),
7827*9880d681SAndroid Build Coastguard Worker                           (ins f128mem:$src),
7828*9880d681SAndroid Build Coastguard Worker                           "vbroadcastf128\t{$src, $dst|$dst, $src}",
7829*9880d681SAndroid Build Coastguard Worker                           [(set VR256:$dst,
7830*9880d681SAndroid Build Coastguard Worker                              (int_x86_avx_vbroadcastf128_pd_256 addr:$src))]>,
7831*9880d681SAndroid Build Coastguard Worker                           Sched<[WriteFShuffleLd]>, VEX, VEX_L;
7832*9880d681SAndroid Build Coastguard Worker
7833*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in
7834*9880d681SAndroid Build Coastguard Workerdef : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7835*9880d681SAndroid Build Coastguard Worker          (VBROADCASTF128 addr:$src)>;
7836*9880d681SAndroid Build Coastguard Worker
7837*9880d681SAndroid Build Coastguard Worker
7838*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7839*9880d681SAndroid Build Coastguard Worker// VINSERTF128 - Insert packed floating-point values
7840*9880d681SAndroid Build Coastguard Worker//
7841*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7842*9880d681SAndroid Build Coastguard Workerdef VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7843*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, VR128:$src2, u8imm:$src3),
7844*9880d681SAndroid Build Coastguard Worker          "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7845*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteFShuffle]>, VEX_4V, VEX_L;
7846*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
7847*9880d681SAndroid Build Coastguard Workerdef VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7848*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, f128mem:$src2, u8imm:$src3),
7849*9880d681SAndroid Build Coastguard Worker          "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7850*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteFShuffleLd, ReadAfterLd]>, VEX_4V, VEX_L;
7851*9880d681SAndroid Build Coastguard Worker}
7852*9880d681SAndroid Build Coastguard Worker
7853*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
7854*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7855*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7856*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7857*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7858*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7859*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7860*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7861*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7862*9880d681SAndroid Build Coastguard Worker
7863*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (loadv4f32 addr:$src2),
7864*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7865*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7866*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7867*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (loadv2f64 addr:$src2),
7868*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7869*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7870*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7871*9880d681SAndroid Build Coastguard Worker}
7872*9880d681SAndroid Build Coastguard Worker
7873*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
7874*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7875*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7876*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7877*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7878*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7879*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7880*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7881*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7882*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7883*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7884*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7885*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7886*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7887*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7888*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rr VR256:$src1, VR128:$src2,
7889*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7890*9880d681SAndroid Build Coastguard Worker
7891*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
7892*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7893*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7894*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7895*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
7896*9880d681SAndroid Build Coastguard Worker                                   (bc_v4i32 (loadv2i64 addr:$src2)),
7897*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7898*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7899*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7900*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
7901*9880d681SAndroid Build Coastguard Worker                                   (bc_v16i8 (loadv2i64 addr:$src2)),
7902*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7903*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7904*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7905*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
7906*9880d681SAndroid Build Coastguard Worker                                   (bc_v8i16 (loadv2i64 addr:$src2)),
7907*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
7908*9880d681SAndroid Build Coastguard Worker          (VINSERTF128rm VR256:$src1, addr:$src2,
7909*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
7910*9880d681SAndroid Build Coastguard Worker}
7911*9880d681SAndroid Build Coastguard Worker
7912*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7913*9880d681SAndroid Build Coastguard Worker// VEXTRACTF128 - Extract packed floating-point values
7914*9880d681SAndroid Build Coastguard Worker//
7915*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7916*9880d681SAndroid Build Coastguard Workerdef VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7917*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, u8imm:$src2),
7918*9880d681SAndroid Build Coastguard Worker          "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7919*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteFShuffle]>, VEX, VEX_L;
7920*9880d681SAndroid Build Coastguard Workerlet mayStore = 1 in
7921*9880d681SAndroid Build Coastguard Workerdef VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7922*9880d681SAndroid Build Coastguard Worker          (ins f128mem:$dst, VR256:$src1, u8imm:$src2),
7923*9880d681SAndroid Build Coastguard Worker          "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7924*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteStore]>, VEX, VEX_L;
7925*9880d681SAndroid Build Coastguard Worker}
7926*9880d681SAndroid Build Coastguard Worker
7927*9880d681SAndroid Build Coastguard Worker// AVX1 patterns
7928*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
7929*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7930*9880d681SAndroid Build Coastguard Worker          (v4f32 (VEXTRACTF128rr
7931*9880d681SAndroid Build Coastguard Worker                    (v8f32 VR256:$src1),
7932*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7933*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7934*9880d681SAndroid Build Coastguard Worker          (v2f64 (VEXTRACTF128rr
7935*9880d681SAndroid Build Coastguard Worker                    (v4f64 VR256:$src1),
7936*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7937*9880d681SAndroid Build Coastguard Worker
7938*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v4f32 (vextract128_extract:$ext (v8f32 VR256:$src1),
7939*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7940*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7941*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7942*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v2f64 (vextract128_extract:$ext (v4f64 VR256:$src1),
7943*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7944*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7945*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7946*9880d681SAndroid Build Coastguard Worker}
7947*9880d681SAndroid Build Coastguard Worker
7948*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
7949*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7950*9880d681SAndroid Build Coastguard Worker          (v2i64 (VEXTRACTF128rr
7951*9880d681SAndroid Build Coastguard Worker                  (v4i64 VR256:$src1),
7952*9880d681SAndroid Build Coastguard Worker                  (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7953*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7954*9880d681SAndroid Build Coastguard Worker          (v4i32 (VEXTRACTF128rr
7955*9880d681SAndroid Build Coastguard Worker                  (v8i32 VR256:$src1),
7956*9880d681SAndroid Build Coastguard Worker                  (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7957*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7958*9880d681SAndroid Build Coastguard Worker          (v8i16 (VEXTRACTF128rr
7959*9880d681SAndroid Build Coastguard Worker                  (v16i16 VR256:$src1),
7960*9880d681SAndroid Build Coastguard Worker                  (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7961*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7962*9880d681SAndroid Build Coastguard Worker          (v16i8 (VEXTRACTF128rr
7963*9880d681SAndroid Build Coastguard Worker                  (v32i8 VR256:$src1),
7964*9880d681SAndroid Build Coastguard Worker                  (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7965*9880d681SAndroid Build Coastguard Worker
7966*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
7967*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7968*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7969*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7970*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
7971*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7972*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7973*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7974*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
7975*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7976*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7977*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7978*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
7979*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
7980*9880d681SAndroid Build Coastguard Worker          (VEXTRACTF128mr addr:$dst, VR256:$src1,
7981*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
7982*9880d681SAndroid Build Coastguard Worker}
7983*9880d681SAndroid Build Coastguard Worker
7984*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
7985*9880d681SAndroid Build Coastguard Worker// VMASKMOV - Conditional SIMD Packed Loads and Stores
7986*9880d681SAndroid Build Coastguard Worker//
7987*9880d681SAndroid Build Coastguard Workermulticlass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7988*9880d681SAndroid Build Coastguard Worker                          Intrinsic IntLd, Intrinsic IntLd256,
7989*9880d681SAndroid Build Coastguard Worker                          Intrinsic IntSt, Intrinsic IntSt256> {
7990*9880d681SAndroid Build Coastguard Worker  def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7991*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, f128mem:$src2),
7992*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7993*9880d681SAndroid Build Coastguard Worker             [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7994*9880d681SAndroid Build Coastguard Worker             VEX_4V;
7995*9880d681SAndroid Build Coastguard Worker  def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7996*9880d681SAndroid Build Coastguard Worker             (ins VR256:$src1, f256mem:$src2),
7997*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7998*9880d681SAndroid Build Coastguard Worker             [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7999*9880d681SAndroid Build Coastguard Worker             VEX_4V, VEX_L;
8000*9880d681SAndroid Build Coastguard Worker  def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
8001*9880d681SAndroid Build Coastguard Worker             (ins f128mem:$dst, VR128:$src1, VR128:$src2),
8002*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8003*9880d681SAndroid Build Coastguard Worker             [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8004*9880d681SAndroid Build Coastguard Worker  def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
8005*9880d681SAndroid Build Coastguard Worker             (ins f256mem:$dst, VR256:$src1, VR256:$src2),
8006*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8007*9880d681SAndroid Build Coastguard Worker             [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8008*9880d681SAndroid Build Coastguard Worker}
8009*9880d681SAndroid Build Coastguard Worker
8010*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in
8011*9880d681SAndroid Build Coastguard Workerdefm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
8012*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskload_ps,
8013*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskload_ps_256,
8014*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskstore_ps,
8015*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskstore_ps_256>;
8016*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in
8017*9880d681SAndroid Build Coastguard Workerdefm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
8018*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskload_pd,
8019*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskload_pd_256,
8020*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskstore_pd,
8021*9880d681SAndroid Build Coastguard Worker                                 int_x86_avx_maskstore_pd_256>;
8022*9880d681SAndroid Build Coastguard Worker
8023*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8024*9880d681SAndroid Build Coastguard Worker// VPERMIL - Permute Single and Double Floating-Point Values
8025*9880d681SAndroid Build Coastguard Worker//
8026*9880d681SAndroid Build Coastguard Workermulticlass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
8027*9880d681SAndroid Build Coastguard Worker                      RegisterClass RC, X86MemOperand x86memop_f,
8028*9880d681SAndroid Build Coastguard Worker                      X86MemOperand x86memop_i, PatFrag i_frag,
8029*9880d681SAndroid Build Coastguard Worker                      ValueType f_vt, ValueType i_vt> {
8030*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX, NoVLX] in {
8031*9880d681SAndroid Build Coastguard Worker    def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
8032*9880d681SAndroid Build Coastguard Worker               (ins RC:$src1, RC:$src2),
8033*9880d681SAndroid Build Coastguard Worker               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8034*9880d681SAndroid Build Coastguard Worker               [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1, (i_vt RC:$src2))))]>, VEX_4V,
8035*9880d681SAndroid Build Coastguard Worker               Sched<[WriteFShuffle]>;
8036*9880d681SAndroid Build Coastguard Worker    def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
8037*9880d681SAndroid Build Coastguard Worker               (ins RC:$src1, x86memop_i:$src2),
8038*9880d681SAndroid Build Coastguard Worker               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8039*9880d681SAndroid Build Coastguard Worker               [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1,
8040*9880d681SAndroid Build Coastguard Worker                              (i_vt (bitconvert (i_frag addr:$src2))))))]>, VEX_4V,
8041*9880d681SAndroid Build Coastguard Worker               Sched<[WriteFShuffleLd, ReadAfterLd]>;
8042*9880d681SAndroid Build Coastguard Worker
8043*9880d681SAndroid Build Coastguard Worker    def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
8044*9880d681SAndroid Build Coastguard Worker             (ins RC:$src1, u8imm:$src2),
8045*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8046*9880d681SAndroid Build Coastguard Worker             [(set RC:$dst, (f_vt (X86VPermilpi RC:$src1, (i8 imm:$src2))))]>, VEX,
8047*9880d681SAndroid Build Coastguard Worker             Sched<[WriteFShuffle]>;
8048*9880d681SAndroid Build Coastguard Worker    def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
8049*9880d681SAndroid Build Coastguard Worker             (ins x86memop_f:$src1, u8imm:$src2),
8050*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8051*9880d681SAndroid Build Coastguard Worker             [(set RC:$dst,
8052*9880d681SAndroid Build Coastguard Worker               (f_vt (X86VPermilpi (load addr:$src1), (i8 imm:$src2))))]>, VEX,
8053*9880d681SAndroid Build Coastguard Worker             Sched<[WriteFShuffleLd]>;
8054*9880d681SAndroid Build Coastguard Worker  }// Predicates = [HasAVX, NoVLX]
8055*9880d681SAndroid Build Coastguard Worker}
8056*9880d681SAndroid Build Coastguard Worker
8057*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
8058*9880d681SAndroid Build Coastguard Worker  defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
8059*9880d681SAndroid Build Coastguard Worker                               loadv2i64, v4f32, v4i32>;
8060*9880d681SAndroid Build Coastguard Worker  defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
8061*9880d681SAndroid Build Coastguard Worker                               loadv4i64, v8f32, v8i32>, VEX_L;
8062*9880d681SAndroid Build Coastguard Worker}
8063*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in {
8064*9880d681SAndroid Build Coastguard Worker  defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
8065*9880d681SAndroid Build Coastguard Worker                               loadv2i64, v2f64, v2i64>;
8066*9880d681SAndroid Build Coastguard Worker  defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
8067*9880d681SAndroid Build Coastguard Worker                               loadv4i64, v4f64, v4i64>, VEX_L;
8068*9880d681SAndroid Build Coastguard Worker}
8069*9880d681SAndroid Build Coastguard Worker
8070*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX] in {
8071*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (X86VPermilpv VR256:$src1, (v8i32 VR256:$src2))),
8072*9880d681SAndroid Build Coastguard Worker          (VPERMILPSYrr VR256:$src1, VR256:$src2)>;
8073*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8f32 (X86VPermilpv VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
8074*9880d681SAndroid Build Coastguard Worker          (VPERMILPSYrm VR256:$src1, addr:$src2)>;
8075*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86VPermilpv VR256:$src1, (v4i64 VR256:$src2))),
8076*9880d681SAndroid Build Coastguard Worker          (VPERMILPDYrr VR256:$src1, VR256:$src2)>;
8077*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86VPermilpv VR256:$src1, (loadv4i64 addr:$src2))),
8078*9880d681SAndroid Build Coastguard Worker          (VPERMILPDYrm VR256:$src1, addr:$src2)>;
8079*9880d681SAndroid Build Coastguard Worker
8080*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8081*9880d681SAndroid Build Coastguard Worker          (VPERMILPSYri VR256:$src1, imm:$imm)>;
8082*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8083*9880d681SAndroid Build Coastguard Worker          (VPERMILPDYri VR256:$src1, imm:$imm)>;
8084*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPermilpi (bc_v8i32 (loadv4i64 addr:$src1)),
8085*9880d681SAndroid Build Coastguard Worker                               (i8 imm:$imm))),
8086*9880d681SAndroid Build Coastguard Worker          (VPERMILPSYmi addr:$src1, imm:$imm)>;
8087*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86VPermilpi (loadv4i64 addr:$src1), (i8 imm:$imm))),
8088*9880d681SAndroid Build Coastguard Worker          (VPERMILPDYmi addr:$src1, imm:$imm)>;
8089*9880d681SAndroid Build Coastguard Worker
8090*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86VPermilpv VR128:$src1, (v4i32 VR128:$src2))),
8091*9880d681SAndroid Build Coastguard Worker          (VPERMILPSrr VR128:$src1, VR128:$src2)>;
8092*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f32 (X86VPermilpv VR128:$src1, (bc_v4i32 (loadv2i64 addr:$src2)))),
8093*9880d681SAndroid Build Coastguard Worker          (VPERMILPSrm VR128:$src1, addr:$src2)>;
8094*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86VPermilpv VR128:$src1, (v2i64 VR128:$src2))),
8095*9880d681SAndroid Build Coastguard Worker          (VPERMILPDrr VR128:$src1, VR128:$src2)>;
8096*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2f64 (X86VPermilpv VR128:$src1, (loadv2i64 addr:$src2))),
8097*9880d681SAndroid Build Coastguard Worker          (VPERMILPDrm VR128:$src1, addr:$src2)>;
8098*9880d681SAndroid Build Coastguard Worker
8099*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (X86VPermilpi VR128:$src1, (i8 imm:$imm))),
8100*9880d681SAndroid Build Coastguard Worker          (VPERMILPDri VR128:$src1, imm:$imm)>;
8101*9880d681SAndroid Build Coastguard Workerdef : Pat<(v2i64 (X86VPermilpi (loadv2i64 addr:$src1), (i8 imm:$imm))),
8102*9880d681SAndroid Build Coastguard Worker          (VPERMILPDmi addr:$src1, imm:$imm)>;
8103*9880d681SAndroid Build Coastguard Worker}
8104*9880d681SAndroid Build Coastguard Worker
8105*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8106*9880d681SAndroid Build Coastguard Worker// VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
8107*9880d681SAndroid Build Coastguard Worker//
8108*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in {
8109*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
8110*9880d681SAndroid Build Coastguard Workerdef VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
8111*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, VR256:$src2, u8imm:$src3),
8112*9880d681SAndroid Build Coastguard Worker          "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8113*9880d681SAndroid Build Coastguard Worker          [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8114*9880d681SAndroid Build Coastguard Worker                              (i8 imm:$src3))))]>, VEX_4V, VEX_L,
8115*9880d681SAndroid Build Coastguard Worker          Sched<[WriteFShuffle]>;
8116*9880d681SAndroid Build Coastguard Workerdef VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
8117*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
8118*9880d681SAndroid Build Coastguard Worker          "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8119*9880d681SAndroid Build Coastguard Worker          [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv8f32 addr:$src2),
8120*9880d681SAndroid Build Coastguard Worker                             (i8 imm:$src3)))]>, VEX_4V, VEX_L,
8121*9880d681SAndroid Build Coastguard Worker          Sched<[WriteFShuffleLd, ReadAfterLd]>;
8122*9880d681SAndroid Build Coastguard Worker}
8123*9880d681SAndroid Build Coastguard Worker
8124*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
8125*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8126*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8127*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
8128*9880d681SAndroid Build Coastguard Worker                  (loadv4f64 addr:$src2), (i8 imm:$imm))),
8129*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8130*9880d681SAndroid Build Coastguard Worker}
8131*9880d681SAndroid Build Coastguard Worker
8132*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
8133*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8134*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8135*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8136*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8137*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8138*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8139*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8140*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8141*9880d681SAndroid Build Coastguard Worker
8142*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
8143*9880d681SAndroid Build Coastguard Worker                  (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8144*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8145*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
8146*9880d681SAndroid Build Coastguard Worker                  (loadv4i64 addr:$src2), (i8 imm:$imm))),
8147*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8148*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
8149*9880d681SAndroid Build Coastguard Worker                  (bc_v32i8 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8150*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8151*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8152*9880d681SAndroid Build Coastguard Worker                  (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8153*9880d681SAndroid Build Coastguard Worker          (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8154*9880d681SAndroid Build Coastguard Worker}
8155*9880d681SAndroid Build Coastguard Worker
8156*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8157*9880d681SAndroid Build Coastguard Worker// VZERO - Zero YMM registers
8158*9880d681SAndroid Build Coastguard Worker//
8159*9880d681SAndroid Build Coastguard Workerlet Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
8160*9880d681SAndroid Build Coastguard Worker            YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
8161*9880d681SAndroid Build Coastguard Worker  // Zero All YMM registers
8162*9880d681SAndroid Build Coastguard Worker  def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
8163*9880d681SAndroid Build Coastguard Worker                  [(int_x86_avx_vzeroall)]>, PS, VEX, VEX_L, Requires<[HasAVX]>;
8164*9880d681SAndroid Build Coastguard Worker
8165*9880d681SAndroid Build Coastguard Worker  // Zero Upper bits of YMM registers
8166*9880d681SAndroid Build Coastguard Worker  def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
8167*9880d681SAndroid Build Coastguard Worker                     [(int_x86_avx_vzeroupper)]>, PS, VEX, Requires<[HasAVX]>;
8168*9880d681SAndroid Build Coastguard Worker}
8169*9880d681SAndroid Build Coastguard Worker
8170*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8171*9880d681SAndroid Build Coastguard Worker// Half precision conversion instructions
8172*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8173*9880d681SAndroid Build Coastguard Workermulticlass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8174*9880d681SAndroid Build Coastguard Worker  def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8175*9880d681SAndroid Build Coastguard Worker             "vcvtph2ps\t{$src, $dst|$dst, $src}",
8176*9880d681SAndroid Build Coastguard Worker             [(set RC:$dst, (Int VR128:$src))]>,
8177*9880d681SAndroid Build Coastguard Worker             T8PD, VEX, Sched<[WriteCvtF2F]>;
8178*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0, mayLoad = 1 in
8179*9880d681SAndroid Build Coastguard Worker  def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8180*9880d681SAndroid Build Coastguard Worker             "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8PD, VEX,
8181*9880d681SAndroid Build Coastguard Worker             Sched<[WriteCvtF2FLd]>;
8182*9880d681SAndroid Build Coastguard Worker}
8183*9880d681SAndroid Build Coastguard Worker
8184*9880d681SAndroid Build Coastguard Workermulticlass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8185*9880d681SAndroid Build Coastguard Worker  def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
8186*9880d681SAndroid Build Coastguard Worker               (ins RC:$src1, i32u8imm:$src2),
8187*9880d681SAndroid Build Coastguard Worker               "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8188*9880d681SAndroid Build Coastguard Worker               [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
8189*9880d681SAndroid Build Coastguard Worker               TAPD, VEX, Sched<[WriteCvtF2F]>;
8190*9880d681SAndroid Build Coastguard Worker  let hasSideEffects = 0, mayStore = 1,
8191*9880d681SAndroid Build Coastguard Worker      SchedRW = [WriteCvtF2FLd, WriteRMW] in
8192*9880d681SAndroid Build Coastguard Worker  def mr : Ii8<0x1D, MRMDestMem, (outs),
8193*9880d681SAndroid Build Coastguard Worker               (ins x86memop:$dst, RC:$src1, i32u8imm:$src2),
8194*9880d681SAndroid Build Coastguard Worker               "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8195*9880d681SAndroid Build Coastguard Worker               TAPD, VEX;
8196*9880d681SAndroid Build Coastguard Worker}
8197*9880d681SAndroid Build Coastguard Worker
8198*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasF16C] in {
8199*9880d681SAndroid Build Coastguard Worker  defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
8200*9880d681SAndroid Build Coastguard Worker  defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>, VEX_L;
8201*9880d681SAndroid Build Coastguard Worker  defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
8202*9880d681SAndroid Build Coastguard Worker  defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>, VEX_L;
8203*9880d681SAndroid Build Coastguard Worker
8204*9880d681SAndroid Build Coastguard Worker  // Pattern match vcvtph2ps of a scalar i64 load.
8205*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_vcvtph2ps_128 (vzmovl_v2i64 addr:$src)),
8206*9880d681SAndroid Build Coastguard Worker            (VCVTPH2PSrm addr:$src)>;
8207*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_vcvtph2ps_128 (vzload_v2i64 addr:$src)),
8208*9880d681SAndroid Build Coastguard Worker            (VCVTPH2PSrm addr:$src)>;
8209*9880d681SAndroid Build Coastguard Worker  def : Pat<(int_x86_vcvtph2ps_128 (bitconvert
8210*9880d681SAndroid Build Coastguard Worker              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
8211*9880d681SAndroid Build Coastguard Worker            (VCVTPH2PSrm addr:$src)>;
8212*9880d681SAndroid Build Coastguard Worker
8213*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (f64 (extractelt (bc_v2f64 (v8i16
8214*9880d681SAndroid Build Coastguard Worker                  (int_x86_vcvtps2ph_128 VR128:$src1, i32:$src2))), (iPTR 0))),
8215*9880d681SAndroid Build Coastguard Worker                   addr:$dst),
8216*9880d681SAndroid Build Coastguard Worker                   (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
8217*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (i64 (extractelt (bc_v2i64 (v8i16
8218*9880d681SAndroid Build Coastguard Worker                  (int_x86_vcvtps2ph_128 VR128:$src1, i32:$src2))), (iPTR 0))),
8219*9880d681SAndroid Build Coastguard Worker                   addr:$dst),
8220*9880d681SAndroid Build Coastguard Worker                   (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
8221*9880d681SAndroid Build Coastguard Worker  def : Pat<(store (v8i16 (int_x86_vcvtps2ph_256 VR256:$src1, i32:$src2)),
8222*9880d681SAndroid Build Coastguard Worker                   addr:$dst),
8223*9880d681SAndroid Build Coastguard Worker                   (VCVTPS2PHYmr addr:$dst, VR256:$src1, imm:$src2)>;
8224*9880d681SAndroid Build Coastguard Worker}
8225*9880d681SAndroid Build Coastguard Worker
8226*9880d681SAndroid Build Coastguard Worker// Patterns for  matching conversions from float to half-float and vice versa.
8227*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasF16C] in {
8228*9880d681SAndroid Build Coastguard Worker  // Use MXCSR.RC for rounding instead of explicitly specifying the default
8229*9880d681SAndroid Build Coastguard Worker  // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
8230*9880d681SAndroid Build Coastguard Worker  // configurations we support (the default). However, falling back to MXCSR is
8231*9880d681SAndroid Build Coastguard Worker  // more consistent with other instructions, which are always controlled by it.
8232*9880d681SAndroid Build Coastguard Worker  // It's encoded as 0b100.
8233*9880d681SAndroid Build Coastguard Worker  def : Pat<(fp_to_f16 FR32:$src),
8234*9880d681SAndroid Build Coastguard Worker            (i16 (EXTRACT_SUBREG (VMOVPDI2DIrr (VCVTPS2PHrr
8235*9880d681SAndroid Build Coastguard Worker              (COPY_TO_REGCLASS FR32:$src, VR128), 4)), sub_16bit))>;
8236*9880d681SAndroid Build Coastguard Worker
8237*9880d681SAndroid Build Coastguard Worker  def : Pat<(f16_to_fp GR16:$src),
8238*9880d681SAndroid Build Coastguard Worker            (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8239*9880d681SAndroid Build Coastguard Worker              (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128)), FR32)) >;
8240*9880d681SAndroid Build Coastguard Worker
8241*9880d681SAndroid Build Coastguard Worker  def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32:$src))),
8242*9880d681SAndroid Build Coastguard Worker            (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8243*9880d681SAndroid Build Coastguard Worker              (VCVTPS2PHrr (COPY_TO_REGCLASS FR32:$src, VR128), 4)), FR32)) >;
8244*9880d681SAndroid Build Coastguard Worker}
8245*9880d681SAndroid Build Coastguard Worker
8246*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8247*9880d681SAndroid Build Coastguard Worker// AVX2 Instructions
8248*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8249*9880d681SAndroid Build Coastguard Worker
8250*9880d681SAndroid Build Coastguard Worker/// AVX2_binop_rmi - AVX2 binary operator with 8-bit immediate
8251*9880d681SAndroid Build Coastguard Workermulticlass AVX2_binop_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
8252*9880d681SAndroid Build Coastguard Worker                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
8253*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop> {
8254*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in
8255*9880d681SAndroid Build Coastguard Worker  def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
8256*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, RC:$src2, u8imm:$src3),
8257*9880d681SAndroid Build Coastguard Worker        !strconcat(OpcodeStr,
8258*9880d681SAndroid Build Coastguard Worker            "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8259*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))]>,
8260*9880d681SAndroid Build Coastguard Worker        Sched<[WriteBlend]>, VEX_4V;
8261*9880d681SAndroid Build Coastguard Worker  def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
8262*9880d681SAndroid Build Coastguard Worker        (ins RC:$src1, x86memop:$src2, u8imm:$src3),
8263*9880d681SAndroid Build Coastguard Worker        !strconcat(OpcodeStr,
8264*9880d681SAndroid Build Coastguard Worker            "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8265*9880d681SAndroid Build Coastguard Worker        [(set RC:$dst,
8266*9880d681SAndroid Build Coastguard Worker          (OpVT (OpNode RC:$src1,
8267*9880d681SAndroid Build Coastguard Worker           (bitconvert (memop_frag addr:$src2)), imm:$src3)))]>,
8268*9880d681SAndroid Build Coastguard Worker        Sched<[WriteBlendLd, ReadAfterLd]>, VEX_4V;
8269*9880d681SAndroid Build Coastguard Worker}
8270*9880d681SAndroid Build Coastguard Worker
8271*9880d681SAndroid Build Coastguard Workerdefm VPBLENDD : AVX2_binop_rmi<0x02, "vpblendd", X86Blendi, v4i32,
8272*9880d681SAndroid Build Coastguard Worker                               VR128, loadv2i64, i128mem>;
8273*9880d681SAndroid Build Coastguard Workerdefm VPBLENDDY : AVX2_binop_rmi<0x02, "vpblendd", X86Blendi, v8i32,
8274*9880d681SAndroid Build Coastguard Worker                                VR256, loadv4i64, i256mem>, VEX_L;
8275*9880d681SAndroid Build Coastguard Worker
8276*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8277*9880d681SAndroid Build Coastguard Worker// VPBROADCAST - Load from memory and broadcast to all elements of the
8278*9880d681SAndroid Build Coastguard Worker//               destination operand
8279*9880d681SAndroid Build Coastguard Worker//
8280*9880d681SAndroid Build Coastguard Workermulticlass avx2_broadcast<bits<8> opc, string OpcodeStr,
8281*9880d681SAndroid Build Coastguard Worker                          X86MemOperand x86memop, PatFrag ld_frag,
8282*9880d681SAndroid Build Coastguard Worker                          ValueType OpVT128, ValueType OpVT256, Predicate prd> {
8283*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX2, prd] in {
8284*9880d681SAndroid Build Coastguard Worker    def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
8285*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8286*9880d681SAndroid Build Coastguard Worker                  [(set VR128:$dst,
8287*9880d681SAndroid Build Coastguard Worker                   (OpVT128 (X86VBroadcast (OpVT128 VR128:$src))))]>,
8288*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteShuffle]>, VEX;
8289*9880d681SAndroid Build Coastguard Worker    def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
8290*9880d681SAndroid Build Coastguard Worker                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8291*9880d681SAndroid Build Coastguard Worker                  [(set VR128:$dst,
8292*9880d681SAndroid Build Coastguard Worker                   (OpVT128 (X86VBroadcast (ld_frag addr:$src))))]>,
8293*9880d681SAndroid Build Coastguard Worker                  Sched<[WriteLoad]>, VEX;
8294*9880d681SAndroid Build Coastguard Worker    def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
8295*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8296*9880d681SAndroid Build Coastguard Worker                   [(set VR256:$dst,
8297*9880d681SAndroid Build Coastguard Worker                    (OpVT256 (X86VBroadcast (OpVT128 VR128:$src))))]>,
8298*9880d681SAndroid Build Coastguard Worker                   Sched<[WriteShuffle256]>, VEX, VEX_L;
8299*9880d681SAndroid Build Coastguard Worker    def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
8300*9880d681SAndroid Build Coastguard Worker                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8301*9880d681SAndroid Build Coastguard Worker                   [(set VR256:$dst,
8302*9880d681SAndroid Build Coastguard Worker                    (OpVT256 (X86VBroadcast (ld_frag addr:$src))))]>,
8303*9880d681SAndroid Build Coastguard Worker                   Sched<[WriteLoad]>, VEX, VEX_L;
8304*9880d681SAndroid Build Coastguard Worker
8305*9880d681SAndroid Build Coastguard Worker    // Provide aliases for broadcast from the same register class that
8306*9880d681SAndroid Build Coastguard Worker    // automatically does the extract.
8307*9880d681SAndroid Build Coastguard Worker    def : Pat<(OpVT256 (X86VBroadcast (OpVT256 VR256:$src))),
8308*9880d681SAndroid Build Coastguard Worker              (!cast<Instruction>(NAME#"Yrr")
8309*9880d681SAndroid Build Coastguard Worker                  (OpVT128 (EXTRACT_SUBREG (OpVT256 VR256:$src),sub_xmm)))>;
8310*9880d681SAndroid Build Coastguard Worker  }
8311*9880d681SAndroid Build Coastguard Worker}
8312*9880d681SAndroid Build Coastguard Worker
8313*9880d681SAndroid Build Coastguard Workerdefm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
8314*9880d681SAndroid Build Coastguard Worker                                    v16i8, v32i8, NoVLX_Or_NoBWI>;
8315*9880d681SAndroid Build Coastguard Workerdefm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
8316*9880d681SAndroid Build Coastguard Worker                                    v8i16, v16i16, NoVLX_Or_NoBWI>;
8317*9880d681SAndroid Build Coastguard Workerdefm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
8318*9880d681SAndroid Build Coastguard Worker                                    v4i32, v8i32, NoVLX>;
8319*9880d681SAndroid Build Coastguard Workerdefm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
8320*9880d681SAndroid Build Coastguard Worker                                    v2i64, v4i64, NoVLX>;
8321*9880d681SAndroid Build Coastguard Worker
8322*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
8323*9880d681SAndroid Build Coastguard Worker  // loadi16 is tricky to fold, because !isTypeDesirableForOp, justifiably.
8324*9880d681SAndroid Build Coastguard Worker  // This means we'll encounter truncated i32 loads; match that here.
8325*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
8326*9880d681SAndroid Build Coastguard Worker            (VPBROADCASTWrm addr:$src)>;
8327*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
8328*9880d681SAndroid Build Coastguard Worker            (VPBROADCASTWYrm addr:$src)>;
8329*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (X86VBroadcast
8330*9880d681SAndroid Build Coastguard Worker              (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
8331*9880d681SAndroid Build Coastguard Worker            (VPBROADCASTWrm addr:$src)>;
8332*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (X86VBroadcast
8333*9880d681SAndroid Build Coastguard Worker              (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
8334*9880d681SAndroid Build Coastguard Worker            (VPBROADCASTWYrm addr:$src)>;
8335*9880d681SAndroid Build Coastguard Worker
8336*9880d681SAndroid Build Coastguard Worker  // Provide aliases for broadcast from the same register class that
8337*9880d681SAndroid Build Coastguard Worker  // automatically does the extract.
8338*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86VBroadcast (v8f32 VR256:$src))),
8339*9880d681SAndroid Build Coastguard Worker            (VBROADCASTSSYrr (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src),
8340*9880d681SAndroid Build Coastguard Worker                                                    sub_xmm)))>;
8341*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86VBroadcast (v4f64 VR256:$src))),
8342*9880d681SAndroid Build Coastguard Worker            (VBROADCASTSDYrr (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src),
8343*9880d681SAndroid Build Coastguard Worker                                                    sub_xmm)))>;
8344*9880d681SAndroid Build Coastguard Worker}
8345*9880d681SAndroid Build Coastguard Worker
8346*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
8347*9880d681SAndroid Build Coastguard Worker  // Provide fallback in case the load node that is used in the patterns above
8348*9880d681SAndroid Build Coastguard Worker  // is used by additional users, which prevents the pattern selection.
8349*9880d681SAndroid Build Coastguard Worker    let AddedComplexity = 20 in {
8350*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8351*9880d681SAndroid Build Coastguard Worker              (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8352*9880d681SAndroid Build Coastguard Worker    def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8353*9880d681SAndroid Build Coastguard Worker              (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8354*9880d681SAndroid Build Coastguard Worker    def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8355*9880d681SAndroid Build Coastguard Worker              (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8356*9880d681SAndroid Build Coastguard Worker    }
8357*9880d681SAndroid Build Coastguard Worker}
8358*9880d681SAndroid Build Coastguard Worker
8359*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX_Or_NoBWI], AddedComplexity = 20 in {
8360*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i8 (X86VBroadcast GR8:$src)),
8361*9880d681SAndroid Build Coastguard Worker        (VPBROADCASTBrr (COPY_TO_REGCLASS
8362*9880d681SAndroid Build Coastguard Worker                         (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8363*9880d681SAndroid Build Coastguard Worker                         VR128))>;
8364*9880d681SAndroid Build Coastguard Worker  def : Pat<(v32i8 (X86VBroadcast GR8:$src)),
8365*9880d681SAndroid Build Coastguard Worker        (VPBROADCASTBYrr (COPY_TO_REGCLASS
8366*9880d681SAndroid Build Coastguard Worker                          (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8367*9880d681SAndroid Build Coastguard Worker                          VR128))>;
8368*9880d681SAndroid Build Coastguard Worker
8369*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i16 (X86VBroadcast GR16:$src)),
8370*9880d681SAndroid Build Coastguard Worker        (VPBROADCASTWrr (COPY_TO_REGCLASS
8371*9880d681SAndroid Build Coastguard Worker                         (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8372*9880d681SAndroid Build Coastguard Worker                         VR128))>;
8373*9880d681SAndroid Build Coastguard Worker  def : Pat<(v16i16 (X86VBroadcast GR16:$src)),
8374*9880d681SAndroid Build Coastguard Worker        (VPBROADCASTWYrr (COPY_TO_REGCLASS
8375*9880d681SAndroid Build Coastguard Worker                          (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8376*9880d681SAndroid Build Coastguard Worker                          VR128))>;
8377*9880d681SAndroid Build Coastguard Worker}
8378*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX], AddedComplexity = 20 in {
8379*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8380*9880d681SAndroid Build Coastguard Worker            (VBROADCASTSSrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8381*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8382*9880d681SAndroid Build Coastguard Worker            (VBROADCASTSSYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8383*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8384*9880d681SAndroid Build Coastguard Worker            (VBROADCASTSDYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8385*9880d681SAndroid Build Coastguard Worker
8386*9880d681SAndroid Build Coastguard Worker  // The patterns for VPBROADCASTD are not needed because they would match
8387*9880d681SAndroid Build Coastguard Worker  // the exact same thing as VBROADCASTSS patterns.
8388*9880d681SAndroid Build Coastguard Worker
8389*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86VBroadcast GR64:$src)),
8390*9880d681SAndroid Build Coastguard Worker        (VPBROADCASTQrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8391*9880d681SAndroid Build Coastguard Worker  // The v4i64 pattern is not needed because VBROADCASTSDYrr already match.
8392*9880d681SAndroid Build Coastguard Worker}
8393*9880d681SAndroid Build Coastguard Worker
8394*9880d681SAndroid Build Coastguard Worker// AVX1 broadcast patterns
8395*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
8396*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8397*9880d681SAndroid Build Coastguard Worker          (VBROADCASTSSYrm addr:$src)>;
8398*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8399*9880d681SAndroid Build Coastguard Worker          (VBROADCASTSDYrm addr:$src)>;
8400*9880d681SAndroid Build Coastguard Workerdef : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8401*9880d681SAndroid Build Coastguard Worker          (VBROADCASTSSrm addr:$src)>;
8402*9880d681SAndroid Build Coastguard Worker}
8403*9880d681SAndroid Build Coastguard Worker
8404*9880d681SAndroid Build Coastguard Worker  // Provide fallback in case the load node that is used in the patterns above
8405*9880d681SAndroid Build Coastguard Worker  // is used by additional users, which prevents the pattern selection.
8406*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX], AddedComplexity = 20 in {
8407*9880d681SAndroid Build Coastguard Worker  // 128bit broadcasts:
8408*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8409*9880d681SAndroid Build Coastguard Worker            (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8410*9880d681SAndroid Build Coastguard Worker}
8411*9880d681SAndroid Build Coastguard Worker
8412*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX, NoVLX], AddedComplexity = 20 in {
8413*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8414*9880d681SAndroid Build Coastguard Worker            (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
8415*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8416*9880d681SAndroid Build Coastguard Worker            (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
8417*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
8418*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
8419*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8420*9880d681SAndroid Build Coastguard Worker            (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
8421*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), sub_xmm),
8422*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), 1)>;
8423*9880d681SAndroid Build Coastguard Worker
8424*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8425*9880d681SAndroid Build Coastguard Worker            (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
8426*9880d681SAndroid Build Coastguard Worker  def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8427*9880d681SAndroid Build Coastguard Worker            (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8428*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
8429*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
8430*9880d681SAndroid Build Coastguard Worker  def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8431*9880d681SAndroid Build Coastguard Worker            (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
8432*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
8433*9880d681SAndroid Build Coastguard Worker              (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
8434*9880d681SAndroid Build Coastguard Worker
8435*9880d681SAndroid Build Coastguard Worker  def : Pat<(v2i64 (X86VBroadcast i64:$src)),
8436*9880d681SAndroid Build Coastguard Worker              (VMOVDDUPrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8437*9880d681SAndroid Build Coastguard Worker}
8438*9880d681SAndroid Build Coastguard Worker
8439*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8440*9880d681SAndroid Build Coastguard Worker// VPERM - Permute instructions
8441*9880d681SAndroid Build Coastguard Worker//
8442*9880d681SAndroid Build Coastguard Worker
8443*9880d681SAndroid Build Coastguard Workermulticlass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8444*9880d681SAndroid Build Coastguard Worker                     ValueType OpVT, X86FoldableSchedWrite Sched> {
8445*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX2, NoVLX] in {
8446*9880d681SAndroid Build Coastguard Worker    def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8447*9880d681SAndroid Build Coastguard Worker                     (ins VR256:$src1, VR256:$src2),
8448*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr,
8449*9880d681SAndroid Build Coastguard Worker                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8450*9880d681SAndroid Build Coastguard Worker                     [(set VR256:$dst,
8451*9880d681SAndroid Build Coastguard Worker                       (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
8452*9880d681SAndroid Build Coastguard Worker                     Sched<[Sched]>, VEX_4V, VEX_L;
8453*9880d681SAndroid Build Coastguard Worker    def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8454*9880d681SAndroid Build Coastguard Worker                     (ins VR256:$src1, i256mem:$src2),
8455*9880d681SAndroid Build Coastguard Worker                     !strconcat(OpcodeStr,
8456*9880d681SAndroid Build Coastguard Worker                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8457*9880d681SAndroid Build Coastguard Worker                     [(set VR256:$dst,
8458*9880d681SAndroid Build Coastguard Worker                       (OpVT (X86VPermv VR256:$src1,
8459*9880d681SAndroid Build Coastguard Worker                              (bitconvert (mem_frag addr:$src2)))))]>,
8460*9880d681SAndroid Build Coastguard Worker                     Sched<[Sched.Folded, ReadAfterLd]>, VEX_4V, VEX_L;
8461*9880d681SAndroid Build Coastguard Worker  }
8462*9880d681SAndroid Build Coastguard Worker}
8463*9880d681SAndroid Build Coastguard Worker
8464*9880d681SAndroid Build Coastguard Workerdefm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32, WriteShuffle256>;
8465*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedSingle in
8466*9880d681SAndroid Build Coastguard Workerdefm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32, WriteFShuffle256>;
8467*9880d681SAndroid Build Coastguard Worker
8468*9880d681SAndroid Build Coastguard Workermulticlass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8469*9880d681SAndroid Build Coastguard Worker                         ValueType OpVT, X86FoldableSchedWrite Sched> {
8470*9880d681SAndroid Build Coastguard Worker  let Predicates = [HasAVX2, NoVLX] in {
8471*9880d681SAndroid Build Coastguard Worker    def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
8472*9880d681SAndroid Build Coastguard Worker                       (ins VR256:$src1, u8imm:$src2),
8473*9880d681SAndroid Build Coastguard Worker                       !strconcat(OpcodeStr,
8474*9880d681SAndroid Build Coastguard Worker                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8475*9880d681SAndroid Build Coastguard Worker                       [(set VR256:$dst,
8476*9880d681SAndroid Build Coastguard Worker                         (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
8477*9880d681SAndroid Build Coastguard Worker                       Sched<[Sched]>, VEX, VEX_L;
8478*9880d681SAndroid Build Coastguard Worker    def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
8479*9880d681SAndroid Build Coastguard Worker                       (ins i256mem:$src1, u8imm:$src2),
8480*9880d681SAndroid Build Coastguard Worker                       !strconcat(OpcodeStr,
8481*9880d681SAndroid Build Coastguard Worker                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8482*9880d681SAndroid Build Coastguard Worker                       [(set VR256:$dst,
8483*9880d681SAndroid Build Coastguard Worker                         (OpVT (X86VPermi (mem_frag addr:$src1),
8484*9880d681SAndroid Build Coastguard Worker                                (i8 imm:$src2))))]>,
8485*9880d681SAndroid Build Coastguard Worker                       Sched<[Sched.Folded, ReadAfterLd]>, VEX, VEX_L;
8486*9880d681SAndroid Build Coastguard Worker  }
8487*9880d681SAndroid Build Coastguard Worker}
8488*9880d681SAndroid Build Coastguard Worker
8489*9880d681SAndroid Build Coastguard Workerdefm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64,
8490*9880d681SAndroid Build Coastguard Worker                            WriteShuffle256>, VEX_W;
8491*9880d681SAndroid Build Coastguard Workerlet ExeDomain = SSEPackedDouble in
8492*9880d681SAndroid Build Coastguard Workerdefm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
8493*9880d681SAndroid Build Coastguard Worker                             WriteFShuffle256>, VEX_W;
8494*9880d681SAndroid Build Coastguard Worker
8495*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8496*9880d681SAndroid Build Coastguard Worker// VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
8497*9880d681SAndroid Build Coastguard Worker//
8498*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
8499*9880d681SAndroid Build Coastguard Workerdef VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
8500*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, VR256:$src2, u8imm:$src3),
8501*9880d681SAndroid Build Coastguard Worker          "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8502*9880d681SAndroid Build Coastguard Worker          [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8503*9880d681SAndroid Build Coastguard Worker                            (i8 imm:$src3))))]>, Sched<[WriteShuffle256]>,
8504*9880d681SAndroid Build Coastguard Worker          VEX_4V, VEX_L;
8505*9880d681SAndroid Build Coastguard Workerdef VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
8506*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
8507*9880d681SAndroid Build Coastguard Worker          "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8508*9880d681SAndroid Build Coastguard Worker          [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
8509*9880d681SAndroid Build Coastguard Worker                             (i8 imm:$src3)))]>,
8510*9880d681SAndroid Build Coastguard Worker          Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8511*9880d681SAndroid Build Coastguard Worker
8512*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
8513*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8514*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8515*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8516*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8517*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8518*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8519*9880d681SAndroid Build Coastguard Worker
8520*9880d681SAndroid Build Coastguard Workerdef : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (loadv4i64 addr:$src2)),
8521*9880d681SAndroid Build Coastguard Worker                  (i8 imm:$imm))),
8522*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8523*9880d681SAndroid Build Coastguard Workerdef : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8524*9880d681SAndroid Build Coastguard Worker                   (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8525*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8526*9880d681SAndroid Build Coastguard Workerdef : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)),
8527*9880d681SAndroid Build Coastguard Worker                  (i8 imm:$imm))),
8528*9880d681SAndroid Build Coastguard Worker          (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8529*9880d681SAndroid Build Coastguard Worker}
8530*9880d681SAndroid Build Coastguard Worker
8531*9880d681SAndroid Build Coastguard Worker
8532*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8533*9880d681SAndroid Build Coastguard Worker// VINSERTI128 - Insert packed integer values
8534*9880d681SAndroid Build Coastguard Worker//
8535*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in {
8536*9880d681SAndroid Build Coastguard Workerdef VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
8537*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, VR128:$src2, u8imm:$src3),
8538*9880d681SAndroid Build Coastguard Worker          "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8539*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
8540*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1 in
8541*9880d681SAndroid Build Coastguard Workerdef VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
8542*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, i128mem:$src2, u8imm:$src3),
8543*9880d681SAndroid Build Coastguard Worker          "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8544*9880d681SAndroid Build Coastguard Worker          []>, Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8545*9880d681SAndroid Build Coastguard Worker}
8546*9880d681SAndroid Build Coastguard Worker
8547*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
8548*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8549*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8550*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rr VR256:$src1, VR128:$src2,
8551*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8552*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8553*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8554*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rr VR256:$src1, VR128:$src2,
8555*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8556*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8557*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8558*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rr VR256:$src1, VR128:$src2,
8559*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8560*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8561*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8562*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rr VR256:$src1, VR128:$src2,
8563*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8564*9880d681SAndroid Build Coastguard Worker
8565*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8566*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8567*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rm VR256:$src1, addr:$src2,
8568*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8569*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8570*9880d681SAndroid Build Coastguard Worker                                   (bc_v4i32 (loadv2i64 addr:$src2)),
8571*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8572*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rm VR256:$src1, addr:$src2,
8573*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8574*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8575*9880d681SAndroid Build Coastguard Worker                                   (bc_v16i8 (loadv2i64 addr:$src2)),
8576*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8577*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rm VR256:$src1, addr:$src2,
8578*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8579*9880d681SAndroid Build Coastguard Workerdef : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8580*9880d681SAndroid Build Coastguard Worker                                   (bc_v8i16 (loadv2i64 addr:$src2)),
8581*9880d681SAndroid Build Coastguard Worker                                   (iPTR imm)),
8582*9880d681SAndroid Build Coastguard Worker          (VINSERTI128rm VR256:$src1, addr:$src2,
8583*9880d681SAndroid Build Coastguard Worker                         (INSERT_get_vinsert128_imm VR256:$ins))>;
8584*9880d681SAndroid Build Coastguard Worker}
8585*9880d681SAndroid Build Coastguard Worker
8586*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8587*9880d681SAndroid Build Coastguard Worker// VEXTRACTI128 - Extract packed integer values
8588*9880d681SAndroid Build Coastguard Worker//
8589*9880d681SAndroid Build Coastguard Workerdef VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
8590*9880d681SAndroid Build Coastguard Worker          (ins VR256:$src1, u8imm:$src2),
8591*9880d681SAndroid Build Coastguard Worker          "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8592*9880d681SAndroid Build Coastguard Worker          Sched<[WriteShuffle256]>, VEX, VEX_L;
8593*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, mayStore = 1 in
8594*9880d681SAndroid Build Coastguard Workerdef VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
8595*9880d681SAndroid Build Coastguard Worker          (ins i128mem:$dst, VR256:$src1, u8imm:$src2),
8596*9880d681SAndroid Build Coastguard Worker          "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8597*9880d681SAndroid Build Coastguard Worker          Sched<[WriteStore]>, VEX, VEX_L;
8598*9880d681SAndroid Build Coastguard Worker
8599*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
8600*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8601*9880d681SAndroid Build Coastguard Worker          (v2i64 (VEXTRACTI128rr
8602*9880d681SAndroid Build Coastguard Worker                    (v4i64 VR256:$src1),
8603*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8604*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8605*9880d681SAndroid Build Coastguard Worker          (v4i32 (VEXTRACTI128rr
8606*9880d681SAndroid Build Coastguard Worker                    (v8i32 VR256:$src1),
8607*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8608*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8609*9880d681SAndroid Build Coastguard Worker          (v8i16 (VEXTRACTI128rr
8610*9880d681SAndroid Build Coastguard Worker                    (v16i16 VR256:$src1),
8611*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8612*9880d681SAndroid Build Coastguard Workerdef : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8613*9880d681SAndroid Build Coastguard Worker          (v16i8 (VEXTRACTI128rr
8614*9880d681SAndroid Build Coastguard Worker                    (v32i8 VR256:$src1),
8615*9880d681SAndroid Build Coastguard Worker                    (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8616*9880d681SAndroid Build Coastguard Worker
8617*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
8618*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
8619*9880d681SAndroid Build Coastguard Worker          (VEXTRACTI128mr addr:$dst, VR256:$src1,
8620*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
8621*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
8622*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
8623*9880d681SAndroid Build Coastguard Worker          (VEXTRACTI128mr addr:$dst, VR256:$src1,
8624*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
8625*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
8626*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
8627*9880d681SAndroid Build Coastguard Worker          (VEXTRACTI128mr addr:$dst, VR256:$src1,
8628*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
8629*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
8630*9880d681SAndroid Build Coastguard Worker                         (iPTR imm))), addr:$dst),
8631*9880d681SAndroid Build Coastguard Worker          (VEXTRACTI128mr addr:$dst, VR256:$src1,
8632*9880d681SAndroid Build Coastguard Worker           (EXTRACT_get_vextract128_imm VR128:$ext))>;
8633*9880d681SAndroid Build Coastguard Worker}
8634*9880d681SAndroid Build Coastguard Worker
8635*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8636*9880d681SAndroid Build Coastguard Worker// VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
8637*9880d681SAndroid Build Coastguard Worker//
8638*9880d681SAndroid Build Coastguard Workermulticlass avx2_pmovmask<string OpcodeStr,
8639*9880d681SAndroid Build Coastguard Worker                         Intrinsic IntLd128, Intrinsic IntLd256,
8640*9880d681SAndroid Build Coastguard Worker                         Intrinsic IntSt128, Intrinsic IntSt256> {
8641*9880d681SAndroid Build Coastguard Worker  def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
8642*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, i128mem:$src2),
8643*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8644*9880d681SAndroid Build Coastguard Worker             [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
8645*9880d681SAndroid Build Coastguard Worker  def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
8646*9880d681SAndroid Build Coastguard Worker             (ins VR256:$src1, i256mem:$src2),
8647*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8648*9880d681SAndroid Build Coastguard Worker             [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8649*9880d681SAndroid Build Coastguard Worker             VEX_4V, VEX_L;
8650*9880d681SAndroid Build Coastguard Worker  def mr  : AVX28I<0x8e, MRMDestMem, (outs),
8651*9880d681SAndroid Build Coastguard Worker             (ins i128mem:$dst, VR128:$src1, VR128:$src2),
8652*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8653*9880d681SAndroid Build Coastguard Worker             [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8654*9880d681SAndroid Build Coastguard Worker  def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
8655*9880d681SAndroid Build Coastguard Worker             (ins i256mem:$dst, VR256:$src1, VR256:$src2),
8656*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8657*9880d681SAndroid Build Coastguard Worker             [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8658*9880d681SAndroid Build Coastguard Worker}
8659*9880d681SAndroid Build Coastguard Worker
8660*9880d681SAndroid Build Coastguard Workerdefm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
8661*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskload_d,
8662*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskload_d_256,
8663*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskstore_d,
8664*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskstore_d_256>;
8665*9880d681SAndroid Build Coastguard Workerdefm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
8666*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskload_q,
8667*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskload_q_256,
8668*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskstore_q,
8669*9880d681SAndroid Build Coastguard Worker                                int_x86_avx2_maskstore_q_256>, VEX_W;
8670*9880d681SAndroid Build Coastguard Worker
8671*9880d681SAndroid Build Coastguard Workermulticlass maskmov_lowering<string InstrStr, RegisterClass RC, ValueType VT,
8672*9880d681SAndroid Build Coastguard Worker                          ValueType MaskVT, string BlendStr, ValueType ZeroVT> {
8673*9880d681SAndroid Build Coastguard Worker    // masked store
8674*9880d681SAndroid Build Coastguard Worker    def: Pat<(X86mstore addr:$ptr, (MaskVT RC:$mask), (VT RC:$src)),
8675*9880d681SAndroid Build Coastguard Worker             (!cast<Instruction>(InstrStr#"mr") addr:$ptr, RC:$mask, RC:$src)>;
8676*9880d681SAndroid Build Coastguard Worker    // masked load
8677*9880d681SAndroid Build Coastguard Worker    def: Pat<(VT (masked_load addr:$ptr, (MaskVT RC:$mask), undef)),
8678*9880d681SAndroid Build Coastguard Worker             (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
8679*9880d681SAndroid Build Coastguard Worker    def: Pat<(VT (masked_load addr:$ptr, (MaskVT RC:$mask),
8680*9880d681SAndroid Build Coastguard Worker                              (VT (bitconvert (ZeroVT immAllZerosV))))),
8681*9880d681SAndroid Build Coastguard Worker             (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
8682*9880d681SAndroid Build Coastguard Worker    def: Pat<(VT (masked_load addr:$ptr, (MaskVT RC:$mask), (VT RC:$src0))),
8683*9880d681SAndroid Build Coastguard Worker             (!cast<Instruction>(BlendStr#"rr")
8684*9880d681SAndroid Build Coastguard Worker                 RC:$src0,
8685*9880d681SAndroid Build Coastguard Worker                 (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr),
8686*9880d681SAndroid Build Coastguard Worker                 RC:$mask)>;
8687*9880d681SAndroid Build Coastguard Worker}
8688*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX] in {
8689*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPS", VR128, v4f32, v4i32, "VBLENDVPS", v4i32>;
8690*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPD", VR128, v2f64, v2i64, "VBLENDVPD", v4i32>;
8691*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8f32, v8i32, "VBLENDVPSY", v8i32>;
8692*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4f64, v4i64, "VBLENDVPDY", v8i32>;
8693*9880d681SAndroid Build Coastguard Worker}
8694*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX1Only] in {
8695*9880d681SAndroid Build Coastguard Worker  // load/store i32/i64 not supported use ps/pd version
8696*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
8697*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
8698*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPS", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
8699*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VMASKMOVPD", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
8700*9880d681SAndroid Build Coastguard Worker}
8701*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2] in {
8702*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VPMASKMOVDY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
8703*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VPMASKMOVQY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
8704*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VPMASKMOVD", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
8705*9880d681SAndroid Build Coastguard Worker  defm : maskmov_lowering<"VPMASKMOVQ", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
8706*9880d681SAndroid Build Coastguard Worker}
8707*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8708*9880d681SAndroid Build Coastguard Worker// Variable Bit Shifts
8709*9880d681SAndroid Build Coastguard Worker//
8710*9880d681SAndroid Build Coastguard Workermulticlass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
8711*9880d681SAndroid Build Coastguard Worker                          ValueType vt128, ValueType vt256> {
8712*9880d681SAndroid Build Coastguard Worker  def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
8713*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, VR128:$src2),
8714*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8715*9880d681SAndroid Build Coastguard Worker             [(set VR128:$dst,
8716*9880d681SAndroid Build Coastguard Worker               (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
8717*9880d681SAndroid Build Coastguard Worker             VEX_4V, Sched<[WriteVarVecShift]>;
8718*9880d681SAndroid Build Coastguard Worker  def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
8719*9880d681SAndroid Build Coastguard Worker             (ins VR128:$src1, i128mem:$src2),
8720*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8721*9880d681SAndroid Build Coastguard Worker             [(set VR128:$dst,
8722*9880d681SAndroid Build Coastguard Worker               (vt128 (OpNode VR128:$src1,
8723*9880d681SAndroid Build Coastguard Worker                       (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
8724*9880d681SAndroid Build Coastguard Worker             VEX_4V, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
8725*9880d681SAndroid Build Coastguard Worker  def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8726*9880d681SAndroid Build Coastguard Worker             (ins VR256:$src1, VR256:$src2),
8727*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8728*9880d681SAndroid Build Coastguard Worker             [(set VR256:$dst,
8729*9880d681SAndroid Build Coastguard Worker               (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
8730*9880d681SAndroid Build Coastguard Worker             VEX_4V, VEX_L, Sched<[WriteVarVecShift]>;
8731*9880d681SAndroid Build Coastguard Worker  def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8732*9880d681SAndroid Build Coastguard Worker             (ins VR256:$src1, i256mem:$src2),
8733*9880d681SAndroid Build Coastguard Worker             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8734*9880d681SAndroid Build Coastguard Worker             [(set VR256:$dst,
8735*9880d681SAndroid Build Coastguard Worker               (vt256 (OpNode VR256:$src1,
8736*9880d681SAndroid Build Coastguard Worker                       (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
8737*9880d681SAndroid Build Coastguard Worker             VEX_4V, VEX_L, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
8738*9880d681SAndroid Build Coastguard Worker}
8739*9880d681SAndroid Build Coastguard Worker
8740*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasAVX2, NoVLX] in {
8741*9880d681SAndroid Build Coastguard Worker  defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
8742*9880d681SAndroid Build Coastguard Worker  defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
8743*9880d681SAndroid Build Coastguard Worker  defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
8744*9880d681SAndroid Build Coastguard Worker  defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
8745*9880d681SAndroid Build Coastguard Worker  defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
8746*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in
8747*9880d681SAndroid Build Coastguard Worker    defm VPSRAVD_Int : avx2_var_shift<0x46, "vpsravd", X86vsrav, v4i32, v8i32>;
8748*9880d681SAndroid Build Coastguard Worker}
8749*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8750*9880d681SAndroid Build Coastguard Worker// VGATHER - GATHER Operations
8751*9880d681SAndroid Build Coastguard Workermulticlass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
8752*9880d681SAndroid Build Coastguard Worker                       X86MemOperand memop128, X86MemOperand memop256> {
8753*9880d681SAndroid Build Coastguard Worker  def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),
8754*9880d681SAndroid Build Coastguard Worker            (ins VR128:$src1, memop128:$src2, VR128:$mask),
8755*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
8756*9880d681SAndroid Build Coastguard Worker              "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8757*9880d681SAndroid Build Coastguard Worker            []>, VEX_4VOp3;
8758*9880d681SAndroid Build Coastguard Worker  def Yrm : AVX28I<opc, MRMSrcMem, (outs RC256:$dst, RC256:$mask_wb),
8759*9880d681SAndroid Build Coastguard Worker            (ins RC256:$src1, memop256:$src2, RC256:$mask),
8760*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcodeStr,
8761*9880d681SAndroid Build Coastguard Worker              "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8762*9880d681SAndroid Build Coastguard Worker            []>, VEX_4VOp3, VEX_L;
8763*9880d681SAndroid Build Coastguard Worker}
8764*9880d681SAndroid Build Coastguard Worker
8765*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, hasSideEffects = 0, Constraints
8766*9880d681SAndroid Build Coastguard Worker  = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
8767*9880d681SAndroid Build Coastguard Worker  in {
8768*9880d681SAndroid Build Coastguard Worker  defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx128mem, vx256mem>, VEX_W;
8769*9880d681SAndroid Build Coastguard Worker  defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx128mem, vy256mem>, VEX_W;
8770*9880d681SAndroid Build Coastguard Worker  defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx128mem, vy256mem>;
8771*9880d681SAndroid Build Coastguard Worker  defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx64mem, vy128mem>;
8772*9880d681SAndroid Build Coastguard Worker
8773*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedDouble in {
8774*9880d681SAndroid Build Coastguard Worker    defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx128mem, vx256mem>, VEX_W;
8775*9880d681SAndroid Build Coastguard Worker    defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx128mem, vy256mem>, VEX_W;
8776*9880d681SAndroid Build Coastguard Worker  }
8777*9880d681SAndroid Build Coastguard Worker
8778*9880d681SAndroid Build Coastguard Worker  let ExeDomain = SSEPackedSingle in {
8779*9880d681SAndroid Build Coastguard Worker    defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx128mem, vy256mem>;
8780*9880d681SAndroid Build Coastguard Worker    defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx64mem, vy128mem>;
8781*9880d681SAndroid Build Coastguard Worker  }
8782*9880d681SAndroid Build Coastguard Worker}
8783*9880d681SAndroid Build Coastguard Worker
8784*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
8785*9880d681SAndroid Build Coastguard Worker// Extra selection patterns for FR128, f128, f128mem
8786*9880d681SAndroid Build Coastguard Worker
8787*9880d681SAndroid Build Coastguard Worker// movaps is shorter than movdqa. movaps is in SSE and movdqa is in SSE2.
8788*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (f128 FR128:$src), addr:$dst),
8789*9880d681SAndroid Build Coastguard Worker          (MOVAPSmr addr:$dst, (COPY_TO_REGCLASS (f128 FR128:$src), VR128))>;
8790*9880d681SAndroid Build Coastguard Worker
8791*9880d681SAndroid Build Coastguard Workerdef : Pat<(loadf128 addr:$src),
8792*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS (MOVAPSrm addr:$src), FR128)>;
8793*9880d681SAndroid Build Coastguard Worker
8794*9880d681SAndroid Build Coastguard Worker// andps is shorter than andpd or pand. andps is SSE and andpd/pand are in SSE2
8795*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86fand FR128:$src1, (loadf128 addr:$src2)),
8796*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8797*9880d681SAndroid Build Coastguard Worker           (ANDPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8798*9880d681SAndroid Build Coastguard Worker           FR128)>;
8799*9880d681SAndroid Build Coastguard Worker
8800*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86fand FR128:$src1, FR128:$src2),
8801*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8802*9880d681SAndroid Build Coastguard Worker           (ANDPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8803*9880d681SAndroid Build Coastguard Worker                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8804*9880d681SAndroid Build Coastguard Worker
8805*9880d681SAndroid Build Coastguard Workerdef : Pat<(and FR128:$src1, FR128:$src2),
8806*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8807*9880d681SAndroid Build Coastguard Worker           (ANDPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8808*9880d681SAndroid Build Coastguard Worker                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8809*9880d681SAndroid Build Coastguard Worker
8810*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86for FR128:$src1, (loadf128 addr:$src2)),
8811*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8812*9880d681SAndroid Build Coastguard Worker           (ORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8813*9880d681SAndroid Build Coastguard Worker           FR128)>;
8814*9880d681SAndroid Build Coastguard Worker
8815*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86for FR128:$src1, FR128:$src2),
8816*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8817*9880d681SAndroid Build Coastguard Worker           (ORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8818*9880d681SAndroid Build Coastguard Worker                   (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8819*9880d681SAndroid Build Coastguard Worker
8820*9880d681SAndroid Build Coastguard Workerdef : Pat<(or FR128:$src1, FR128:$src2),
8821*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8822*9880d681SAndroid Build Coastguard Worker           (ORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8823*9880d681SAndroid Build Coastguard Worker                   (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8824*9880d681SAndroid Build Coastguard Worker
8825*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86fxor FR128:$src1, (loadf128 addr:$src2)),
8826*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8827*9880d681SAndroid Build Coastguard Worker           (XORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8828*9880d681SAndroid Build Coastguard Worker           FR128)>;
8829*9880d681SAndroid Build Coastguard Worker
8830*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86fxor FR128:$src1, FR128:$src2),
8831*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8832*9880d681SAndroid Build Coastguard Worker           (XORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8833*9880d681SAndroid Build Coastguard Worker                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8834*9880d681SAndroid Build Coastguard Worker
8835*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor FR128:$src1, FR128:$src2),
8836*9880d681SAndroid Build Coastguard Worker          (COPY_TO_REGCLASS
8837*9880d681SAndroid Build Coastguard Worker           (XORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8838*9880d681SAndroid Build Coastguard Worker                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8839