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 29 def PPCRegVSRCAsmOperand : AsmOperandClass { 30 let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber"; 31 } 32 def vsrc : RegisterOperand<VSRC> { 33 let ParserMatchClass = PPCRegVSRCAsmOperand; 34 } 35 36 def PPCRegVSFRCAsmOperand : AsmOperandClass { 37 let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber"; 38 } 39 def vsfrc : RegisterOperand<VSFRC> { 40 let ParserMatchClass = PPCRegVSFRCAsmOperand; 41 } 42 43 def PPCRegVSSRCAsmOperand : AsmOperandClass { 44 let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber"; 45 } 46 def vssrc : RegisterOperand<VSSRC> { 47 let ParserMatchClass = PPCRegVSSRCAsmOperand; 48 } 49 50 // Little-endian-specific nodes. 51 def SDT_PPClxvd2x : SDTypeProfile<1, 1, [ 52 SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 53 ]>; 54 def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [ 55 SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 56 ]>; 57 def SDT_PPCxxswapd : SDTypeProfile<1, 1, [ 58 SDTCisSameAs<0, 1> 59 ]>; 60 61 def PPClxvd2x : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x, 62 [SDNPHasChain, SDNPMayLoad]>; 63 def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x, 64 [SDNPHasChain, SDNPMayStore]>; 65 def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>; 66 def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>; 67 def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>; 68 def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>; 69 70 multiclass 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 86 def HasVSX : Predicate<"PPCSubTarget->hasVSX()">; 87 def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">; 88 def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">; 89 90 let Predicates = [HasVSX] in { 91 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 92 let hasSideEffects = 0 in { // VSX instructions don't have side effects. 93 let 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. 783 let 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 816 def : InstAlias<"xvmovdp $XT, $XB", 817 (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 818 def : InstAlias<"xvmovsp $XT, $XB", 819 (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 820 821 def : InstAlias<"xxspltd $XT, $XB, 0", 822 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>; 823 def : InstAlias<"xxspltd $XT, $XB, 1", 824 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>; 825 def : InstAlias<"xxmrghd $XT, $XA, $XB", 826 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>; 827 def : InstAlias<"xxmrgld $XT, $XA, $XB", 828 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>; 829 def : InstAlias<"xxswapd $XT, $XB", 830 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>; 831 832 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 833 834 let Predicates = [IsBigEndian] in { 835 def : Pat<(v2f64 (scalar_to_vector f64:$A)), 836 (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>; 837 838 def : Pat<(f64 (extractelt v2f64:$S, 0)), 839 (f64 (EXTRACT_SUBREG $S, sub_64))>; 840 def : Pat<(f64 (extractelt v2f64:$S, 1)), 841 (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 842 } 843 844 let Predicates = [IsLittleEndian] in { 845 def : 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 849 def : Pat<(f64 (extractelt v2f64:$S, 0)), 850 (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 851 def : 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) 856 def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), 857 (XSNMSUBADP $B, $C, $A)>; 858 def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B), 859 (XSNMSUBADP $B, $C, $A)>; 860 861 def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B), 862 (XVNMSUBADP $B, $C, $A)>; 863 def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B), 864 (XVNMSUBADP $B, $C, $A)>; 865 866 def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B), 867 (XVNMSUBASP $B, $C, $A)>; 868 def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B), 869 (XVNMSUBASP $B, $C, $A)>; 870 871 def : Pat<(v2f64 (bitconvert v4f32:$A)), 872 (COPY_TO_REGCLASS $A, VSRC)>; 873 def : Pat<(v2f64 (bitconvert v4i32:$A)), 874 (COPY_TO_REGCLASS $A, VSRC)>; 875 def : Pat<(v2f64 (bitconvert v8i16:$A)), 876 (COPY_TO_REGCLASS $A, VSRC)>; 877 def : Pat<(v2f64 (bitconvert v16i8:$A)), 878 (COPY_TO_REGCLASS $A, VSRC)>; 879 880 def : Pat<(v4f32 (bitconvert v2f64:$A)), 881 (COPY_TO_REGCLASS $A, VRRC)>; 882 def : Pat<(v4i32 (bitconvert v2f64:$A)), 883 (COPY_TO_REGCLASS $A, VRRC)>; 884 def : Pat<(v8i16 (bitconvert v2f64:$A)), 885 (COPY_TO_REGCLASS $A, VRRC)>; 886 def : Pat<(v16i8 (bitconvert v2f64:$A)), 887 (COPY_TO_REGCLASS $A, VRRC)>; 888 889 def : Pat<(v2i64 (bitconvert v4f32:$A)), 890 (COPY_TO_REGCLASS $A, VSRC)>; 891 def : Pat<(v2i64 (bitconvert v4i32:$A)), 892 (COPY_TO_REGCLASS $A, VSRC)>; 893 def : Pat<(v2i64 (bitconvert v8i16:$A)), 894 (COPY_TO_REGCLASS $A, VSRC)>; 895 def : Pat<(v2i64 (bitconvert v16i8:$A)), 896 (COPY_TO_REGCLASS $A, VSRC)>; 897 898 def : Pat<(v4f32 (bitconvert v2i64:$A)), 899 (COPY_TO_REGCLASS $A, VRRC)>; 900 def : Pat<(v4i32 (bitconvert v2i64:$A)), 901 (COPY_TO_REGCLASS $A, VRRC)>; 902 def : Pat<(v8i16 (bitconvert v2i64:$A)), 903 (COPY_TO_REGCLASS $A, VRRC)>; 904 def : Pat<(v16i8 (bitconvert v2i64:$A)), 905 (COPY_TO_REGCLASS $A, VRRC)>; 906 907 def : Pat<(v2f64 (bitconvert v2i64:$A)), 908 (COPY_TO_REGCLASS $A, VRRC)>; 909 def : Pat<(v2i64 (bitconvert v2f64:$A)), 910 (COPY_TO_REGCLASS $A, VRRC)>; 911 912 def : Pat<(v2f64 (bitconvert v1i128:$A)), 913 (COPY_TO_REGCLASS $A, VRRC)>; 914 def : 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. 924 def : Pat<(sext_inreg v2i64:$C, v2i32), 925 (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>; 926 def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))), 927 (XVCVSXWDP (XXSLDWI $C, $C, 1))>; 928 929 // Loads. 930 def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 931 def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 932 def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>; 933 def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>; 934 935 // Stores. 936 def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), 937 (STXVD2X $rS, xoaddr:$dst)>; 938 def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 939 def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), 940 (STXVW4X $rS, xoaddr:$dst)>; 941 def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 942 943 // Permutes. 944 def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>; 945 def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>; 946 def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>; 947 def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>; 948 949 // Selects. 950 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)), 951 (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 952 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)), 953 (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 954 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)), 955 (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 956 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)), 957 (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 958 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)), 959 (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>; 960 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)), 961 (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 962 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)), 963 (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 964 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)), 965 (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 966 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)), 967 (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 968 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)), 969 (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 970 971 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)), 972 (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 973 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)), 974 (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 975 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)), 976 (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 977 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)), 978 (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 979 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)), 980 (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>; 981 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)), 982 (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 983 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)), 984 (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 985 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)), 986 (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 987 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)), 988 (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 989 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)), 990 (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>; 991 992 // Divides. 993 def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B), 994 (XVDIVSP $A, $B)>; 995 def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B), 996 (XVDIVDP $A, $B)>; 997 998 // Reciprocal estimate 999 def : Pat<(int_ppc_vsx_xvresp v4f32:$A), 1000 (XVRESP $A)>; 1001 def : Pat<(int_ppc_vsx_xvredp v2f64:$A), 1002 (XVREDP $A)>; 1003 1004 // Recip. square root estimate 1005 def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A), 1006 (XVRSQRTESP $A)>; 1007 def : 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 */ 1018 def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">; 1019 def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">; 1020 let Predicates = [HasP8Vector] in { 1021 let 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 1219 let 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 */ 1245 def 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 */ 1276 def 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) 1550 let 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 1566 let Predicates = [IsBigEndian, HasVSX] in 1567 def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 1568 (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>; 1569 1570 let 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) 1657 let 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 1673 let Predicates = [IsLittleEndian, HasVSX] in 1674 def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 1675 (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>; 1676 1677 let 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 1763 let Predicates = [HasDirectMove, HasVSX] in { 1764 // bitconvert f32 -> i32 1765 // (convert to 32-bit fp single, shift right 1 word, move to GPR) 1766 def : 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) 1772 def : 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) 1778 def : Pat<(i64 (bitconvert f64:$S)), 1779 (i64 (MFVSRD $S))>; 1780 1781 // bitconvert i64 -> f64 1782 // (move to FPR, nothing else needed) 1783 def : Pat<(f64 (bitconvert i64:$S)), 1784 (f64 (MTVSRD $S))>; 1785 } 1786