1//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the VSX extension to the PowerPC instruction set.
11//
12//===----------------------------------------------------------------------===//
13
14// *********************************** NOTE ***********************************
15// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
16// ** which VMX and VSX instructions are lane-sensitive and which are not.   **
17// ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
18// ** whether lanes are numbered from left to right.  An instruction like    **
19// ** VADDFP is not lane-sensitive, because each lane of the result vector   **
20// ** relies only on the corresponding lane of the source vectors.  However, **
21// ** an instruction like VMULESB is lane-sensitive, because "even" and      **
22// ** "odd" lanes are different for big-endian and little-endian numbering.  **
23// **                                                                        **
24// ** When adding new VMX and VSX instructions, please consider whether they **
25// ** are lane-sensitive.  If so, they must be added to a switch statement   **
26// ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
27// ****************************************************************************
28
29def PPCRegVSRCAsmOperand : AsmOperandClass {
30  let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
31}
32def vsrc : RegisterOperand<VSRC> {
33  let ParserMatchClass = PPCRegVSRCAsmOperand;
34}
35
36def PPCRegVSFRCAsmOperand : AsmOperandClass {
37  let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
38}
39def vsfrc : RegisterOperand<VSFRC> {
40  let ParserMatchClass = PPCRegVSFRCAsmOperand;
41}
42
43def PPCRegVSSRCAsmOperand : AsmOperandClass {
44  let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
45}
46def vssrc : RegisterOperand<VSSRC> {
47  let ParserMatchClass = PPCRegVSSRCAsmOperand;
48}
49
50// Little-endian-specific nodes.
51def SDT_PPClxvd2x : SDTypeProfile<1, 1, [
52  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
53]>;
54def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
55  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
56]>;
57def SDT_PPCxxswapd : SDTypeProfile<1, 1, [
58  SDTCisSameAs<0, 1>
59]>;
60
61def PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
62                        [SDNPHasChain, SDNPMayLoad]>;
63def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
64                        [SDNPHasChain, SDNPMayStore]>;
65def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
66def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
67def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
68def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
69
70multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
71                    string asmstr, InstrItinClass itin, Intrinsic Int,
72                    ValueType OutTy, ValueType InTy> {
73  let BaseName = asmbase in {
74    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
75                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
76                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
77    let Defs = [CR6] in
78    def o    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
79                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
80                       [(set InTy:$XT,
81                                (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
82                       isDOT;
83  }
84}
85
86def HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
87def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
88def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
89
90let Predicates = [HasVSX] in {
91let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
92let hasSideEffects = 0 in { // VSX instructions don't have side effects.
93let Uses = [RM] in {
94
95  // Load indexed instructions
96  let mayLoad = 1 in {
97    def LXSDX : XX1Form<31, 588,
98                        (outs vsfrc:$XT), (ins memrr:$src),
99                        "lxsdx $XT, $src", IIC_LdStLFD,
100                        [(set f64:$XT, (load xoaddr:$src))]>;
101
102    def LXVD2X : XX1Form<31, 844,
103                         (outs vsrc:$XT), (ins memrr:$src),
104                         "lxvd2x $XT, $src", IIC_LdStLFD,
105                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
106
107    def LXVDSX : XX1Form<31, 332,
108                         (outs vsrc:$XT), (ins memrr:$src),
109                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
110
111    def LXVW4X : XX1Form<31, 780,
112                         (outs vsrc:$XT), (ins memrr:$src),
113                         "lxvw4x $XT, $src", IIC_LdStLFD,
114                         [(set v4i32:$XT, (int_ppc_vsx_lxvw4x xoaddr:$src))]>;
115  } // mayLoad
116
117  // Store indexed instructions
118  let mayStore = 1 in {
119    def STXSDX : XX1Form<31, 716,
120                        (outs), (ins vsfrc:$XT, memrr:$dst),
121                        "stxsdx $XT, $dst", IIC_LdStSTFD,
122                        [(store f64:$XT, xoaddr:$dst)]>;
123
124    def STXVD2X : XX1Form<31, 972,
125                         (outs), (ins vsrc:$XT, memrr:$dst),
126                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
127                         [(store v2f64:$XT, xoaddr:$dst)]>;
128
129    def STXVW4X : XX1Form<31, 908,
130                         (outs), (ins vsrc:$XT, memrr:$dst),
131                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
132                         [(store v4i32:$XT, xoaddr:$dst)]>;
133
134  } // mayStore
135
136  // Add/Mul Instructions
137  let isCommutable = 1 in {
138    def XSADDDP : XX3Form<60, 32,
139                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
140                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
141                          [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>;
142    def XSMULDP : XX3Form<60, 48,
143                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
144                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
145                          [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>;
146
147    def XVADDDP : XX3Form<60, 96,
148                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
149                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
150                          [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>;
151
152    def XVADDSP : XX3Form<60, 64,
153                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
154                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
155                          [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>;
156
157    def XVMULDP : XX3Form<60, 112,
158                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
159                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
160                          [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>;
161
162    def XVMULSP : XX3Form<60, 80,
163                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
164                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
165                          [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>;
166  }
167
168  // Subtract Instructions
169  def XSSUBDP : XX3Form<60, 40,
170                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
171                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
172                        [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>;
173
174  def XVSUBDP : XX3Form<60, 104,
175                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
176                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
177                        [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>;
178  def XVSUBSP : XX3Form<60, 72,
179                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
180                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
181                        [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>;
182
183  // FMA Instructions
184  let BaseName = "XSMADDADP" in {
185  let isCommutable = 1 in
186  def XSMADDADP : XX3Form<60, 33,
187                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
188                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
189                          [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>,
190                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
191                          AltVSXFMARel;
192  let IsVSXFMAAlt = 1 in
193  def XSMADDMDP : XX3Form<60, 41,
194                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
195                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
196                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
197                          AltVSXFMARel;
198  }
199
200  let BaseName = "XSMSUBADP" in {
201  let isCommutable = 1 in
202  def XSMSUBADP : XX3Form<60, 49,
203                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
204                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
205                          [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
206                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
207                          AltVSXFMARel;
208  let IsVSXFMAAlt = 1 in
209  def XSMSUBMDP : XX3Form<60, 57,
210                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
211                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
212                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
213                          AltVSXFMARel;
214  }
215
216  let BaseName = "XSNMADDADP" in {
217  let isCommutable = 1 in
218  def XSNMADDADP : XX3Form<60, 161,
219                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
220                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
221                          [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>,
222                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
223                          AltVSXFMARel;
224  let IsVSXFMAAlt = 1 in
225  def XSNMADDMDP : XX3Form<60, 169,
226                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
227                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
228                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
229                          AltVSXFMARel;
230  }
231
232  let BaseName = "XSNMSUBADP" in {
233  let isCommutable = 1 in
234  def XSNMSUBADP : XX3Form<60, 177,
235                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
236                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
237                          [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
238                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
239                          AltVSXFMARel;
240  let IsVSXFMAAlt = 1 in
241  def XSNMSUBMDP : XX3Form<60, 185,
242                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
243                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
244                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
245                          AltVSXFMARel;
246  }
247
248  let BaseName = "XVMADDADP" in {
249  let isCommutable = 1 in
250  def XVMADDADP : XX3Form<60, 97,
251                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
252                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
253                          [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
254                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
255                          AltVSXFMARel;
256  let IsVSXFMAAlt = 1 in
257  def XVMADDMDP : XX3Form<60, 105,
258                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
259                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
260                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
261                          AltVSXFMARel;
262  }
263
264  let BaseName = "XVMADDASP" in {
265  let isCommutable = 1 in
266  def XVMADDASP : XX3Form<60, 65,
267                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
268                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
269                          [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
270                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
271                          AltVSXFMARel;
272  let IsVSXFMAAlt = 1 in
273  def XVMADDMSP : XX3Form<60, 73,
274                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
275                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
276                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
277                          AltVSXFMARel;
278  }
279
280  let BaseName = "XVMSUBADP" in {
281  let isCommutable = 1 in
282  def XVMSUBADP : XX3Form<60, 113,
283                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
284                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
285                          [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
286                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
287                          AltVSXFMARel;
288  let IsVSXFMAAlt = 1 in
289  def XVMSUBMDP : XX3Form<60, 121,
290                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
291                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
292                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
293                          AltVSXFMARel;
294  }
295
296  let BaseName = "XVMSUBASP" in {
297  let isCommutable = 1 in
298  def XVMSUBASP : XX3Form<60, 81,
299                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
300                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
301                          [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
302                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
303                          AltVSXFMARel;
304  let IsVSXFMAAlt = 1 in
305  def XVMSUBMSP : XX3Form<60, 89,
306                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
307                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
308                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
309                          AltVSXFMARel;
310  }
311
312  let BaseName = "XVNMADDADP" in {
313  let isCommutable = 1 in
314  def XVNMADDADP : XX3Form<60, 225,
315                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
316                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
317                          [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
318                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
319                          AltVSXFMARel;
320  let IsVSXFMAAlt = 1 in
321  def XVNMADDMDP : XX3Form<60, 233,
322                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
323                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
324                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
325                          AltVSXFMARel;
326  }
327
328  let BaseName = "XVNMADDASP" in {
329  let isCommutable = 1 in
330  def XVNMADDASP : XX3Form<60, 193,
331                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
332                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
333                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
334                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
335                          AltVSXFMARel;
336  let IsVSXFMAAlt = 1 in
337  def XVNMADDMSP : XX3Form<60, 201,
338                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
339                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
340                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
341                          AltVSXFMARel;
342  }
343
344  let BaseName = "XVNMSUBADP" in {
345  let isCommutable = 1 in
346  def XVNMSUBADP : XX3Form<60, 241,
347                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
348                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
349                          [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
350                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
351                          AltVSXFMARel;
352  let IsVSXFMAAlt = 1 in
353  def XVNMSUBMDP : XX3Form<60, 249,
354                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
355                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
356                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
357                          AltVSXFMARel;
358  }
359
360  let BaseName = "XVNMSUBASP" in {
361  let isCommutable = 1 in
362  def XVNMSUBASP : XX3Form<60, 209,
363                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
364                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
365                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
366                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
367                          AltVSXFMARel;
368  let IsVSXFMAAlt = 1 in
369  def XVNMSUBMSP : XX3Form<60, 217,
370                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
371                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
372                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
373                          AltVSXFMARel;
374  }
375
376  // Division Instructions
377  def XSDIVDP : XX3Form<60, 56,
378                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
379                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
380                        [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>;
381  def XSSQRTDP : XX2Form<60, 75,
382                        (outs vsfrc:$XT), (ins vsfrc:$XB),
383                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
384                        [(set f64:$XT, (fsqrt f64:$XB))]>;
385
386  def XSREDP : XX2Form<60, 90,
387                        (outs vsfrc:$XT), (ins vsfrc:$XB),
388                        "xsredp $XT, $XB", IIC_VecFP,
389                        [(set f64:$XT, (PPCfre f64:$XB))]>;
390  def XSRSQRTEDP : XX2Form<60, 74,
391                           (outs vsfrc:$XT), (ins vsfrc:$XB),
392                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
393                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
394
395  def XSTDIVDP : XX3Form_1<60, 61,
396                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
397                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
398  def XSTSQRTDP : XX2Form_1<60, 106,
399                          (outs crrc:$crD), (ins vsfrc:$XB),
400                          "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
401
402  def XVDIVDP : XX3Form<60, 120,
403                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
404                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
405                        [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>;
406  def XVDIVSP : XX3Form<60, 88,
407                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
408                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
409                        [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>;
410
411  def XVSQRTDP : XX2Form<60, 203,
412                        (outs vsrc:$XT), (ins vsrc:$XB),
413                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
414                        [(set v2f64:$XT, (fsqrt v2f64:$XB))]>;
415  def XVSQRTSP : XX2Form<60, 139,
416                        (outs vsrc:$XT), (ins vsrc:$XB),
417                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
418                        [(set v4f32:$XT, (fsqrt v4f32:$XB))]>;
419
420  def XVTDIVDP : XX3Form_1<60, 125,
421                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
422                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
423  def XVTDIVSP : XX3Form_1<60, 93,
424                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
425                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
426
427  def XVTSQRTDP : XX2Form_1<60, 234,
428                          (outs crrc:$crD), (ins vsrc:$XB),
429                          "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
430  def XVTSQRTSP : XX2Form_1<60, 170,
431                          (outs crrc:$crD), (ins vsrc:$XB),
432                          "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
433
434  def XVREDP : XX2Form<60, 218,
435                        (outs vsrc:$XT), (ins vsrc:$XB),
436                        "xvredp $XT, $XB", IIC_VecFP,
437                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
438  def XVRESP : XX2Form<60, 154,
439                        (outs vsrc:$XT), (ins vsrc:$XB),
440                        "xvresp $XT, $XB", IIC_VecFP,
441                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
442
443  def XVRSQRTEDP : XX2Form<60, 202,
444                           (outs vsrc:$XT), (ins vsrc:$XB),
445                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
446                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
447  def XVRSQRTESP : XX2Form<60, 138,
448                           (outs vsrc:$XT), (ins vsrc:$XB),
449                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
450                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
451
452  // Compare Instructions
453  def XSCMPODP : XX3Form_1<60, 43,
454                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
455                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
456  def XSCMPUDP : XX3Form_1<60, 35,
457                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
458                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
459
460  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
461                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
462                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
463  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
464                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
465                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
466  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
467                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
468                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
469  defm XVCMPGESP : XX3Form_Rcr<60, 83,
470                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
471                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
472  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
473                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
474                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
475  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
476                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
477                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
478
479  // Move Instructions
480  def XSABSDP : XX2Form<60, 345,
481                      (outs vsfrc:$XT), (ins vsfrc:$XB),
482                      "xsabsdp $XT, $XB", IIC_VecFP,
483                      [(set f64:$XT, (fabs f64:$XB))]>;
484  def XSNABSDP : XX2Form<60, 361,
485                      (outs vsfrc:$XT), (ins vsfrc:$XB),
486                      "xsnabsdp $XT, $XB", IIC_VecFP,
487                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
488  def XSNEGDP : XX2Form<60, 377,
489                      (outs vsfrc:$XT), (ins vsfrc:$XB),
490                      "xsnegdp $XT, $XB", IIC_VecFP,
491                      [(set f64:$XT, (fneg f64:$XB))]>;
492  def XSCPSGNDP : XX3Form<60, 176,
493                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
494                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
495                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
496
497  def XVABSDP : XX2Form<60, 473,
498                      (outs vsrc:$XT), (ins vsrc:$XB),
499                      "xvabsdp $XT, $XB", IIC_VecFP,
500                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
501
502  def XVABSSP : XX2Form<60, 409,
503                      (outs vsrc:$XT), (ins vsrc:$XB),
504                      "xvabssp $XT, $XB", IIC_VecFP,
505                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
506
507  def XVCPSGNDP : XX3Form<60, 240,
508                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
509                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
510                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
511  def XVCPSGNSP : XX3Form<60, 208,
512                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
513                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
514                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
515
516  def XVNABSDP : XX2Form<60, 489,
517                      (outs vsrc:$XT), (ins vsrc:$XB),
518                      "xvnabsdp $XT, $XB", IIC_VecFP,
519                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
520  def XVNABSSP : XX2Form<60, 425,
521                      (outs vsrc:$XT), (ins vsrc:$XB),
522                      "xvnabssp $XT, $XB", IIC_VecFP,
523                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
524
525  def XVNEGDP : XX2Form<60, 505,
526                      (outs vsrc:$XT), (ins vsrc:$XB),
527                      "xvnegdp $XT, $XB", IIC_VecFP,
528                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
529  def XVNEGSP : XX2Form<60, 441,
530                      (outs vsrc:$XT), (ins vsrc:$XB),
531                      "xvnegsp $XT, $XB", IIC_VecFP,
532                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
533
534  // Conversion Instructions
535  def XSCVDPSP : XX2Form<60, 265,
536                      (outs vsfrc:$XT), (ins vsfrc:$XB),
537                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
538  def XSCVDPSXDS : XX2Form<60, 344,
539                      (outs vsfrc:$XT), (ins vsfrc:$XB),
540                      "xscvdpsxds $XT, $XB", IIC_VecFP,
541                      [(set f64:$XT, (PPCfctidz f64:$XB))]>;
542  def XSCVDPSXWS : XX2Form<60, 88,
543                      (outs vsfrc:$XT), (ins vsfrc:$XB),
544                      "xscvdpsxws $XT, $XB", IIC_VecFP,
545                      [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
546  def XSCVDPUXDS : XX2Form<60, 328,
547                      (outs vsfrc:$XT), (ins vsfrc:$XB),
548                      "xscvdpuxds $XT, $XB", IIC_VecFP,
549                      [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
550  def XSCVDPUXWS : XX2Form<60, 72,
551                      (outs vsfrc:$XT), (ins vsfrc:$XB),
552                      "xscvdpuxws $XT, $XB", IIC_VecFP,
553                      [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
554  def XSCVSPDP : XX2Form<60, 329,
555                      (outs vsfrc:$XT), (ins vsfrc:$XB),
556                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
557  def XSCVSXDDP : XX2Form<60, 376,
558                      (outs vsfrc:$XT), (ins vsfrc:$XB),
559                      "xscvsxddp $XT, $XB", IIC_VecFP,
560                      [(set f64:$XT, (PPCfcfid f64:$XB))]>;
561  def XSCVUXDDP : XX2Form<60, 360,
562                      (outs vsfrc:$XT), (ins vsfrc:$XB),
563                      "xscvuxddp $XT, $XB", IIC_VecFP,
564                      [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
565
566  def XVCVDPSP : XX2Form<60, 393,
567                      (outs vsrc:$XT), (ins vsrc:$XB),
568                      "xvcvdpsp $XT, $XB", IIC_VecFP, []>;
569  def XVCVDPSXDS : XX2Form<60, 472,
570                      (outs vsrc:$XT), (ins vsrc:$XB),
571                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
572                      [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
573  def XVCVDPSXWS : XX2Form<60, 216,
574                      (outs vsrc:$XT), (ins vsrc:$XB),
575                      "xvcvdpsxws $XT, $XB", IIC_VecFP, []>;
576  def XVCVDPUXDS : XX2Form<60, 456,
577                      (outs vsrc:$XT), (ins vsrc:$XB),
578                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
579                      [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
580  def XVCVDPUXWS : XX2Form<60, 200,
581                      (outs vsrc:$XT), (ins vsrc:$XB),
582                      "xvcvdpuxws $XT, $XB", IIC_VecFP, []>;
583
584  def XVCVSPDP : XX2Form<60, 457,
585                      (outs vsrc:$XT), (ins vsrc:$XB),
586                      "xvcvspdp $XT, $XB", IIC_VecFP, []>;
587  def XVCVSPSXDS : XX2Form<60, 408,
588                      (outs vsrc:$XT), (ins vsrc:$XB),
589                      "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
590  def XVCVSPSXWS : XX2Form<60, 152,
591                      (outs vsrc:$XT), (ins vsrc:$XB),
592                      "xvcvspsxws $XT, $XB", IIC_VecFP, []>;
593  def XVCVSPUXDS : XX2Form<60, 392,
594                      (outs vsrc:$XT), (ins vsrc:$XB),
595                      "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
596  def XVCVSPUXWS : XX2Form<60, 136,
597                      (outs vsrc:$XT), (ins vsrc:$XB),
598                      "xvcvspuxws $XT, $XB", IIC_VecFP, []>;
599  def XVCVSXDDP : XX2Form<60, 504,
600                      (outs vsrc:$XT), (ins vsrc:$XB),
601                      "xvcvsxddp $XT, $XB", IIC_VecFP,
602                      [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
603  def XVCVSXDSP : XX2Form<60, 440,
604                      (outs vsrc:$XT), (ins vsrc:$XB),
605                      "xvcvsxdsp $XT, $XB", IIC_VecFP, []>;
606  def XVCVSXWDP : XX2Form<60, 248,
607                      (outs vsrc:$XT), (ins vsrc:$XB),
608                      "xvcvsxwdp $XT, $XB", IIC_VecFP, []>;
609  def XVCVSXWSP : XX2Form<60, 184,
610                      (outs vsrc:$XT), (ins vsrc:$XB),
611                      "xvcvsxwsp $XT, $XB", IIC_VecFP, []>;
612  def XVCVUXDDP : XX2Form<60, 488,
613                      (outs vsrc:$XT), (ins vsrc:$XB),
614                      "xvcvuxddp $XT, $XB", IIC_VecFP,
615                      [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
616  def XVCVUXDSP : XX2Form<60, 424,
617                      (outs vsrc:$XT), (ins vsrc:$XB),
618                      "xvcvuxdsp $XT, $XB", IIC_VecFP, []>;
619  def XVCVUXWDP : XX2Form<60, 232,
620                      (outs vsrc:$XT), (ins vsrc:$XB),
621                      "xvcvuxwdp $XT, $XB", IIC_VecFP, []>;
622  def XVCVUXWSP : XX2Form<60, 168,
623                      (outs vsrc:$XT), (ins vsrc:$XB),
624                      "xvcvuxwsp $XT, $XB", IIC_VecFP, []>;
625
626  // Rounding Instructions
627  def XSRDPI : XX2Form<60, 73,
628                      (outs vsfrc:$XT), (ins vsfrc:$XB),
629                      "xsrdpi $XT, $XB", IIC_VecFP,
630                      [(set f64:$XT, (frnd f64:$XB))]>;
631  def XSRDPIC : XX2Form<60, 107,
632                      (outs vsfrc:$XT), (ins vsfrc:$XB),
633                      "xsrdpic $XT, $XB", IIC_VecFP,
634                      [(set f64:$XT, (fnearbyint f64:$XB))]>;
635  def XSRDPIM : XX2Form<60, 121,
636                      (outs vsfrc:$XT), (ins vsfrc:$XB),
637                      "xsrdpim $XT, $XB", IIC_VecFP,
638                      [(set f64:$XT, (ffloor f64:$XB))]>;
639  def XSRDPIP : XX2Form<60, 105,
640                      (outs vsfrc:$XT), (ins vsfrc:$XB),
641                      "xsrdpip $XT, $XB", IIC_VecFP,
642                      [(set f64:$XT, (fceil f64:$XB))]>;
643  def XSRDPIZ : XX2Form<60, 89,
644                      (outs vsfrc:$XT), (ins vsfrc:$XB),
645                      "xsrdpiz $XT, $XB", IIC_VecFP,
646                      [(set f64:$XT, (ftrunc f64:$XB))]>;
647
648  def XVRDPI : XX2Form<60, 201,
649                      (outs vsrc:$XT), (ins vsrc:$XB),
650                      "xvrdpi $XT, $XB", IIC_VecFP,
651                      [(set v2f64:$XT, (frnd v2f64:$XB))]>;
652  def XVRDPIC : XX2Form<60, 235,
653                      (outs vsrc:$XT), (ins vsrc:$XB),
654                      "xvrdpic $XT, $XB", IIC_VecFP,
655                      [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
656  def XVRDPIM : XX2Form<60, 249,
657                      (outs vsrc:$XT), (ins vsrc:$XB),
658                      "xvrdpim $XT, $XB", IIC_VecFP,
659                      [(set v2f64:$XT, (ffloor v2f64:$XB))]>;
660  def XVRDPIP : XX2Form<60, 233,
661                      (outs vsrc:$XT), (ins vsrc:$XB),
662                      "xvrdpip $XT, $XB", IIC_VecFP,
663                      [(set v2f64:$XT, (fceil v2f64:$XB))]>;
664  def XVRDPIZ : XX2Form<60, 217,
665                      (outs vsrc:$XT), (ins vsrc:$XB),
666                      "xvrdpiz $XT, $XB", IIC_VecFP,
667                      [(set v2f64:$XT, (ftrunc v2f64:$XB))]>;
668
669  def XVRSPI : XX2Form<60, 137,
670                      (outs vsrc:$XT), (ins vsrc:$XB),
671                      "xvrspi $XT, $XB", IIC_VecFP,
672                      [(set v4f32:$XT, (frnd v4f32:$XB))]>;
673  def XVRSPIC : XX2Form<60, 171,
674                      (outs vsrc:$XT), (ins vsrc:$XB),
675                      "xvrspic $XT, $XB", IIC_VecFP,
676                      [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
677  def XVRSPIM : XX2Form<60, 185,
678                      (outs vsrc:$XT), (ins vsrc:$XB),
679                      "xvrspim $XT, $XB", IIC_VecFP,
680                      [(set v4f32:$XT, (ffloor v4f32:$XB))]>;
681  def XVRSPIP : XX2Form<60, 169,
682                      (outs vsrc:$XT), (ins vsrc:$XB),
683                      "xvrspip $XT, $XB", IIC_VecFP,
684                      [(set v4f32:$XT, (fceil v4f32:$XB))]>;
685  def XVRSPIZ : XX2Form<60, 153,
686                      (outs vsrc:$XT), (ins vsrc:$XB),
687                      "xvrspiz $XT, $XB", IIC_VecFP,
688                      [(set v4f32:$XT, (ftrunc v4f32:$XB))]>;
689
690  // Max/Min Instructions
691  let isCommutable = 1 in {
692  def XSMAXDP : XX3Form<60, 160,
693                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
694                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
695                        [(set vsfrc:$XT,
696                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
697  def XSMINDP : XX3Form<60, 168,
698                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
699                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
700                        [(set vsfrc:$XT,
701                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
702
703  def XVMAXDP : XX3Form<60, 224,
704                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
705                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
706                        [(set vsrc:$XT,
707                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
708  def XVMINDP : XX3Form<60, 232,
709                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
710                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
711                        [(set vsrc:$XT,
712                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
713
714  def XVMAXSP : XX3Form<60, 192,
715                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
716                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
717                        [(set vsrc:$XT,
718                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
719  def XVMINSP : XX3Form<60, 200,
720                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
721                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
722                        [(set vsrc:$XT,
723                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
724  } // isCommutable
725} // Uses = [RM]
726
727  // Logical Instructions
728  let isCommutable = 1 in
729  def XXLAND : XX3Form<60, 130,
730                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
731                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
732                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
733  def XXLANDC : XX3Form<60, 138,
734                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
735                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
736                        [(set v4i32:$XT, (and v4i32:$XA,
737                                              (vnot_ppc v4i32:$XB)))]>;
738  let isCommutable = 1 in {
739  def XXLNOR : XX3Form<60, 162,
740                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
741                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
742                       [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
743                                                   v4i32:$XB)))]>;
744  def XXLOR : XX3Form<60, 146,
745                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
746                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
747                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
748  let isCodeGenOnly = 1 in
749  def XXLORf: XX3Form<60, 146,
750                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
751                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
752  def XXLXOR : XX3Form<60, 154,
753                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
754                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
755                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
756  } // isCommutable
757
758  // Permutation Instructions
759  def XXMRGHW : XX3Form<60, 18,
760                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
761                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
762  def XXMRGLW : XX3Form<60, 50,
763                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
764                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
765
766  def XXPERMDI : XX3Form_2<60, 10,
767                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
768                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, []>;
769  def XXSEL : XX4Form<60, 3,
770                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
771                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
772
773  def XXSLDWI : XX3Form_2<60, 2,
774                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
775                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm, []>;
776  def XXSPLTW : XX2Form_2<60, 164,
777                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
778                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
779} // hasSideEffects
780
781// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
782// instruction selection into a branch sequence.
783let usesCustomInserter = 1,    // Expanded after instruction selection.
784    PPC970_Single = 1 in {
785
786  def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst),
787                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
788                             "#SELECT_CC_VSRC",
789                             []>;
790  def SELECT_VSRC: Pseudo<(outs vsrc:$dst),
791                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
792                          "#SELECT_VSRC",
793                          [(set v2f64:$dst,
794                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
795  def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst),
796                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
797                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
798                              []>;
799  def SELECT_VSFRC: Pseudo<(outs f8rc:$dst),
800                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
801                           "#SELECT_VSFRC",
802                           [(set f64:$dst,
803                                 (select i1:$cond, f64:$T, f64:$F))]>;
804  def SELECT_CC_VSSRC: Pseudo<(outs f4rc:$dst),
805                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
806                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
807                              []>;
808  def SELECT_VSSRC: Pseudo<(outs f4rc:$dst),
809                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
810                           "#SELECT_VSSRC",
811                           [(set f32:$dst,
812                                 (select i1:$cond, f32:$T, f32:$F))]>;
813} // usesCustomInserter
814} // AddedComplexity
815
816def : InstAlias<"xvmovdp $XT, $XB",
817                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
818def : InstAlias<"xvmovsp $XT, $XB",
819                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
820
821def : InstAlias<"xxspltd $XT, $XB, 0",
822                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
823def : InstAlias<"xxspltd $XT, $XB, 1",
824                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
825def : InstAlias<"xxmrghd $XT, $XA, $XB",
826                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
827def : InstAlias<"xxmrgld $XT, $XA, $XB",
828                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
829def : InstAlias<"xxswapd $XT, $XB",
830                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
831
832let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
833
834let Predicates = [IsBigEndian] in {
835def : Pat<(v2f64 (scalar_to_vector f64:$A)),
836          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
837
838def : Pat<(f64 (extractelt v2f64:$S, 0)),
839          (f64 (EXTRACT_SUBREG $S, sub_64))>;
840def : Pat<(f64 (extractelt v2f64:$S, 1)),
841          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
842}
843
844let Predicates = [IsLittleEndian] in {
845def : Pat<(v2f64 (scalar_to_vector f64:$A)),
846          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
847                           (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
848
849def : Pat<(f64 (extractelt v2f64:$S, 0)),
850          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
851def : Pat<(f64 (extractelt v2f64:$S, 1)),
852          (f64 (EXTRACT_SUBREG $S, sub_64))>;
853}
854
855// Additional fnmsub patterns: -a*c + b == -(a*c - b)
856def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
857          (XSNMSUBADP $B, $C, $A)>;
858def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
859          (XSNMSUBADP $B, $C, $A)>;
860
861def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B),
862          (XVNMSUBADP $B, $C, $A)>;
863def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B),
864          (XVNMSUBADP $B, $C, $A)>;
865
866def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B),
867          (XVNMSUBASP $B, $C, $A)>;
868def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B),
869          (XVNMSUBASP $B, $C, $A)>;
870
871def : Pat<(v2f64 (bitconvert v4f32:$A)),
872          (COPY_TO_REGCLASS $A, VSRC)>;
873def : Pat<(v2f64 (bitconvert v4i32:$A)),
874          (COPY_TO_REGCLASS $A, VSRC)>;
875def : Pat<(v2f64 (bitconvert v8i16:$A)),
876          (COPY_TO_REGCLASS $A, VSRC)>;
877def : Pat<(v2f64 (bitconvert v16i8:$A)),
878          (COPY_TO_REGCLASS $A, VSRC)>;
879
880def : Pat<(v4f32 (bitconvert v2f64:$A)),
881          (COPY_TO_REGCLASS $A, VRRC)>;
882def : Pat<(v4i32 (bitconvert v2f64:$A)),
883          (COPY_TO_REGCLASS $A, VRRC)>;
884def : Pat<(v8i16 (bitconvert v2f64:$A)),
885          (COPY_TO_REGCLASS $A, VRRC)>;
886def : Pat<(v16i8 (bitconvert v2f64:$A)),
887          (COPY_TO_REGCLASS $A, VRRC)>;
888
889def : Pat<(v2i64 (bitconvert v4f32:$A)),
890          (COPY_TO_REGCLASS $A, VSRC)>;
891def : Pat<(v2i64 (bitconvert v4i32:$A)),
892          (COPY_TO_REGCLASS $A, VSRC)>;
893def : Pat<(v2i64 (bitconvert v8i16:$A)),
894          (COPY_TO_REGCLASS $A, VSRC)>;
895def : Pat<(v2i64 (bitconvert v16i8:$A)),
896          (COPY_TO_REGCLASS $A, VSRC)>;
897
898def : Pat<(v4f32 (bitconvert v2i64:$A)),
899          (COPY_TO_REGCLASS $A, VRRC)>;
900def : Pat<(v4i32 (bitconvert v2i64:$A)),
901          (COPY_TO_REGCLASS $A, VRRC)>;
902def : Pat<(v8i16 (bitconvert v2i64:$A)),
903          (COPY_TO_REGCLASS $A, VRRC)>;
904def : Pat<(v16i8 (bitconvert v2i64:$A)),
905          (COPY_TO_REGCLASS $A, VRRC)>;
906
907def : Pat<(v2f64 (bitconvert v2i64:$A)),
908          (COPY_TO_REGCLASS $A, VRRC)>;
909def : Pat<(v2i64 (bitconvert v2f64:$A)),
910          (COPY_TO_REGCLASS $A, VRRC)>;
911
912def : Pat<(v2f64 (bitconvert v1i128:$A)),
913          (COPY_TO_REGCLASS $A, VRRC)>;
914def : Pat<(v1i128 (bitconvert v2f64:$A)),
915          (COPY_TO_REGCLASS $A, VRRC)>;
916
917// sign extension patterns
918// To extend "in place" from v2i32 to v2i64, we have input data like:
919// | undef | i32 | undef | i32 |
920// but xvcvsxwdp expects the input in big-Endian format:
921// | i32 | undef | i32 | undef |
922// so we need to shift everything to the left by one i32 (word) before
923// the conversion.
924def : Pat<(sext_inreg v2i64:$C, v2i32),
925          (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>;
926def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))),
927          (XVCVSXWDP (XXSLDWI $C, $C, 1))>;
928
929// Loads.
930def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
931def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
932def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
933def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
934
935// Stores.
936def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
937          (STXVD2X $rS, xoaddr:$dst)>;
938def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
939def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
940          (STXVW4X $rS, xoaddr:$dst)>;
941def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
942
943// Permutes.
944def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
945def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
946def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
947def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
948
949// Selects.
950def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
951          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
952def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
953          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
954def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
955          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
956def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
957          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
958def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
959          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
960def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
961          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
962def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
963          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
964def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
965          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
966def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
967          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
968def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
969          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
970
971def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
972          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
973def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
974          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
975def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
976          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
977def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
978          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
979def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
980          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
981def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
982          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
983def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
984          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
985def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
986          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
987def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
988          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
989def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
990          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
991
992// Divides.
993def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
994          (XVDIVSP $A, $B)>;
995def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
996          (XVDIVDP $A, $B)>;
997
998// Reciprocal estimate
999def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1000          (XVRESP $A)>;
1001def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1002          (XVREDP $A)>;
1003
1004// Recip. square root estimate
1005def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1006          (XVRSQRTESP $A)>;
1007def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1008          (XVRSQRTEDP $A)>;
1009
1010} // AddedComplexity
1011} // HasVSX
1012
1013// The following VSX instructions were introduced in Power ISA 2.07
1014/* FIXME: if the operands are v2i64, these patterns will not match.
1015   we should define new patterns or otherwise match the same patterns
1016   when the elements are larger than i32.
1017*/
1018def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1019def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1020let Predicates = [HasP8Vector] in {
1021let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1022  let isCommutable = 1 in {
1023    def XXLEQV : XX3Form<60, 186,
1024                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1025                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1026                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1027    def XXLNAND : XX3Form<60, 178,
1028                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1029                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1030                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1031                                                    v4i32:$XB)))]>;
1032  } // isCommutable
1033
1034  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1035            (XXLEQV $A, $B)>;
1036
1037  def XXLORC : XX3Form<60, 170,
1038                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1039                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1040                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1041
1042  // VSX scalar loads introduced in ISA 2.07
1043  let mayLoad = 1 in {
1044    def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1045                         "lxsspx $XT, $src", IIC_LdStLFD,
1046                         [(set f32:$XT, (load xoaddr:$src))]>;
1047    def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1048                          "lxsiwax $XT, $src", IIC_LdStLFD,
1049                          [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1050    def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1051                          "lxsiwzx $XT, $src", IIC_LdStLFD,
1052                          [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1053  } // mayLoad
1054
1055  // VSX scalar stores introduced in ISA 2.07
1056  let mayStore = 1 in {
1057    def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1058                          "stxsspx $XT, $dst", IIC_LdStSTFD,
1059                          [(store f32:$XT, xoaddr:$dst)]>;
1060    def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1061                          "stxsiwx $XT, $dst", IIC_LdStSTFD,
1062                          [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1063  } // mayStore
1064
1065  def : Pat<(f64 (extloadf32 xoaddr:$src)),
1066            (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>;
1067  def : Pat<(f64 (fextend f32:$src)),
1068            (COPY_TO_REGCLASS $src, VSFRC)>;
1069
1070  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1071            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1072  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1073            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1074  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1075            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1076  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1077            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1078  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1079            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1080  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1081            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1082  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1083            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1084  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1085            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1086  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1087            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1088  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1089            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1090
1091  // VSX Elementary Scalar FP arithmetic (SP)
1092  let isCommutable = 1 in {
1093    def XSADDSP : XX3Form<60, 0,
1094                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1095                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1096                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1097    def XSMULSP : XX3Form<60, 16,
1098                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1099                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1100                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1101  } // isCommutable
1102
1103  def XSDIVSP : XX3Form<60, 24,
1104                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1105                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1106                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1107  def XSRESP : XX2Form<60, 26,
1108                        (outs vssrc:$XT), (ins vssrc:$XB),
1109                        "xsresp $XT, $XB", IIC_VecFP,
1110                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1111  def XSSQRTSP : XX2Form<60, 11,
1112                        (outs vssrc:$XT), (ins vssrc:$XB),
1113                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1114                        [(set f32:$XT, (fsqrt f32:$XB))]>;
1115  def XSRSQRTESP : XX2Form<60, 10,
1116                           (outs vssrc:$XT), (ins vssrc:$XB),
1117                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1118                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1119  def XSSUBSP : XX3Form<60, 8,
1120                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1121                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1122                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1123
1124  // FMA Instructions
1125  let BaseName = "XSMADDASP" in {
1126  let isCommutable = 1 in
1127  def XSMADDASP : XX3Form<60, 1,
1128                          (outs vssrc:$XT),
1129                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1130                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1131                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1132                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1133                          AltVSXFMARel;
1134  let IsVSXFMAAlt = 1 in
1135  def XSMADDMSP : XX3Form<60, 9,
1136                          (outs vssrc:$XT),
1137                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1138                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1139                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1140                          AltVSXFMARel;
1141  }
1142
1143  let BaseName = "XSMSUBASP" in {
1144  let isCommutable = 1 in
1145  def XSMSUBASP : XX3Form<60, 17,
1146                          (outs vssrc:$XT),
1147                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1148                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1149                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
1150                                              (fneg f32:$XTi)))]>,
1151                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1152                          AltVSXFMARel;
1153  let IsVSXFMAAlt = 1 in
1154  def XSMSUBMSP : XX3Form<60, 25,
1155                          (outs vssrc:$XT),
1156                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1157                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1158                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1159                          AltVSXFMARel;
1160  }
1161
1162  let BaseName = "XSNMADDASP" in {
1163  let isCommutable = 1 in
1164  def XSNMADDASP : XX3Form<60, 129,
1165                          (outs vssrc:$XT),
1166                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1167                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1168                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1169                                                    f32:$XTi)))]>,
1170                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1171                          AltVSXFMARel;
1172  let IsVSXFMAAlt = 1 in
1173  def XSNMADDMSP : XX3Form<60, 137,
1174                          (outs vssrc:$XT),
1175                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1176                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1177                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1178                          AltVSXFMARel;
1179  }
1180
1181  let BaseName = "XSNMSUBASP" in {
1182  let isCommutable = 1 in
1183  def XSNMSUBASP : XX3Form<60, 145,
1184                          (outs vssrc:$XT),
1185                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1186                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1187                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1188                                                    (fneg f32:$XTi))))]>,
1189                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1190                          AltVSXFMARel;
1191  let IsVSXFMAAlt = 1 in
1192  def XSNMSUBMSP : XX3Form<60, 153,
1193                          (outs vssrc:$XT),
1194                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1195                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1196                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1197                          AltVSXFMARel;
1198  }
1199
1200  // Single Precision Conversions (FP <-> INT)
1201  def XSCVSXDSP : XX2Form<60, 312,
1202                      (outs vssrc:$XT), (ins vsfrc:$XB),
1203                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1204                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1205  def XSCVUXDSP : XX2Form<60, 296,
1206                      (outs vssrc:$XT), (ins vsfrc:$XB),
1207                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1208                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1209
1210  // Conversions between vector and scalar single precision
1211  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1212                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1213  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1214                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1215
1216} // AddedComplexity = 400
1217} // HasP8Vector
1218
1219let Predicates = [HasDirectMove, HasVSX] in {
1220  // VSX direct move instructions
1221  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1222                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1223                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1224      Requires<[In64BitMode]>;
1225  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1226                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1227                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1228  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1229                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1230                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1231      Requires<[In64BitMode]>;
1232  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1233                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1234                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1235  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1236                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1237                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1238} // HasDirectMove, HasVSX
1239
1240/*  Direct moves of various widths from GPR's into VSR's. Each move lines
1241    the value up into element 0 (both BE and LE). Namely, entities smaller than
1242    a doubleword are shifted left and moved for BE. For LE, they're moved, then
1243    swapped to go into the least significant element of the VSR.
1244*/
1245def MovesToVSR {
1246  dag BE_BYTE_0 =
1247    (MTVSRD
1248      (RLDICR
1249        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1250  dag BE_HALF_0 =
1251    (MTVSRD
1252      (RLDICR
1253        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1254  dag BE_WORD_0 =
1255    (MTVSRD
1256      (RLDICR
1257        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1258  dag BE_DWORD_0 = (MTVSRD $A);
1259
1260  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1261  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1262                                        LE_MTVSRW, sub_64));
1263  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1264  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1265                                         BE_DWORD_0, sub_64));
1266  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1267}
1268
1269/*  Patterns for extracting elements out of vectors. Integer elements are
1270    extracted using direct move operations. Patterns for extracting elements
1271    whose indices are not available at compile time are also provided with
1272    various _VARIABLE_ patterns.
1273    The numbering for the DAG's is for LE, but when used on BE, the correct
1274    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1275*/
1276def VectorExtractions {
1277  // Doubleword extraction
1278  dag LE_DWORD_0 =
1279    (MFVSRD
1280      (EXTRACT_SUBREG
1281        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1282                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1283  dag LE_DWORD_1 = (MFVSRD
1284                     (EXTRACT_SUBREG
1285                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1286
1287  // Word extraction
1288  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 2), sub_64));
1289  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1290  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1291                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1292  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1293
1294  // Halfword extraction
1295  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1296  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1297  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1298  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1299  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1300  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1301  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1302  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1303
1304  // Byte extraction
1305  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1306  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1307  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1308  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1309  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1310  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1311  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1312  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1313  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1314  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1315  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1316  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1317  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1318  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1319  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1320  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1321
1322  /* Variable element number (BE and LE patterns must be specified separately)
1323     This is a rather involved process.
1324
1325     Conceptually, this is how the move is accomplished:
1326     1. Identify which doubleword contains the element
1327     2. Shift in the VMX register so that the correct doubleword is correctly
1328        lined up for the MFVSRD
1329     3. Perform the move so that the element (along with some extra stuff)
1330        is in the GPR
1331     4. Right shift within the GPR so that the element is right-justified
1332
1333     Of course, the index is an element number which has a different meaning
1334     on LE/BE so the patterns have to be specified separately.
1335
1336     Note: The final result will be the element right-justified with high
1337           order bits being arbitrarily defined (namely, whatever was in the
1338           vector register to the left of the value originally).
1339  */
1340
1341  /*  LE variable byte
1342      Number 1. above:
1343      - For elements 0-7, we shift left by 8 bytes since they're on the right
1344      - For elements 8-15, we need not shift (shift left by zero bytes)
1345      This is accomplished by inverting the bits of the index and AND-ing
1346      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1347  */
1348  dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1349
1350  //  Number 2. above:
1351  //  - Now that we set up the shift amount, we shift in the VMX register
1352  dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1353
1354  //  Number 3. above:
1355  //  - The doubleword containing our element is moved to a GPR
1356  dag LE_MV_VBYTE = (MFVSRD
1357                      (EXTRACT_SUBREG
1358                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1359                        sub_64));
1360
1361  /*  Number 4. above:
1362      - Truncate the element number to the range 0-7 (8-15 are symmetrical
1363        and out of range values are truncated accordingly)
1364      - Multiply by 8 as we need to shift right by the number of bits, not bytes
1365      - Shift right in the GPR by the calculated value
1366  */
1367  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1368                                       sub_32);
1369  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1370                                         sub_32);
1371
1372  /*  LE variable halfword
1373      Number 1. above:
1374      - For elements 0-3, we shift left by 8 since they're on the right
1375      - For elements 4-7, we need not shift (shift left by zero bytes)
1376      Similarly to the byte pattern, we invert the bits of the index, but we
1377      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1378      Of course, the shift is still by 8 bytes, so we must multiply by 2.
1379  */
1380  dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1381
1382  //  Number 2. above:
1383  //  - Now that we set up the shift amount, we shift in the VMX register
1384  dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1385
1386  //  Number 3. above:
1387  //  - The doubleword containing our element is moved to a GPR
1388  dag LE_MV_VHALF = (MFVSRD
1389                      (EXTRACT_SUBREG
1390                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1391                        sub_64));
1392
1393  /*  Number 4. above:
1394      - Truncate the element number to the range 0-3 (4-7 are symmetrical
1395        and out of range values are truncated accordingly)
1396      - Multiply by 16 as we need to shift right by the number of bits
1397      - Shift right in the GPR by the calculated value
1398  */
1399  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1400                                       sub_32);
1401  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1402                                         sub_32);
1403
1404  /*  LE variable word
1405      Number 1. above:
1406      - For elements 0-1, we shift left by 8 since they're on the right
1407      - For elements 2-3, we need not shift
1408  */
1409  dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1410
1411  //  Number 2. above:
1412  //  - Now that we set up the shift amount, we shift in the VMX register
1413  dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1414
1415  //  Number 3. above:
1416  //  - The doubleword containing our element is moved to a GPR
1417  dag LE_MV_VWORD = (MFVSRD
1418                      (EXTRACT_SUBREG
1419                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1420                        sub_64));
1421
1422  /*  Number 4. above:
1423      - Truncate the element number to the range 0-1 (2-3 are symmetrical
1424        and out of range values are truncated accordingly)
1425      - Multiply by 32 as we need to shift right by the number of bits
1426      - Shift right in the GPR by the calculated value
1427  */
1428  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1429                                       sub_32);
1430  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1431                                         sub_32);
1432
1433  /*  LE variable doubleword
1434      Number 1. above:
1435      - For element 0, we shift left by 8 since it's on the right
1436      - For element 1, we need not shift
1437  */
1438  dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1439
1440  //  Number 2. above:
1441  //  - Now that we set up the shift amount, we shift in the VMX register
1442  dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1443
1444  // Number 3. above:
1445  //  - The doubleword containing our element is moved to a GPR
1446  //  - Number 4. is not needed for the doubleword as the value is 64-bits
1447  dag LE_VARIABLE_DWORD =
1448        (MFVSRD (EXTRACT_SUBREG
1449                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1450                  sub_64));
1451
1452  /*  LE variable float
1453      - Shift the vector to line up the desired element to BE Word 0
1454      - Convert 32-bit float to a 64-bit single precision float
1455  */
1456  dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1457  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1458  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1459
1460  /*  LE variable double
1461      Same as the LE doubleword except there is no move.
1462  */
1463  dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1464                                  (COPY_TO_REGCLASS $S, VRRC),
1465                                  LE_VDWORD_PERM_VEC);
1466  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1467
1468  /*  BE variable byte
1469      The algorithm here is the same as the LE variable byte except:
1470      - The shift in the VMX register is by 0/8 for opposite element numbers so
1471        we simply AND the element number with 0x8
1472      - The order of elements after the move to GPR is reversed, so we invert
1473        the bits of the index prior to truncating to the range 0-7
1474  */
1475  dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1476  dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1477  dag BE_MV_VBYTE = (MFVSRD
1478                      (EXTRACT_SUBREG
1479                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1480                        sub_64));
1481  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1482                                       sub_32);
1483  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1484                                         sub_32);
1485
1486  /*  BE variable halfword
1487      The algorithm here is the same as the LE variable halfword except:
1488      - The shift in the VMX register is by 0/8 for opposite element numbers so
1489        we simply AND the element number with 0x4 and multiply by 2
1490      - The order of elements after the move to GPR is reversed, so we invert
1491        the bits of the index prior to truncating to the range 0-3
1492  */
1493  dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1494  dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1495  dag BE_MV_VHALF = (MFVSRD
1496                      (EXTRACT_SUBREG
1497                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1498                        sub_64));
1499  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1500                                       sub_32);
1501  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1502                                         sub_32);
1503
1504  /*  BE variable word
1505      The algorithm is the same as the LE variable word except:
1506      - The shift in the VMX register happens for opposite element numbers
1507      - The order of elements after the move to GPR is reversed, so we invert
1508        the bits of the index prior to truncating to the range 0-1
1509  */
1510  dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1511  dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1512  dag BE_MV_VWORD = (MFVSRD
1513                      (EXTRACT_SUBREG
1514                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1515                        sub_64));
1516  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1517                                       sub_32);
1518  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1519                                         sub_32);
1520
1521  /*  BE variable doubleword
1522      Same as the LE doubleword except we shift in the VMX register for opposite
1523      element indices.
1524  */
1525  dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1526  dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1527  dag BE_VARIABLE_DWORD =
1528        (MFVSRD (EXTRACT_SUBREG
1529                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1530                  sub_64));
1531
1532  /*  BE variable float
1533      - Shift the vector to line up the desired element to BE Word 0
1534      - Convert 32-bit float to a 64-bit single precision float
1535  */
1536  dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1537  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1538  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1539
1540  /* BE variable double
1541      Same as the BE doubleword except there is no move.
1542  */
1543  dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1544                                  (COPY_TO_REGCLASS $S, VRRC),
1545                                  BE_VDWORD_PERM_VEC);
1546  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1547}
1548
1549// v4f32 scalar <-> vector conversions (BE)
1550let Predicates = [IsBigEndian, HasP8Vector] in {
1551  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1552            (v4f32 (XSCVDPSPN $A))>;
1553  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1554            (f32 (XSCVSPDPN $S))>;
1555  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1556            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1557  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1558            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 2)))>;
1559  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1560            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1561  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1562            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1563} // IsBigEndian, HasP8Vector
1564
1565// Variable index vector_extract for v2f64 does not require P8Vector
1566let Predicates = [IsBigEndian, HasVSX] in
1567  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1568            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1569
1570let Predicates = [IsBigEndian, HasDirectMove] in {
1571  // v16i8 scalar <-> vector conversions (BE)
1572  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1573            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1574  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1575            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1576  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1577            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1578  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1579            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1580  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1581            (i32 VectorExtractions.LE_BYTE_15)>;
1582  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1583            (i32 VectorExtractions.LE_BYTE_14)>;
1584  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1585            (i32 VectorExtractions.LE_BYTE_13)>;
1586  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1587            (i32 VectorExtractions.LE_BYTE_12)>;
1588  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1589            (i32 VectorExtractions.LE_BYTE_11)>;
1590  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1591            (i32 VectorExtractions.LE_BYTE_10)>;
1592  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1593            (i32 VectorExtractions.LE_BYTE_9)>;
1594  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1595            (i32 VectorExtractions.LE_BYTE_8)>;
1596  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1597            (i32 VectorExtractions.LE_BYTE_7)>;
1598  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1599            (i32 VectorExtractions.LE_BYTE_6)>;
1600  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1601            (i32 VectorExtractions.LE_BYTE_5)>;
1602  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1603            (i32 VectorExtractions.LE_BYTE_4)>;
1604  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1605            (i32 VectorExtractions.LE_BYTE_3)>;
1606  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1607            (i32 VectorExtractions.LE_BYTE_2)>;
1608  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1609            (i32 VectorExtractions.LE_BYTE_1)>;
1610  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1611            (i32 VectorExtractions.LE_BYTE_0)>;
1612  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1613            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1614
1615  // v8i16 scalar <-> vector conversions (BE)
1616  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1617            (i32 VectorExtractions.LE_HALF_7)>;
1618  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1619            (i32 VectorExtractions.LE_HALF_6)>;
1620  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1621            (i32 VectorExtractions.LE_HALF_5)>;
1622  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1623            (i32 VectorExtractions.LE_HALF_4)>;
1624  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1625            (i32 VectorExtractions.LE_HALF_3)>;
1626  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1627            (i32 VectorExtractions.LE_HALF_2)>;
1628  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1629            (i32 VectorExtractions.LE_HALF_1)>;
1630  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1631            (i32 VectorExtractions.LE_HALF_0)>;
1632  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1633            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1634
1635  // v4i32 scalar <-> vector conversions (BE)
1636  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1637            (i32 VectorExtractions.LE_WORD_3)>;
1638  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1639            (i32 VectorExtractions.LE_WORD_2)>;
1640  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1641            (i32 VectorExtractions.LE_WORD_1)>;
1642  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1643            (i32 VectorExtractions.LE_WORD_0)>;
1644  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1645            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1646
1647  // v2i64 scalar <-> vector conversions (BE)
1648  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1649            (i64 VectorExtractions.LE_DWORD_1)>;
1650  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1651            (i64 VectorExtractions.LE_DWORD_0)>;
1652  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1653            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1654} // IsBigEndian, HasDirectMove
1655
1656// v4f32 scalar <-> vector conversions (LE)
1657let Predicates = [IsLittleEndian, HasP8Vector] in {
1658  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1659            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1660  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1661            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1662  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1663            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 2)))>;
1664  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1665            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1666  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1667            (f32 (XSCVSPDPN $S))>;
1668  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1669            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1670} // IsLittleEndian, HasP8Vector
1671
1672// Variable index vector_extract for v2f64 does not require P8Vector
1673let Predicates = [IsLittleEndian, HasVSX] in
1674  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1675            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1676
1677let Predicates = [IsLittleEndian, HasDirectMove] in {
1678  // v16i8 scalar <-> vector conversions (LE)
1679  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1680            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1681  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1682            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1683  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1684            (v4i32 MovesToVSR.LE_WORD_0)>;
1685  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1686            (v2i64 MovesToVSR.LE_DWORD_0)>;
1687  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1688            (i32 VectorExtractions.LE_BYTE_0)>;
1689  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1690            (i32 VectorExtractions.LE_BYTE_1)>;
1691  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1692            (i32 VectorExtractions.LE_BYTE_2)>;
1693  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1694            (i32 VectorExtractions.LE_BYTE_3)>;
1695  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1696            (i32 VectorExtractions.LE_BYTE_4)>;
1697  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1698            (i32 VectorExtractions.LE_BYTE_5)>;
1699  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1700            (i32 VectorExtractions.LE_BYTE_6)>;
1701  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1702            (i32 VectorExtractions.LE_BYTE_7)>;
1703  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1704            (i32 VectorExtractions.LE_BYTE_8)>;
1705  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1706            (i32 VectorExtractions.LE_BYTE_9)>;
1707  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1708            (i32 VectorExtractions.LE_BYTE_10)>;
1709  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1710            (i32 VectorExtractions.LE_BYTE_11)>;
1711  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1712            (i32 VectorExtractions.LE_BYTE_12)>;
1713  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1714            (i32 VectorExtractions.LE_BYTE_13)>;
1715  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1716            (i32 VectorExtractions.LE_BYTE_14)>;
1717  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1718            (i32 VectorExtractions.LE_BYTE_15)>;
1719  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1720            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
1721
1722  // v8i16 scalar <-> vector conversions (LE)
1723  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1724            (i32 VectorExtractions.LE_HALF_0)>;
1725  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1726            (i32 VectorExtractions.LE_HALF_1)>;
1727  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1728            (i32 VectorExtractions.LE_HALF_2)>;
1729  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1730            (i32 VectorExtractions.LE_HALF_3)>;
1731  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1732            (i32 VectorExtractions.LE_HALF_4)>;
1733  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1734            (i32 VectorExtractions.LE_HALF_5)>;
1735  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1736            (i32 VectorExtractions.LE_HALF_6)>;
1737  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1738            (i32 VectorExtractions.LE_HALF_7)>;
1739  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1740            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
1741
1742  // v4i32 scalar <-> vector conversions (LE)
1743  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1744            (i32 VectorExtractions.LE_WORD_0)>;
1745  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1746            (i32 VectorExtractions.LE_WORD_1)>;
1747  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1748            (i32 VectorExtractions.LE_WORD_2)>;
1749  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1750            (i32 VectorExtractions.LE_WORD_3)>;
1751  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1752            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
1753
1754  // v2i64 scalar <-> vector conversions (LE)
1755  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1756            (i64 VectorExtractions.LE_DWORD_0)>;
1757  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1758            (i64 VectorExtractions.LE_DWORD_1)>;
1759  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1760            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
1761} // IsLittleEndian, HasDirectMove
1762
1763let Predicates = [HasDirectMove, HasVSX] in {
1764// bitconvert f32 -> i32
1765// (convert to 32-bit fp single, shift right 1 word, move to GPR)
1766def : Pat<(i32 (bitconvert f32:$S)),
1767          (i32 (MFVSRWZ (EXTRACT_SUBREG
1768                          (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
1769                          sub_64)))>;
1770// bitconvert i32 -> f32
1771// (move to FPR, shift left 1 word, convert to 64-bit fp single)
1772def : Pat<(f32 (bitconvert i32:$A)),
1773          (f32 (XSCVSPDPN
1774                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
1775
1776// bitconvert f64 -> i64
1777// (move to GPR, nothing else needed)
1778def : Pat<(i64 (bitconvert f64:$S)),
1779          (i64 (MFVSRD $S))>;
1780
1781// bitconvert i64 -> f64
1782// (move to FPR, nothing else needed)
1783def : Pat<(f64 (bitconvert i64:$S)),
1784          (f64 (MTVSRD $S))>;
1785}
1786
1787// The following VSX instructions were introduced in Power ISA 3.0
1788def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
1789let Predicates = [HasP9Vector] in {
1790
1791  // [PO VRT XO VRB XO /]
1792  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1793                      list<dag> pattern>
1794    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
1795                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1796
1797  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
1798  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1799                         list<dag> pattern>
1800    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
1801
1802  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
1803  // So we use different operand class for VRB
1804  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1805                           RegisterOperand vbtype, list<dag> pattern>
1806    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
1807                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1808
1809  // [PO T XO B XO BX /]
1810  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
1811                        list<dag> pattern>
1812    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
1813                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
1814
1815  // [PO T XO B XO BX TX]
1816  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
1817                        RegisterOperand vtype, list<dag> pattern>
1818    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
1819                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
1820
1821  // [PO T A B XO AX BX TX], src and dest register use different operand class
1822  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
1823                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
1824                  InstrItinClass itin, list<dag> pattern>
1825    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
1826              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
1827
1828  // [PO VRT VRA VRB XO /]
1829  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
1830                      list<dag> pattern>
1831    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
1832              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
1833
1834  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
1835  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
1836                         list<dag> pattern>
1837    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
1838
1839  //===--------------------------------------------------------------------===//
1840  // Quad-Precision Scalar Move Instructions:
1841
1842  // Copy Sign
1843  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
1844
1845  // Absolute/Negative-Absolute/Negate
1846  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
1847  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
1848  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
1849
1850  //===--------------------------------------------------------------------===//
1851  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
1852
1853  // Add/Divide/Multiply/Subtract
1854  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
1855  def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
1856  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
1857  def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
1858  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
1859  def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
1860  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
1861  def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
1862
1863  // Square-Root
1864  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
1865  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
1866
1867  // (Negative) Multiply-{Add/Subtract}
1868  def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
1869  def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
1870  def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
1871  def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
1872  def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
1873  def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
1874  def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
1875  def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
1876
1877  //===--------------------------------------------------------------------===//
1878  // Quad/Double-Precision Compare Instructions:
1879
1880  // [PO BF // VRA VRB XO /]
1881  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
1882                      list<dag> pattern>
1883    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
1884               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
1885    let Pattern = pattern;
1886  }
1887
1888  // QP Compare Ordered/Unordered
1889  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1890  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1891
1892  // DP/QP Compare Exponents
1893  def XSCMPEXPDP : XX3Form_1<60, 59,
1894                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
1895                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
1896  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
1897
1898  // DP Compare ==, >=, >, !=
1899  // Use vsrc for XT, because the entire register of XT is set.
1900  // XT.dword[1] = 0x0000_0000_0000_0000
1901  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
1902                                  IIC_FPCompare, []>;
1903  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
1904                                  IIC_FPCompare, []>;
1905  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
1906                                  IIC_FPCompare, []>;
1907  def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
1908                                  IIC_FPCompare, []>;
1909  // Vector Compare Not Equal
1910  def XVCMPNEDP  : XX3Form_Rc<60, 123,
1911                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1912                              "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
1913  let Defs = [CR6] in
1914  def XVCMPNEDPo : XX3Form_Rc<60, 123,
1915                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1916                              "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
1917                              isDOT;
1918  def XVCMPNESP  : XX3Form_Rc<60,  91,
1919                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1920                              "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
1921  let Defs = [CR6] in
1922  def XVCMPNESPo : XX3Form_Rc<60,  91,
1923                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1924                              "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
1925                              isDOT;
1926
1927  //===--------------------------------------------------------------------===//
1928  // Quad-Precision Floating-Point Conversion Instructions:
1929
1930  // Convert DP -> QP
1931  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vsfrc, []>;
1932
1933  // Round & Convert QP -> DP (dword[1] is set to zero)
1934  def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
1935  def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
1936
1937  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1938  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
1939  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
1940  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
1941  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
1942
1943  // Convert (Un)Signed DWord -> QP
1944  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vsfrc, []>;
1945  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vsfrc, []>;
1946
1947  //===--------------------------------------------------------------------===//
1948  // Round to Floating-Point Integer Instructions
1949
1950  // (Round &) Convert DP <-> HP
1951  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
1952  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
1953  // but we still use vsfrc for it.
1954  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
1955  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
1956
1957  // Vector HP -> SP
1958  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
1959  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc, []>;
1960
1961  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
1962                                list<dag> pattern>
1963    : Z23Form_1<opcode, xo,
1964                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
1965                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
1966    let RC = ex;
1967  }
1968
1969  // Round to Quad-Precision Integer [with Inexact]
1970  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
1971  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
1972
1973  // Round Quad-Precision to Double-Extended Precision (fp80)
1974  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1975
1976  //===--------------------------------------------------------------------===//
1977  // Insert/Extract Instructions
1978
1979  // Insert Exponent DP/QP
1980  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
1981  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1982                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
1983  // vB NOTE: only vB.dword[0] is used, that's why we don't use
1984  //          X_VT5_VA5_VB5 form
1985  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
1986                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
1987
1988  // Extract Exponent/Significand DP/QP
1989  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
1990  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
1991  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
1992  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
1993
1994  // Vector Insert Word
1995  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
1996  def XXINSERTW   : XX2_RD6_UIM5_RS6<60, 181,
1997                                  (outs vsrc:$XT), (ins u4imm:$UIMM, vsrc:$XB),
1998                                  "xxinsertw $XT, $XB, $UIMM", IIC_VecFP, []>;
1999
2000  // Vector Extract Unsigned Word
2001  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2002                                  (outs vsrc:$XT), (ins u4imm:$UIMM, vsrc:$XB),
2003                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2004
2005  // Vector Insert Exponent DP/SP
2006  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2007                                 IIC_VecFP, []>;
2008  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2009                                 IIC_VecFP, []>;
2010
2011  // Vector Extract Exponent/Significand DP/SP
2012  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc, []>;
2013  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc, []>;
2014  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc, []>;
2015  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc, []>;
2016
2017  //===--------------------------------------------------------------------===//
2018
2019  // Test Data Class SP/DP/QP
2020  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2021                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2022                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2023  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2024                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2025                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2026  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2027                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2028                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2029
2030  // Vector Test Data Class SP/DP
2031  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2032                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2033                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP, []>;
2034  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2035                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2036                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP, []>;
2037
2038  //===--------------------------------------------------------------------===//
2039
2040  // Maximum/Minimum Type-C/Type-J DP
2041  // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2042  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2043                                 IIC_VecFP, []>;
2044  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2045                                 IIC_VecFP, []>;
2046  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2047                                 IIC_VecFP, []>;
2048  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2049                                 IIC_VecFP, []>;
2050
2051  //===--------------------------------------------------------------------===//
2052
2053  // Vector Byte-Reverse H/W/D/Q Word
2054  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2055  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2056  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2057  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2058
2059  // Vector Permute
2060  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2061                                IIC_VecPerm, []>;
2062  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2063                                IIC_VecPerm, []>;
2064
2065  // Vector Splat Immediate Byte
2066  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2067                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
2068
2069  //===--------------------------------------------------------------------===//
2070  // Vector/Scalar Load/Store Instructions
2071
2072  let mayLoad = 1 in {
2073  // Load Vector
2074  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2075                            "lxv $XT, $src", IIC_LdStLFD, []>;
2076  // Load DWord
2077  def LXSD  : DSForm_1<57, 2, (outs vrrc:$vD), (ins memrix:$src),
2078                       "lxsd $vD, $src", IIC_LdStLFD, []>;
2079  // Load SP from src, convert it to DP, and place in dword[0]
2080  def LXSSP : DSForm_1<57, 3, (outs vrrc:$vD), (ins memrix:$src),
2081                       "lxssp $vD, $src", IIC_LdStLFD, []>;
2082
2083  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2084  // "out" and "in" dag
2085  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2086                      RegisterOperand vtype, list<dag> pattern>
2087    : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2088              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2089
2090  // Load as Integer Byte/Halfword & Zero Indexed
2091  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc, []>;
2092  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc, []>;
2093
2094  // Load Vector Halfword*8/Byte*16 Indexed
2095  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2096  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2097
2098  // Load Vector Indexed
2099  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc, []>;
2100
2101  // Load Vector (Left-justified) with Length
2102  def LXVL    : X_XT6_RA5_RB5<31, 269, "lxvl"   , vsrc, []>;
2103  def LXVLL   : X_XT6_RA5_RB5<31, 301, "lxvll"  , vsrc, []>;
2104
2105  // Load Vector Word & Splat Indexed
2106  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2107  } // end mayLoad
2108
2109  let mayStore = 1 in {
2110  // Store Vector
2111  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2112                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
2113  // Store DWord
2114  def STXSD  : DSForm_1<61, 2, (outs), (ins vrrc:$vS, memrix:$dst),
2115                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2116  // Convert DP of dword[0] to SP, and Store to dst
2117  def STXSSP : DSForm_1<61, 3, (outs), (ins vrrc:$vS, memrix:$dst),
2118                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2119
2120  // [PO S RA RB XO SX]
2121  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2122                      RegisterOperand vtype, list<dag> pattern>
2123    : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2124              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2125
2126  // Store as Integer Byte/Halfword Indexed
2127  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc, []>;
2128  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc, []>;
2129
2130  // Store Vector Halfword*8/Byte*16 Indexed
2131  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2132  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2133
2134  // Store Vector Indexed
2135  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc, []>;
2136
2137  // Store Vector (Left-justified) with Length
2138  def STXVL    : X_XS6_RA5_RB5<31,  397, "stxvl"   , vsrc, []>;
2139  def STXVLL   : X_XS6_RA5_RB5<31,  429, "stxvll"  , vsrc, []>;
2140  } // end mayStore
2141} // end HasP9Vector
2142