• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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