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 50def PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass { 51 let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber"; 52} 53 54def spilltovsrrc : RegisterOperand<SPILLTOVSRRC> { 55 let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand; 56} 57// Little-endian-specific nodes. 58def SDT_PPClxvd2x : SDTypeProfile<1, 1, [ 59 SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 60]>; 61def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [ 62 SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 63]>; 64def SDT_PPCxxswapd : SDTypeProfile<1, 1, [ 65 SDTCisSameAs<0, 1> 66]>; 67def SDTVecConv : SDTypeProfile<1, 2, [ 68 SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2> 69]>; 70 71def PPClxvd2x : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x, 72 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 73def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x, 74 [SDNPHasChain, SDNPMayStore]>; 75def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>; 76def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>; 77def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>; 78def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>; 79def PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>; 80def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>; 81def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>; 82 83multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase, 84 string asmstr, InstrItinClass itin, Intrinsic Int, 85 ValueType OutTy, ValueType InTy> { 86 let BaseName = asmbase in { 87 def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 88 !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 89 [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>; 90 let Defs = [CR6] in 91 def o : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 92 !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 93 [(set InTy:$XT, 94 (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>, 95 isDOT; 96 } 97} 98 99// Instruction form with a single input register for instructions such as 100// XXPERMDI. The reason for defining this is that specifying multiple chained 101// operands (such as loads) to an instruction will perform both chained 102// operations rather than coalescing them into a single register - even though 103// the source memory location is the same. This simply forces the instruction 104// to use the same register for both inputs. 105// For example, an output DAG such as this: 106// (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0)) 107// would result in two load instructions emitted and used as separate inputs 108// to the XXPERMDI instruction. 109class XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr, 110 InstrItinClass itin, list<dag> pattern> 111 : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> { 112 let XB = XA; 113} 114 115def HasVSX : Predicate<"PPCSubTarget->hasVSX()">; 116def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">; 117def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">; 118def HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">; 119 120let Predicates = [HasVSX] in { 121let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 122let UseVSXReg = 1 in { 123let hasSideEffects = 0 in { // VSX instructions don't have side effects. 124let Uses = [RM] in { 125 126 // Load indexed instructions 127 let mayLoad = 1, mayStore = 0 in { 128 let CodeSize = 3 in 129 def LXSDX : XX1Form<31, 588, 130 (outs vsfrc:$XT), (ins memrr:$src), 131 "lxsdx $XT, $src", IIC_LdStLFD, 132 [(set f64:$XT, (load xoaddr:$src))]>; 133 134 let Predicates = [HasVSX, HasOnlySwappingMemOps] in 135 def LXVD2X : XX1Form<31, 844, 136 (outs vsrc:$XT), (ins memrr:$src), 137 "lxvd2x $XT, $src", IIC_LdStLFD, 138 [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>; 139 140 def LXVDSX : XX1Form<31, 332, 141 (outs vsrc:$XT), (ins memrr:$src), 142 "lxvdsx $XT, $src", IIC_LdStLFD, []>; 143 144 let Predicates = [HasVSX, HasOnlySwappingMemOps] in 145 def LXVW4X : XX1Form<31, 780, 146 (outs vsrc:$XT), (ins memrr:$src), 147 "lxvw4x $XT, $src", IIC_LdStLFD, 148 []>; 149 } // mayLoad 150 151 // Store indexed instructions 152 let mayStore = 1, mayLoad = 0 in { 153 let CodeSize = 3 in 154 def STXSDX : XX1Form<31, 716, 155 (outs), (ins vsfrc:$XT, memrr:$dst), 156 "stxsdx $XT, $dst", IIC_LdStSTFD, 157 [(store f64:$XT, xoaddr:$dst)]>; 158 159 let Predicates = [HasVSX, HasOnlySwappingMemOps] in { 160 // The behaviour of this instruction is endianness-specific so we provide no 161 // pattern to match it without considering endianness. 162 def STXVD2X : XX1Form<31, 972, 163 (outs), (ins vsrc:$XT, memrr:$dst), 164 "stxvd2x $XT, $dst", IIC_LdStSTFD, 165 []>; 166 167 def STXVW4X : XX1Form<31, 908, 168 (outs), (ins vsrc:$XT, memrr:$dst), 169 "stxvw4x $XT, $dst", IIC_LdStSTFD, 170 []>; 171 } 172 } // mayStore 173 174 // Add/Mul Instructions 175 let isCommutable = 1 in { 176 def XSADDDP : XX3Form<60, 32, 177 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 178 "xsadddp $XT, $XA, $XB", IIC_VecFP, 179 [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>; 180 def XSMULDP : XX3Form<60, 48, 181 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 182 "xsmuldp $XT, $XA, $XB", IIC_VecFP, 183 [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>; 184 185 def XVADDDP : XX3Form<60, 96, 186 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 187 "xvadddp $XT, $XA, $XB", IIC_VecFP, 188 [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>; 189 190 def XVADDSP : XX3Form<60, 64, 191 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 192 "xvaddsp $XT, $XA, $XB", IIC_VecFP, 193 [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>; 194 195 def XVMULDP : XX3Form<60, 112, 196 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 197 "xvmuldp $XT, $XA, $XB", IIC_VecFP, 198 [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>; 199 200 def XVMULSP : XX3Form<60, 80, 201 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 202 "xvmulsp $XT, $XA, $XB", IIC_VecFP, 203 [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>; 204 } 205 206 // Subtract Instructions 207 def XSSUBDP : XX3Form<60, 40, 208 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 209 "xssubdp $XT, $XA, $XB", IIC_VecFP, 210 [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>; 211 212 def XVSUBDP : XX3Form<60, 104, 213 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 214 "xvsubdp $XT, $XA, $XB", IIC_VecFP, 215 [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>; 216 def XVSUBSP : XX3Form<60, 72, 217 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 218 "xvsubsp $XT, $XA, $XB", IIC_VecFP, 219 [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>; 220 221 // FMA Instructions 222 let BaseName = "XSMADDADP" in { 223 let isCommutable = 1 in 224 def XSMADDADP : XX3Form<60, 33, 225 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 226 "xsmaddadp $XT, $XA, $XB", IIC_VecFP, 227 [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>, 228 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 229 AltVSXFMARel; 230 let IsVSXFMAAlt = 1 in 231 def XSMADDMDP : XX3Form<60, 41, 232 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 233 "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 234 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 235 AltVSXFMARel; 236 } 237 238 let BaseName = "XSMSUBADP" in { 239 let isCommutable = 1 in 240 def XSMSUBADP : XX3Form<60, 49, 241 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 242 "xsmsubadp $XT, $XA, $XB", IIC_VecFP, 243 [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>, 244 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 245 AltVSXFMARel; 246 let IsVSXFMAAlt = 1 in 247 def XSMSUBMDP : XX3Form<60, 57, 248 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 249 "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 250 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 251 AltVSXFMARel; 252 } 253 254 let BaseName = "XSNMADDADP" in { 255 let isCommutable = 1 in 256 def XSNMADDADP : XX3Form<60, 161, 257 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 258 "xsnmaddadp $XT, $XA, $XB", IIC_VecFP, 259 [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>, 260 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 261 AltVSXFMARel; 262 let IsVSXFMAAlt = 1 in 263 def XSNMADDMDP : XX3Form<60, 169, 264 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 265 "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 266 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 267 AltVSXFMARel; 268 } 269 270 let BaseName = "XSNMSUBADP" in { 271 let isCommutable = 1 in 272 def XSNMSUBADP : XX3Form<60, 177, 273 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 274 "xsnmsubadp $XT, $XA, $XB", IIC_VecFP, 275 [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>, 276 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 277 AltVSXFMARel; 278 let IsVSXFMAAlt = 1 in 279 def XSNMSUBMDP : XX3Form<60, 185, 280 (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 281 "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 282 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 283 AltVSXFMARel; 284 } 285 286 let BaseName = "XVMADDADP" in { 287 let isCommutable = 1 in 288 def XVMADDADP : XX3Form<60, 97, 289 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 290 "xvmaddadp $XT, $XA, $XB", IIC_VecFP, 291 [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>, 292 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 293 AltVSXFMARel; 294 let IsVSXFMAAlt = 1 in 295 def XVMADDMDP : XX3Form<60, 105, 296 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 297 "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 298 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 299 AltVSXFMARel; 300 } 301 302 let BaseName = "XVMADDASP" in { 303 let isCommutable = 1 in 304 def XVMADDASP : XX3Form<60, 65, 305 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 306 "xvmaddasp $XT, $XA, $XB", IIC_VecFP, 307 [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>, 308 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 309 AltVSXFMARel; 310 let IsVSXFMAAlt = 1 in 311 def XVMADDMSP : XX3Form<60, 73, 312 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 313 "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 314 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 315 AltVSXFMARel; 316 } 317 318 let BaseName = "XVMSUBADP" in { 319 let isCommutable = 1 in 320 def XVMSUBADP : XX3Form<60, 113, 321 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 322 "xvmsubadp $XT, $XA, $XB", IIC_VecFP, 323 [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>, 324 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 325 AltVSXFMARel; 326 let IsVSXFMAAlt = 1 in 327 def XVMSUBMDP : XX3Form<60, 121, 328 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 329 "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 330 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 331 AltVSXFMARel; 332 } 333 334 let BaseName = "XVMSUBASP" in { 335 let isCommutable = 1 in 336 def XVMSUBASP : XX3Form<60, 81, 337 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 338 "xvmsubasp $XT, $XA, $XB", IIC_VecFP, 339 [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>, 340 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 341 AltVSXFMARel; 342 let IsVSXFMAAlt = 1 in 343 def XVMSUBMSP : XX3Form<60, 89, 344 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 345 "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 346 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 347 AltVSXFMARel; 348 } 349 350 let BaseName = "XVNMADDADP" in { 351 let isCommutable = 1 in 352 def XVNMADDADP : XX3Form<60, 225, 353 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 354 "xvnmaddadp $XT, $XA, $XB", IIC_VecFP, 355 [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>, 356 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 357 AltVSXFMARel; 358 let IsVSXFMAAlt = 1 in 359 def XVNMADDMDP : XX3Form<60, 233, 360 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 361 "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 362 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 363 AltVSXFMARel; 364 } 365 366 let BaseName = "XVNMADDASP" in { 367 let isCommutable = 1 in 368 def XVNMADDASP : XX3Form<60, 193, 369 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 370 "xvnmaddasp $XT, $XA, $XB", IIC_VecFP, 371 [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>, 372 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 373 AltVSXFMARel; 374 let IsVSXFMAAlt = 1 in 375 def XVNMADDMSP : XX3Form<60, 201, 376 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 377 "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 378 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 379 AltVSXFMARel; 380 } 381 382 let BaseName = "XVNMSUBADP" in { 383 let isCommutable = 1 in 384 def XVNMSUBADP : XX3Form<60, 241, 385 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 386 "xvnmsubadp $XT, $XA, $XB", IIC_VecFP, 387 [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>, 388 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 389 AltVSXFMARel; 390 let IsVSXFMAAlt = 1 in 391 def XVNMSUBMDP : XX3Form<60, 249, 392 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 393 "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 394 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 395 AltVSXFMARel; 396 } 397 398 let BaseName = "XVNMSUBASP" in { 399 let isCommutable = 1 in 400 def XVNMSUBASP : XX3Form<60, 209, 401 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 402 "xvnmsubasp $XT, $XA, $XB", IIC_VecFP, 403 [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>, 404 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 405 AltVSXFMARel; 406 let IsVSXFMAAlt = 1 in 407 def XVNMSUBMSP : XX3Form<60, 217, 408 (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 409 "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 410 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 411 AltVSXFMARel; 412 } 413 414 // Division Instructions 415 def XSDIVDP : XX3Form<60, 56, 416 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 417 "xsdivdp $XT, $XA, $XB", IIC_FPDivD, 418 [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>; 419 def XSSQRTDP : XX2Form<60, 75, 420 (outs vsfrc:$XT), (ins vsfrc:$XB), 421 "xssqrtdp $XT, $XB", IIC_FPSqrtD, 422 [(set f64:$XT, (fsqrt f64:$XB))]>; 423 424 def XSREDP : XX2Form<60, 90, 425 (outs vsfrc:$XT), (ins vsfrc:$XB), 426 "xsredp $XT, $XB", IIC_VecFP, 427 [(set f64:$XT, (PPCfre f64:$XB))]>; 428 def XSRSQRTEDP : XX2Form<60, 74, 429 (outs vsfrc:$XT), (ins vsfrc:$XB), 430 "xsrsqrtedp $XT, $XB", IIC_VecFP, 431 [(set f64:$XT, (PPCfrsqrte f64:$XB))]>; 432 433 def XSTDIVDP : XX3Form_1<60, 61, 434 (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 435 "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 436 def XSTSQRTDP : XX2Form_1<60, 106, 437 (outs crrc:$crD), (ins vsfrc:$XB), 438 "xstsqrtdp $crD, $XB", IIC_FPCompare, []>; 439 440 def XVDIVDP : XX3Form<60, 120, 441 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 442 "xvdivdp $XT, $XA, $XB", IIC_FPDivD, 443 [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>; 444 def XVDIVSP : XX3Form<60, 88, 445 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 446 "xvdivsp $XT, $XA, $XB", IIC_FPDivS, 447 [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>; 448 449 def XVSQRTDP : XX2Form<60, 203, 450 (outs vsrc:$XT), (ins vsrc:$XB), 451 "xvsqrtdp $XT, $XB", IIC_FPSqrtD, 452 [(set v2f64:$XT, (fsqrt v2f64:$XB))]>; 453 def XVSQRTSP : XX2Form<60, 139, 454 (outs vsrc:$XT), (ins vsrc:$XB), 455 "xvsqrtsp $XT, $XB", IIC_FPSqrtS, 456 [(set v4f32:$XT, (fsqrt v4f32:$XB))]>; 457 458 def XVTDIVDP : XX3Form_1<60, 125, 459 (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 460 "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 461 def XVTDIVSP : XX3Form_1<60, 93, 462 (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 463 "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>; 464 465 def XVTSQRTDP : XX2Form_1<60, 234, 466 (outs crrc:$crD), (ins vsrc:$XB), 467 "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>; 468 def XVTSQRTSP : XX2Form_1<60, 170, 469 (outs crrc:$crD), (ins vsrc:$XB), 470 "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>; 471 472 def XVREDP : XX2Form<60, 218, 473 (outs vsrc:$XT), (ins vsrc:$XB), 474 "xvredp $XT, $XB", IIC_VecFP, 475 [(set v2f64:$XT, (PPCfre v2f64:$XB))]>; 476 def XVRESP : XX2Form<60, 154, 477 (outs vsrc:$XT), (ins vsrc:$XB), 478 "xvresp $XT, $XB", IIC_VecFP, 479 [(set v4f32:$XT, (PPCfre v4f32:$XB))]>; 480 481 def XVRSQRTEDP : XX2Form<60, 202, 482 (outs vsrc:$XT), (ins vsrc:$XB), 483 "xvrsqrtedp $XT, $XB", IIC_VecFP, 484 [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>; 485 def XVRSQRTESP : XX2Form<60, 138, 486 (outs vsrc:$XT), (ins vsrc:$XB), 487 "xvrsqrtesp $XT, $XB", IIC_VecFP, 488 [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>; 489 490 // Compare Instructions 491 def XSCMPODP : XX3Form_1<60, 43, 492 (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 493 "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>; 494 def XSCMPUDP : XX3Form_1<60, 35, 495 (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 496 "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>; 497 498 defm XVCMPEQDP : XX3Form_Rcr<60, 99, 499 "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare, 500 int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>; 501 defm XVCMPEQSP : XX3Form_Rcr<60, 67, 502 "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare, 503 int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>; 504 defm XVCMPGEDP : XX3Form_Rcr<60, 115, 505 "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare, 506 int_ppc_vsx_xvcmpgedp, v2i64, v2f64>; 507 defm XVCMPGESP : XX3Form_Rcr<60, 83, 508 "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare, 509 int_ppc_vsx_xvcmpgesp, v4i32, v4f32>; 510 defm XVCMPGTDP : XX3Form_Rcr<60, 107, 511 "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare, 512 int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>; 513 defm XVCMPGTSP : XX3Form_Rcr<60, 75, 514 "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare, 515 int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>; 516 517 // Move Instructions 518 def XSABSDP : XX2Form<60, 345, 519 (outs vsfrc:$XT), (ins vsfrc:$XB), 520 "xsabsdp $XT, $XB", IIC_VecFP, 521 [(set f64:$XT, (fabs f64:$XB))]>; 522 def XSNABSDP : XX2Form<60, 361, 523 (outs vsfrc:$XT), (ins vsfrc:$XB), 524 "xsnabsdp $XT, $XB", IIC_VecFP, 525 [(set f64:$XT, (fneg (fabs f64:$XB)))]>; 526 def XSNEGDP : XX2Form<60, 377, 527 (outs vsfrc:$XT), (ins vsfrc:$XB), 528 "xsnegdp $XT, $XB", IIC_VecFP, 529 [(set f64:$XT, (fneg f64:$XB))]>; 530 def XSCPSGNDP : XX3Form<60, 176, 531 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 532 "xscpsgndp $XT, $XA, $XB", IIC_VecFP, 533 [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>; 534 535 def XVABSDP : XX2Form<60, 473, 536 (outs vsrc:$XT), (ins vsrc:$XB), 537 "xvabsdp $XT, $XB", IIC_VecFP, 538 [(set v2f64:$XT, (fabs v2f64:$XB))]>; 539 540 def XVABSSP : XX2Form<60, 409, 541 (outs vsrc:$XT), (ins vsrc:$XB), 542 "xvabssp $XT, $XB", IIC_VecFP, 543 [(set v4f32:$XT, (fabs v4f32:$XB))]>; 544 545 def XVCPSGNDP : XX3Form<60, 240, 546 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 547 "xvcpsgndp $XT, $XA, $XB", IIC_VecFP, 548 [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>; 549 def XVCPSGNSP : XX3Form<60, 208, 550 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 551 "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP, 552 [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>; 553 554 def XVNABSDP : XX2Form<60, 489, 555 (outs vsrc:$XT), (ins vsrc:$XB), 556 "xvnabsdp $XT, $XB", IIC_VecFP, 557 [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>; 558 def XVNABSSP : XX2Form<60, 425, 559 (outs vsrc:$XT), (ins vsrc:$XB), 560 "xvnabssp $XT, $XB", IIC_VecFP, 561 [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>; 562 563 def XVNEGDP : XX2Form<60, 505, 564 (outs vsrc:$XT), (ins vsrc:$XB), 565 "xvnegdp $XT, $XB", IIC_VecFP, 566 [(set v2f64:$XT, (fneg v2f64:$XB))]>; 567 def XVNEGSP : XX2Form<60, 441, 568 (outs vsrc:$XT), (ins vsrc:$XB), 569 "xvnegsp $XT, $XB", IIC_VecFP, 570 [(set v4f32:$XT, (fneg v4f32:$XB))]>; 571 572 // Conversion Instructions 573 def XSCVDPSP : XX2Form<60, 265, 574 (outs vsfrc:$XT), (ins vsfrc:$XB), 575 "xscvdpsp $XT, $XB", IIC_VecFP, []>; 576 def XSCVDPSXDS : XX2Form<60, 344, 577 (outs vsfrc:$XT), (ins vsfrc:$XB), 578 "xscvdpsxds $XT, $XB", IIC_VecFP, 579 [(set f64:$XT, (PPCfctidz f64:$XB))]>; 580 let isCodeGenOnly = 1 in 581 def XSCVDPSXDSs : XX2Form<60, 344, 582 (outs vssrc:$XT), (ins vssrc:$XB), 583 "xscvdpsxds $XT, $XB", IIC_VecFP, 584 [(set f32:$XT, (PPCfctidz f32:$XB))]>; 585 def XSCVDPSXWS : XX2Form<60, 88, 586 (outs vsfrc:$XT), (ins vsfrc:$XB), 587 "xscvdpsxws $XT, $XB", IIC_VecFP, 588 [(set f64:$XT, (PPCfctiwz f64:$XB))]>; 589 let isCodeGenOnly = 1 in 590 def XSCVDPSXWSs : XX2Form<60, 88, 591 (outs vssrc:$XT), (ins vssrc:$XB), 592 "xscvdpsxws $XT, $XB", IIC_VecFP, 593 [(set f32:$XT, (PPCfctiwz f32:$XB))]>; 594 def XSCVDPUXDS : XX2Form<60, 328, 595 (outs vsfrc:$XT), (ins vsfrc:$XB), 596 "xscvdpuxds $XT, $XB", IIC_VecFP, 597 [(set f64:$XT, (PPCfctiduz f64:$XB))]>; 598 let isCodeGenOnly = 1 in 599 def XSCVDPUXDSs : XX2Form<60, 328, 600 (outs vssrc:$XT), (ins vssrc:$XB), 601 "xscvdpuxds $XT, $XB", IIC_VecFP, 602 [(set f32:$XT, (PPCfctiduz f32:$XB))]>; 603 def XSCVDPUXWS : XX2Form<60, 72, 604 (outs vsfrc:$XT), (ins vsfrc:$XB), 605 "xscvdpuxws $XT, $XB", IIC_VecFP, 606 [(set f64:$XT, (PPCfctiwuz f64:$XB))]>; 607 let isCodeGenOnly = 1 in 608 def XSCVDPUXWSs : XX2Form<60, 72, 609 (outs vssrc:$XT), (ins vssrc:$XB), 610 "xscvdpuxws $XT, $XB", IIC_VecFP, 611 [(set f32:$XT, (PPCfctiwuz f32:$XB))]>; 612 def XSCVSPDP : XX2Form<60, 329, 613 (outs vsfrc:$XT), (ins vsfrc:$XB), 614 "xscvspdp $XT, $XB", IIC_VecFP, []>; 615 def XSCVSXDDP : XX2Form<60, 376, 616 (outs vsfrc:$XT), (ins vsfrc:$XB), 617 "xscvsxddp $XT, $XB", IIC_VecFP, 618 [(set f64:$XT, (PPCfcfid f64:$XB))]>; 619 def XSCVUXDDP : XX2Form<60, 360, 620 (outs vsfrc:$XT), (ins vsfrc:$XB), 621 "xscvuxddp $XT, $XB", IIC_VecFP, 622 [(set f64:$XT, (PPCfcfidu f64:$XB))]>; 623 624 def XVCVDPSP : XX2Form<60, 393, 625 (outs vsrc:$XT), (ins vsrc:$XB), 626 "xvcvdpsp $XT, $XB", IIC_VecFP, 627 [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>; 628 def XVCVDPSXDS : XX2Form<60, 472, 629 (outs vsrc:$XT), (ins vsrc:$XB), 630 "xvcvdpsxds $XT, $XB", IIC_VecFP, 631 [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>; 632 def XVCVDPSXWS : XX2Form<60, 216, 633 (outs vsrc:$XT), (ins vsrc:$XB), 634 "xvcvdpsxws $XT, $XB", IIC_VecFP, 635 [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>; 636 def XVCVDPUXDS : XX2Form<60, 456, 637 (outs vsrc:$XT), (ins vsrc:$XB), 638 "xvcvdpuxds $XT, $XB", IIC_VecFP, 639 [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>; 640 def XVCVDPUXWS : XX2Form<60, 200, 641 (outs vsrc:$XT), (ins vsrc:$XB), 642 "xvcvdpuxws $XT, $XB", IIC_VecFP, 643 [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>; 644 645 def XVCVSPDP : XX2Form<60, 457, 646 (outs vsrc:$XT), (ins vsrc:$XB), 647 "xvcvspdp $XT, $XB", IIC_VecFP, 648 [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>; 649 def XVCVSPSXDS : XX2Form<60, 408, 650 (outs vsrc:$XT), (ins vsrc:$XB), 651 "xvcvspsxds $XT, $XB", IIC_VecFP, []>; 652 def XVCVSPSXWS : XX2Form<60, 152, 653 (outs vsrc:$XT), (ins vsrc:$XB), 654 "xvcvspsxws $XT, $XB", IIC_VecFP, 655 [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>; 656 def XVCVSPUXDS : XX2Form<60, 392, 657 (outs vsrc:$XT), (ins vsrc:$XB), 658 "xvcvspuxds $XT, $XB", IIC_VecFP, []>; 659 def XVCVSPUXWS : XX2Form<60, 136, 660 (outs vsrc:$XT), (ins vsrc:$XB), 661 "xvcvspuxws $XT, $XB", IIC_VecFP, 662 [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>; 663 def XVCVSXDDP : XX2Form<60, 504, 664 (outs vsrc:$XT), (ins vsrc:$XB), 665 "xvcvsxddp $XT, $XB", IIC_VecFP, 666 [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>; 667 def XVCVSXDSP : XX2Form<60, 440, 668 (outs vsrc:$XT), (ins vsrc:$XB), 669 "xvcvsxdsp $XT, $XB", IIC_VecFP, 670 [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>; 671 def XVCVSXWDP : XX2Form<60, 248, 672 (outs vsrc:$XT), (ins vsrc:$XB), 673 "xvcvsxwdp $XT, $XB", IIC_VecFP, 674 [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>; 675 def XVCVSXWSP : XX2Form<60, 184, 676 (outs vsrc:$XT), (ins vsrc:$XB), 677 "xvcvsxwsp $XT, $XB", IIC_VecFP, 678 [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>; 679 def XVCVUXDDP : XX2Form<60, 488, 680 (outs vsrc:$XT), (ins vsrc:$XB), 681 "xvcvuxddp $XT, $XB", IIC_VecFP, 682 [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>; 683 def XVCVUXDSP : XX2Form<60, 424, 684 (outs vsrc:$XT), (ins vsrc:$XB), 685 "xvcvuxdsp $XT, $XB", IIC_VecFP, 686 [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>; 687 def XVCVUXWDP : XX2Form<60, 232, 688 (outs vsrc:$XT), (ins vsrc:$XB), 689 "xvcvuxwdp $XT, $XB", IIC_VecFP, 690 [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>; 691 def XVCVUXWSP : XX2Form<60, 168, 692 (outs vsrc:$XT), (ins vsrc:$XB), 693 "xvcvuxwsp $XT, $XB", IIC_VecFP, 694 [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>; 695 696 // Rounding Instructions 697 def XSRDPI : XX2Form<60, 73, 698 (outs vsfrc:$XT), (ins vsfrc:$XB), 699 "xsrdpi $XT, $XB", IIC_VecFP, 700 [(set f64:$XT, (fround f64:$XB))]>; 701 def XSRDPIC : XX2Form<60, 107, 702 (outs vsfrc:$XT), (ins vsfrc:$XB), 703 "xsrdpic $XT, $XB", IIC_VecFP, 704 [(set f64:$XT, (fnearbyint f64:$XB))]>; 705 def XSRDPIM : XX2Form<60, 121, 706 (outs vsfrc:$XT), (ins vsfrc:$XB), 707 "xsrdpim $XT, $XB", IIC_VecFP, 708 [(set f64:$XT, (ffloor f64:$XB))]>; 709 def XSRDPIP : XX2Form<60, 105, 710 (outs vsfrc:$XT), (ins vsfrc:$XB), 711 "xsrdpip $XT, $XB", IIC_VecFP, 712 [(set f64:$XT, (fceil f64:$XB))]>; 713 def XSRDPIZ : XX2Form<60, 89, 714 (outs vsfrc:$XT), (ins vsfrc:$XB), 715 "xsrdpiz $XT, $XB", IIC_VecFP, 716 [(set f64:$XT, (ftrunc f64:$XB))]>; 717 718 def XVRDPI : XX2Form<60, 201, 719 (outs vsrc:$XT), (ins vsrc:$XB), 720 "xvrdpi $XT, $XB", IIC_VecFP, 721 [(set v2f64:$XT, (fround v2f64:$XB))]>; 722 def XVRDPIC : XX2Form<60, 235, 723 (outs vsrc:$XT), (ins vsrc:$XB), 724 "xvrdpic $XT, $XB", IIC_VecFP, 725 [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>; 726 def XVRDPIM : XX2Form<60, 249, 727 (outs vsrc:$XT), (ins vsrc:$XB), 728 "xvrdpim $XT, $XB", IIC_VecFP, 729 [(set v2f64:$XT, (ffloor v2f64:$XB))]>; 730 def XVRDPIP : XX2Form<60, 233, 731 (outs vsrc:$XT), (ins vsrc:$XB), 732 "xvrdpip $XT, $XB", IIC_VecFP, 733 [(set v2f64:$XT, (fceil v2f64:$XB))]>; 734 def XVRDPIZ : XX2Form<60, 217, 735 (outs vsrc:$XT), (ins vsrc:$XB), 736 "xvrdpiz $XT, $XB", IIC_VecFP, 737 [(set v2f64:$XT, (ftrunc v2f64:$XB))]>; 738 739 def XVRSPI : XX2Form<60, 137, 740 (outs vsrc:$XT), (ins vsrc:$XB), 741 "xvrspi $XT, $XB", IIC_VecFP, 742 [(set v4f32:$XT, (fround v4f32:$XB))]>; 743 def XVRSPIC : XX2Form<60, 171, 744 (outs vsrc:$XT), (ins vsrc:$XB), 745 "xvrspic $XT, $XB", IIC_VecFP, 746 [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>; 747 def XVRSPIM : XX2Form<60, 185, 748 (outs vsrc:$XT), (ins vsrc:$XB), 749 "xvrspim $XT, $XB", IIC_VecFP, 750 [(set v4f32:$XT, (ffloor v4f32:$XB))]>; 751 def XVRSPIP : XX2Form<60, 169, 752 (outs vsrc:$XT), (ins vsrc:$XB), 753 "xvrspip $XT, $XB", IIC_VecFP, 754 [(set v4f32:$XT, (fceil v4f32:$XB))]>; 755 def XVRSPIZ : XX2Form<60, 153, 756 (outs vsrc:$XT), (ins vsrc:$XB), 757 "xvrspiz $XT, $XB", IIC_VecFP, 758 [(set v4f32:$XT, (ftrunc v4f32:$XB))]>; 759 760 // Max/Min Instructions 761 let isCommutable = 1 in { 762 def XSMAXDP : XX3Form<60, 160, 763 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 764 "xsmaxdp $XT, $XA, $XB", IIC_VecFP, 765 [(set vsfrc:$XT, 766 (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; 767 def XSMINDP : XX3Form<60, 168, 768 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 769 "xsmindp $XT, $XA, $XB", IIC_VecFP, 770 [(set vsfrc:$XT, 771 (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; 772 773 def XVMAXDP : XX3Form<60, 224, 774 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 775 "xvmaxdp $XT, $XA, $XB", IIC_VecFP, 776 [(set vsrc:$XT, 777 (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; 778 def XVMINDP : XX3Form<60, 232, 779 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 780 "xvmindp $XT, $XA, $XB", IIC_VecFP, 781 [(set vsrc:$XT, 782 (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; 783 784 def XVMAXSP : XX3Form<60, 192, 785 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 786 "xvmaxsp $XT, $XA, $XB", IIC_VecFP, 787 [(set vsrc:$XT, 788 (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; 789 def XVMINSP : XX3Form<60, 200, 790 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 791 "xvminsp $XT, $XA, $XB", IIC_VecFP, 792 [(set vsrc:$XT, 793 (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; 794 } // isCommutable 795} // Uses = [RM] 796 797 // Logical Instructions 798 let isCommutable = 1 in 799 def XXLAND : XX3Form<60, 130, 800 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 801 "xxland $XT, $XA, $XB", IIC_VecGeneral, 802 [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>; 803 def XXLANDC : XX3Form<60, 138, 804 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 805 "xxlandc $XT, $XA, $XB", IIC_VecGeneral, 806 [(set v4i32:$XT, (and v4i32:$XA, 807 (vnot_ppc v4i32:$XB)))]>; 808 let isCommutable = 1 in { 809 def XXLNOR : XX3Form<60, 162, 810 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 811 "xxlnor $XT, $XA, $XB", IIC_VecGeneral, 812 [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA, 813 v4i32:$XB)))]>; 814 def XXLOR : XX3Form<60, 146, 815 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 816 "xxlor $XT, $XA, $XB", IIC_VecGeneral, 817 [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>; 818 let isCodeGenOnly = 1 in 819 def XXLORf: XX3Form<60, 146, 820 (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 821 "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>; 822 def XXLXOR : XX3Form<60, 154, 823 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 824 "xxlxor $XT, $XA, $XB", IIC_VecGeneral, 825 [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>; 826 } // isCommutable 827 let isCodeGenOnly = 1 in 828 def XXLXORz : XX3Form_Zero<60, 154, (outs vsrc:$XT), (ins), 829 "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 830 [(set v4i32:$XT, (v4i32 immAllZerosV))]>; 831 832 let isCodeGenOnly = 1 in { 833 def XXLXORdpz : XX3Form_SetZero<60, 154, 834 (outs vsfrc:$XT), (ins), 835 "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 836 [(set f64:$XT, (fpimm0))]>; 837 def XXLXORspz : XX3Form_SetZero<60, 154, 838 (outs vssrc:$XT), (ins), 839 "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 840 [(set f32:$XT, (fpimm0))]>; 841 } 842 843 // Permutation Instructions 844 def XXMRGHW : XX3Form<60, 18, 845 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 846 "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>; 847 def XXMRGLW : XX3Form<60, 50, 848 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 849 "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>; 850 851 def XXPERMDI : XX3Form_2<60, 10, 852 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM), 853 "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, 854 [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB, 855 imm32SExt16:$DM))]>; 856 let isCodeGenOnly = 1 in 857 def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM), 858 "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>; 859 def XXSEL : XX4Form<60, 3, 860 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC), 861 "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>; 862 863 def XXSLDWI : XX3Form_2<60, 2, 864 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW), 865 "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm, 866 [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB, 867 imm32SExt16:$SHW))]>; 868 def XXSPLTW : XX2Form_2<60, 164, 869 (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM), 870 "xxspltw $XT, $XB, $UIM", IIC_VecPerm, 871 [(set v4i32:$XT, 872 (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>; 873 let isCodeGenOnly = 1 in 874 def XXSPLTWs : XX2Form_2<60, 164, 875 (outs vsrc:$XT), (ins vfrc:$XB, u2imm:$UIM), 876 "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>; 877} // hasSideEffects 878} // UseVSXReg = 1 879 880// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 881// instruction selection into a branch sequence. 882let usesCustomInserter = 1, // Expanded after instruction selection. 883 PPC970_Single = 1 in { 884 885 def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst), 886 (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC), 887 "#SELECT_CC_VSRC", 888 []>; 889 def SELECT_VSRC: Pseudo<(outs vsrc:$dst), 890 (ins crbitrc:$cond, vsrc:$T, vsrc:$F), 891 "#SELECT_VSRC", 892 [(set v2f64:$dst, 893 (select i1:$cond, v2f64:$T, v2f64:$F))]>; 894 def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst), 895 (ins crrc:$cond, f8rc:$T, f8rc:$F, 896 i32imm:$BROPC), "#SELECT_CC_VSFRC", 897 []>; 898 def SELECT_VSFRC: Pseudo<(outs f8rc:$dst), 899 (ins crbitrc:$cond, f8rc:$T, f8rc:$F), 900 "#SELECT_VSFRC", 901 [(set f64:$dst, 902 (select i1:$cond, f64:$T, f64:$F))]>; 903 def SELECT_CC_VSSRC: Pseudo<(outs f4rc:$dst), 904 (ins crrc:$cond, f4rc:$T, f4rc:$F, 905 i32imm:$BROPC), "#SELECT_CC_VSSRC", 906 []>; 907 def SELECT_VSSRC: Pseudo<(outs f4rc:$dst), 908 (ins crbitrc:$cond, f4rc:$T, f4rc:$F), 909 "#SELECT_VSSRC", 910 [(set f32:$dst, 911 (select i1:$cond, f32:$T, f32:$F))]>; 912} // usesCustomInserter 913} // AddedComplexity 914 915def : InstAlias<"xvmovdp $XT, $XB", 916 (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 917def : InstAlias<"xvmovsp $XT, $XB", 918 (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 919 920def : InstAlias<"xxspltd $XT, $XB, 0", 921 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>; 922def : InstAlias<"xxspltd $XT, $XB, 1", 923 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>; 924def : InstAlias<"xxmrghd $XT, $XA, $XB", 925 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>; 926def : InstAlias<"xxmrgld $XT, $XA, $XB", 927 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>; 928def : InstAlias<"xxswapd $XT, $XB", 929 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>; 930def : InstAlias<"xxspltd $XT, $XB, 0", 931 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>; 932def : InstAlias<"xxspltd $XT, $XB, 1", 933 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>; 934def : InstAlias<"xxswapd $XT, $XB", 935 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>; 936 937let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 938 939def : Pat<(v4i32 (vnot_ppc v4i32:$A)), 940 (v4i32 (XXLNOR $A, $A))>; 941let Predicates = [IsBigEndian] in { 942def : Pat<(v2f64 (scalar_to_vector f64:$A)), 943 (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>; 944 945def : Pat<(f64 (extractelt v2f64:$S, 0)), 946 (f64 (EXTRACT_SUBREG $S, sub_64))>; 947def : Pat<(f64 (extractelt v2f64:$S, 1)), 948 (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 949} 950 951let Predicates = [IsLittleEndian] in { 952def : Pat<(v2f64 (scalar_to_vector f64:$A)), 953 (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64), 954 (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>; 955 956def : Pat<(f64 (extractelt v2f64:$S, 0)), 957 (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 958def : Pat<(f64 (extractelt v2f64:$S, 1)), 959 (f64 (EXTRACT_SUBREG $S, sub_64))>; 960} 961 962// Additional fnmsub patterns: -a*c + b == -(a*c - b) 963def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), 964 (XSNMSUBADP $B, $C, $A)>; 965def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B), 966 (XSNMSUBADP $B, $C, $A)>; 967 968def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B), 969 (XVNMSUBADP $B, $C, $A)>; 970def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B), 971 (XVNMSUBADP $B, $C, $A)>; 972 973def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B), 974 (XVNMSUBASP $B, $C, $A)>; 975def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B), 976 (XVNMSUBASP $B, $C, $A)>; 977 978def : Pat<(v2f64 (bitconvert v4f32:$A)), 979 (COPY_TO_REGCLASS $A, VSRC)>; 980def : Pat<(v2f64 (bitconvert v4i32:$A)), 981 (COPY_TO_REGCLASS $A, VSRC)>; 982def : Pat<(v2f64 (bitconvert v8i16:$A)), 983 (COPY_TO_REGCLASS $A, VSRC)>; 984def : Pat<(v2f64 (bitconvert v16i8:$A)), 985 (COPY_TO_REGCLASS $A, VSRC)>; 986 987def : Pat<(v4f32 (bitconvert v2f64:$A)), 988 (COPY_TO_REGCLASS $A, VRRC)>; 989def : Pat<(v4i32 (bitconvert v2f64:$A)), 990 (COPY_TO_REGCLASS $A, VRRC)>; 991def : Pat<(v8i16 (bitconvert v2f64:$A)), 992 (COPY_TO_REGCLASS $A, VRRC)>; 993def : Pat<(v16i8 (bitconvert v2f64:$A)), 994 (COPY_TO_REGCLASS $A, VRRC)>; 995 996def : Pat<(v2i64 (bitconvert v4f32:$A)), 997 (COPY_TO_REGCLASS $A, VSRC)>; 998def : Pat<(v2i64 (bitconvert v4i32:$A)), 999 (COPY_TO_REGCLASS $A, VSRC)>; 1000def : Pat<(v2i64 (bitconvert v8i16:$A)), 1001 (COPY_TO_REGCLASS $A, VSRC)>; 1002def : Pat<(v2i64 (bitconvert v16i8:$A)), 1003 (COPY_TO_REGCLASS $A, VSRC)>; 1004 1005def : Pat<(v4f32 (bitconvert v2i64:$A)), 1006 (COPY_TO_REGCLASS $A, VRRC)>; 1007def : Pat<(v4i32 (bitconvert v2i64:$A)), 1008 (COPY_TO_REGCLASS $A, VRRC)>; 1009def : Pat<(v8i16 (bitconvert v2i64:$A)), 1010 (COPY_TO_REGCLASS $A, VRRC)>; 1011def : Pat<(v16i8 (bitconvert v2i64:$A)), 1012 (COPY_TO_REGCLASS $A, VRRC)>; 1013 1014def : Pat<(v2f64 (bitconvert v2i64:$A)), 1015 (COPY_TO_REGCLASS $A, VRRC)>; 1016def : Pat<(v2i64 (bitconvert v2f64:$A)), 1017 (COPY_TO_REGCLASS $A, VRRC)>; 1018 1019def : Pat<(v2f64 (bitconvert v1i128:$A)), 1020 (COPY_TO_REGCLASS $A, VRRC)>; 1021def : Pat<(v1i128 (bitconvert v2f64:$A)), 1022 (COPY_TO_REGCLASS $A, VRRC)>; 1023 1024// sign extension patterns 1025// To extend "in place" from v2i32 to v2i64, we have input data like: 1026// | undef | i32 | undef | i32 | 1027// but xvcvsxwdp expects the input in big-Endian format: 1028// | i32 | undef | i32 | undef | 1029// so we need to shift everything to the left by one i32 (word) before 1030// the conversion. 1031def : Pat<(sext_inreg v2i64:$C, v2i32), 1032 (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>; 1033def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))), 1034 (XVCVSXWDP (XXSLDWI $C, $C, 1))>; 1035 1036def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)), 1037 (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>; 1038def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)), 1039 (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>; 1040 1041def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)), 1042 (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>; 1043def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)), 1044 (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>; 1045 1046// Loads. 1047let Predicates = [HasVSX, HasOnlySwappingMemOps] in { 1048 def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1049 1050 // Stores. 1051 def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), 1052 (STXVD2X $rS, xoaddr:$dst)>; 1053 def : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst), 1054 (STXVD2X $rS, xoaddr:$dst)>; 1055 def : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst), 1056 (STXVW4X $rS, xoaddr:$dst)>; 1057 def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1058} 1059let Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in { 1060 def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1061 def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1062 def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>; 1063 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>; 1064 def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1065 def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1066 def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>; 1067 def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), 1068 (STXVW4X $rS, xoaddr:$dst)>; 1069} 1070 1071// Permutes. 1072def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>; 1073def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>; 1074def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>; 1075def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>; 1076def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>; 1077 1078// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and 1079// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable. 1080def : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>; 1081 1082// Selects. 1083def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)), 1084 (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1085def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)), 1086 (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1087def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)), 1088 (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1089def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)), 1090 (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1091def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)), 1092 (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>; 1093def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)), 1094 (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1095def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)), 1096 (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1097def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)), 1098 (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1099def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)), 1100 (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1101def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)), 1102 (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1103 1104def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)), 1105 (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1106def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)), 1107 (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1108def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)), 1109 (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 1110def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)), 1111 (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 1112def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)), 1113 (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>; 1114def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)), 1115 (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 1116def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)), 1117 (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 1118def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)), 1119 (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1120def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)), 1121 (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1122def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)), 1123 (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1124 1125// Divides. 1126def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B), 1127 (XVDIVSP $A, $B)>; 1128def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B), 1129 (XVDIVDP $A, $B)>; 1130 1131// Reciprocal estimate 1132def : Pat<(int_ppc_vsx_xvresp v4f32:$A), 1133 (XVRESP $A)>; 1134def : Pat<(int_ppc_vsx_xvredp v2f64:$A), 1135 (XVREDP $A)>; 1136 1137// Recip. square root estimate 1138def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A), 1139 (XVRSQRTESP $A)>; 1140def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A), 1141 (XVRSQRTEDP $A)>; 1142 1143let Predicates = [IsLittleEndian] in { 1144def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1145 (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1146def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1147 (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1148def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1149 (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1150def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1151 (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1152} // IsLittleEndian 1153 1154let Predicates = [IsBigEndian] in { 1155def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1156 (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 1157def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1158 (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1159def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1160 (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 1161def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1162 (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1163} // IsBigEndian 1164 1165} // AddedComplexity 1166} // HasVSX 1167 1168def ScalarLoads { 1169 dag Li8 = (i32 (extloadi8 xoaddr:$src)); 1170 dag ZELi8 = (i32 (zextloadi8 xoaddr:$src)); 1171 dag ZELi8i64 = (i64 (zextloadi8 xoaddr:$src)); 1172 dag SELi8 = (i32 (sext_inreg (extloadi8 xoaddr:$src), i8)); 1173 dag SELi8i64 = (i64 (sext_inreg (extloadi8 xoaddr:$src), i8)); 1174 1175 dag Li16 = (i32 (extloadi16 xoaddr:$src)); 1176 dag ZELi16 = (i32 (zextloadi16 xoaddr:$src)); 1177 dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src)); 1178 dag SELi16 = (i32 (sextloadi16 xoaddr:$src)); 1179 dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src)); 1180 1181 dag Li32 = (i32 (load xoaddr:$src)); 1182} 1183 1184// The following VSX instructions were introduced in Power ISA 2.07 1185/* FIXME: if the operands are v2i64, these patterns will not match. 1186 we should define new patterns or otherwise match the same patterns 1187 when the elements are larger than i32. 1188*/ 1189def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">; 1190def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">; 1191let Predicates = [HasP8Vector] in { 1192let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 1193 let isCommutable = 1, UseVSXReg = 1 in { 1194 def XXLEQV : XX3Form<60, 186, 1195 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1196 "xxleqv $XT, $XA, $XB", IIC_VecGeneral, 1197 [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>; 1198 def XXLNAND : XX3Form<60, 178, 1199 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1200 "xxlnand $XT, $XA, $XB", IIC_VecGeneral, 1201 [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA, 1202 v4i32:$XB)))]>; 1203 } // isCommutable, UseVSXReg 1204 1205 def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B), 1206 (XXLEQV $A, $B)>; 1207 1208 let UseVSXReg = 1 in { 1209 def XXLORC : XX3Form<60, 170, 1210 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1211 "xxlorc $XT, $XA, $XB", IIC_VecGeneral, 1212 [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>; 1213 1214 // VSX scalar loads introduced in ISA 2.07 1215 let mayLoad = 1, mayStore = 0 in { 1216 let CodeSize = 3 in 1217 def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src), 1218 "lxsspx $XT, $src", IIC_LdStLFD, 1219 [(set f32:$XT, (load xoaddr:$src))]>; 1220 def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src), 1221 "lxsiwax $XT, $src", IIC_LdStLFD, 1222 [(set f64:$XT, (PPClfiwax xoaddr:$src))]>; 1223 def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src), 1224 "lxsiwzx $XT, $src", IIC_LdStLFD, 1225 [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>; 1226 } // mayLoad 1227 1228 // VSX scalar stores introduced in ISA 2.07 1229 let mayStore = 1, mayLoad = 0 in { 1230 let CodeSize = 3 in 1231 def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst), 1232 "stxsspx $XT, $dst", IIC_LdStSTFD, 1233 [(store f32:$XT, xoaddr:$dst)]>; 1234 def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst), 1235 "stxsiwx $XT, $dst", IIC_LdStSTFD, 1236 [(PPCstfiwx f64:$XT, xoaddr:$dst)]>; 1237 } // mayStore 1238 } // UseVSXReg = 1 1239 1240 def : Pat<(f64 (extloadf32 xoaddr:$src)), 1241 (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>; 1242 def : Pat<(f32 (fpround (extloadf32 xoaddr:$src))), 1243 (f32 (LXSSPX xoaddr:$src))>; 1244 def : Pat<(f64 (fpextend f32:$src)), 1245 (COPY_TO_REGCLASS $src, VSFRC)>; 1246 1247 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)), 1248 (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1249 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)), 1250 (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1251 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)), 1252 (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1253 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)), 1254 (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1255 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)), 1256 (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>; 1257 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)), 1258 (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1259 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)), 1260 (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1261 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)), 1262 (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1263 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)), 1264 (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1265 def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)), 1266 (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1267 1268 let UseVSXReg = 1 in { 1269 // VSX Elementary Scalar FP arithmetic (SP) 1270 let isCommutable = 1 in { 1271 def XSADDSP : XX3Form<60, 0, 1272 (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1273 "xsaddsp $XT, $XA, $XB", IIC_VecFP, 1274 [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>; 1275 def XSMULSP : XX3Form<60, 16, 1276 (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1277 "xsmulsp $XT, $XA, $XB", IIC_VecFP, 1278 [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>; 1279 } // isCommutable 1280 1281 def XSDIVSP : XX3Form<60, 24, 1282 (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1283 "xsdivsp $XT, $XA, $XB", IIC_FPDivS, 1284 [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>; 1285 def XSRESP : XX2Form<60, 26, 1286 (outs vssrc:$XT), (ins vssrc:$XB), 1287 "xsresp $XT, $XB", IIC_VecFP, 1288 [(set f32:$XT, (PPCfre f32:$XB))]>; 1289 def XSSQRTSP : XX2Form<60, 11, 1290 (outs vssrc:$XT), (ins vssrc:$XB), 1291 "xssqrtsp $XT, $XB", IIC_FPSqrtS, 1292 [(set f32:$XT, (fsqrt f32:$XB))]>; 1293 def XSRSQRTESP : XX2Form<60, 10, 1294 (outs vssrc:$XT), (ins vssrc:$XB), 1295 "xsrsqrtesp $XT, $XB", IIC_VecFP, 1296 [(set f32:$XT, (PPCfrsqrte f32:$XB))]>; 1297 def XSSUBSP : XX3Form<60, 8, 1298 (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1299 "xssubsp $XT, $XA, $XB", IIC_VecFP, 1300 [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>; 1301 1302 // FMA Instructions 1303 let BaseName = "XSMADDASP" in { 1304 let isCommutable = 1 in 1305 def XSMADDASP : XX3Form<60, 1, 1306 (outs vssrc:$XT), 1307 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1308 "xsmaddasp $XT, $XA, $XB", IIC_VecFP, 1309 [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>, 1310 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1311 AltVSXFMARel; 1312 let IsVSXFMAAlt = 1 in 1313 def XSMADDMSP : XX3Form<60, 9, 1314 (outs vssrc:$XT), 1315 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1316 "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 1317 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1318 AltVSXFMARel; 1319 } 1320 1321 let BaseName = "XSMSUBASP" in { 1322 let isCommutable = 1 in 1323 def XSMSUBASP : XX3Form<60, 17, 1324 (outs vssrc:$XT), 1325 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1326 "xsmsubasp $XT, $XA, $XB", IIC_VecFP, 1327 [(set f32:$XT, (fma f32:$XA, f32:$XB, 1328 (fneg f32:$XTi)))]>, 1329 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1330 AltVSXFMARel; 1331 let IsVSXFMAAlt = 1 in 1332 def XSMSUBMSP : XX3Form<60, 25, 1333 (outs vssrc:$XT), 1334 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1335 "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 1336 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1337 AltVSXFMARel; 1338 } 1339 1340 let BaseName = "XSNMADDASP" in { 1341 let isCommutable = 1 in 1342 def XSNMADDASP : XX3Form<60, 129, 1343 (outs vssrc:$XT), 1344 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1345 "xsnmaddasp $XT, $XA, $XB", IIC_VecFP, 1346 [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB, 1347 f32:$XTi)))]>, 1348 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1349 AltVSXFMARel; 1350 let IsVSXFMAAlt = 1 in 1351 def XSNMADDMSP : XX3Form<60, 137, 1352 (outs vssrc:$XT), 1353 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1354 "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 1355 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1356 AltVSXFMARel; 1357 } 1358 1359 let BaseName = "XSNMSUBASP" in { 1360 let isCommutable = 1 in 1361 def XSNMSUBASP : XX3Form<60, 145, 1362 (outs vssrc:$XT), 1363 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1364 "xsnmsubasp $XT, $XA, $XB", IIC_VecFP, 1365 [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB, 1366 (fneg f32:$XTi))))]>, 1367 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1368 AltVSXFMARel; 1369 let IsVSXFMAAlt = 1 in 1370 def XSNMSUBMSP : XX3Form<60, 153, 1371 (outs vssrc:$XT), 1372 (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1373 "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 1374 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1375 AltVSXFMARel; 1376 } 1377 1378 // Single Precision Conversions (FP <-> INT) 1379 def XSCVSXDSP : XX2Form<60, 312, 1380 (outs vssrc:$XT), (ins vsfrc:$XB), 1381 "xscvsxdsp $XT, $XB", IIC_VecFP, 1382 [(set f32:$XT, (PPCfcfids f64:$XB))]>; 1383 def XSCVUXDSP : XX2Form<60, 296, 1384 (outs vssrc:$XT), (ins vsfrc:$XB), 1385 "xscvuxdsp $XT, $XB", IIC_VecFP, 1386 [(set f32:$XT, (PPCfcfidus f64:$XB))]>; 1387 1388 // Conversions between vector and scalar single precision 1389 def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB), 1390 "xscvdpspn $XT, $XB", IIC_VecFP, []>; 1391 def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB), 1392 "xscvspdpn $XT, $XB", IIC_VecFP, []>; 1393 } // UseVSXReg = 1 1394 1395 let Predicates = [IsLittleEndian] in { 1396 def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1397 (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1398 def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1399 (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1400 def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1401 (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1402 def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1403 (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1404 } 1405 1406 let Predicates = [IsBigEndian] in { 1407 def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1408 (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>; 1409 def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1410 (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1411 def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1412 (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>; 1413 def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1414 (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1415 } 1416 def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)), 1417 (v4i32 (XXSPLTWs (LXSIWAX xoaddr:$src), 1))>; 1418} // AddedComplexity = 400 1419} // HasP8Vector 1420 1421let UseVSXReg = 1, AddedComplexity = 400 in { 1422let Predicates = [HasDirectMove] in { 1423 // VSX direct move instructions 1424 def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT), 1425 "mfvsrd $rA, $XT", IIC_VecGeneral, 1426 [(set i64:$rA, (PPCmfvsr f64:$XT))]>, 1427 Requires<[In64BitMode]>; 1428 let isCodeGenOnly = 1 in 1429 def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT), 1430 "mfvsrd $rA, $XT", IIC_VecGeneral, 1431 []>, 1432 Requires<[In64BitMode]>; 1433 def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT), 1434 "mfvsrwz $rA, $XT", IIC_VecGeneral, 1435 [(set i32:$rA, (PPCmfvsr f64:$XT))]>; 1436 def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA), 1437 "mtvsrd $XT, $rA", IIC_VecGeneral, 1438 [(set f64:$XT, (PPCmtvsra i64:$rA))]>, 1439 Requires<[In64BitMode]>; 1440 def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA), 1441 "mtvsrwa $XT, $rA", IIC_VecGeneral, 1442 [(set f64:$XT, (PPCmtvsra i32:$rA))]>; 1443 def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA), 1444 "mtvsrwz $XT, $rA", IIC_VecGeneral, 1445 [(set f64:$XT, (PPCmtvsrz i32:$rA))]>; 1446} // HasDirectMove 1447 1448let Predicates = [IsISA3_0, HasDirectMove] in { 1449 def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA), 1450 "mtvsrws $XT, $rA", IIC_VecGeneral, []>; 1451 1452 def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB), 1453 "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral, 1454 []>, Requires<[In64BitMode]>; 1455 1456 def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT), 1457 "mfvsrld $rA, $XT", IIC_VecGeneral, 1458 []>, Requires<[In64BitMode]>; 1459 1460} // IsISA3_0, HasDirectMove 1461} // UseVSXReg = 1 1462 1463// We want to parse this from asm, but we don't want to emit this as it would 1464// be emitted with a VSX reg. So leave Emit = 0 here. 1465def : InstAlias<"mfvrd $rA, $XT", 1466 (MFVRD g8rc:$rA, vrrc:$XT), 0>; 1467def : InstAlias<"mffprd $rA, $src", 1468 (MFVSRD g8rc:$rA, f8rc:$src)>; 1469 1470/* Direct moves of various widths from GPR's into VSR's. Each move lines 1471 the value up into element 0 (both BE and LE). Namely, entities smaller than 1472 a doubleword are shifted left and moved for BE. For LE, they're moved, then 1473 swapped to go into the least significant element of the VSR. 1474*/ 1475def MovesToVSR { 1476 dag BE_BYTE_0 = 1477 (MTVSRD 1478 (RLDICR 1479 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7)); 1480 dag BE_HALF_0 = 1481 (MTVSRD 1482 (RLDICR 1483 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15)); 1484 dag BE_WORD_0 = 1485 (MTVSRD 1486 (RLDICR 1487 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31)); 1488 dag BE_DWORD_0 = (MTVSRD $A); 1489 1490 dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32)); 1491 dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 1492 LE_MTVSRW, sub_64)); 1493 dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2); 1494 dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 1495 BE_DWORD_0, sub_64)); 1496 dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2); 1497} 1498 1499/* Patterns for extracting elements out of vectors. Integer elements are 1500 extracted using direct move operations. Patterns for extracting elements 1501 whose indices are not available at compile time are also provided with 1502 various _VARIABLE_ patterns. 1503 The numbering for the DAG's is for LE, but when used on BE, the correct 1504 LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13). 1505*/ 1506def VectorExtractions { 1507 // Doubleword extraction 1508 dag LE_DWORD_0 = 1509 (MFVSRD 1510 (EXTRACT_SUBREG 1511 (XXPERMDI (COPY_TO_REGCLASS $S, VSRC), 1512 (COPY_TO_REGCLASS $S, VSRC), 2), sub_64)); 1513 dag LE_DWORD_1 = (MFVSRD 1514 (EXTRACT_SUBREG 1515 (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 1516 1517 // Word extraction 1518 dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64)); 1519 dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64)); 1520 dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG 1521 (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 1522 dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64)); 1523 1524 // Halfword extraction 1525 dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32)); 1526 dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32)); 1527 dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32)); 1528 dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32)); 1529 dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32)); 1530 dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32)); 1531 dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32)); 1532 dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32)); 1533 1534 // Byte extraction 1535 dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32)); 1536 dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32)); 1537 dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32)); 1538 dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32)); 1539 dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32)); 1540 dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32)); 1541 dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32)); 1542 dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32)); 1543 dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32)); 1544 dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32)); 1545 dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32)); 1546 dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32)); 1547 dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32)); 1548 dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32)); 1549 dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32)); 1550 dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32)); 1551 1552 /* Variable element number (BE and LE patterns must be specified separately) 1553 This is a rather involved process. 1554 1555 Conceptually, this is how the move is accomplished: 1556 1. Identify which doubleword contains the element 1557 2. Shift in the VMX register so that the correct doubleword is correctly 1558 lined up for the MFVSRD 1559 3. Perform the move so that the element (along with some extra stuff) 1560 is in the GPR 1561 4. Right shift within the GPR so that the element is right-justified 1562 1563 Of course, the index is an element number which has a different meaning 1564 on LE/BE so the patterns have to be specified separately. 1565 1566 Note: The final result will be the element right-justified with high 1567 order bits being arbitrarily defined (namely, whatever was in the 1568 vector register to the left of the value originally). 1569 */ 1570 1571 /* LE variable byte 1572 Number 1. above: 1573 - For elements 0-7, we shift left by 8 bytes since they're on the right 1574 - For elements 8-15, we need not shift (shift left by zero bytes) 1575 This is accomplished by inverting the bits of the index and AND-ing 1576 with 0x8 (i.e. clearing all bits of the index and inverting bit 60). 1577 */ 1578 dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)); 1579 1580 // Number 2. above: 1581 // - Now that we set up the shift amount, we shift in the VMX register 1582 dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC); 1583 1584 // Number 3. above: 1585 // - The doubleword containing our element is moved to a GPR 1586 dag LE_MV_VBYTE = (MFVSRD 1587 (EXTRACT_SUBREG 1588 (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)), 1589 sub_64)); 1590 1591 /* Number 4. above: 1592 - Truncate the element number to the range 0-7 (8-15 are symmetrical 1593 and out of range values are truncated accordingly) 1594 - Multiply by 8 as we need to shift right by the number of bits, not bytes 1595 - Shift right in the GPR by the calculated value 1596 */ 1597 dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60), 1598 sub_32); 1599 dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT), 1600 sub_32); 1601 1602 /* LE variable halfword 1603 Number 1. above: 1604 - For elements 0-3, we shift left by 8 since they're on the right 1605 - For elements 4-7, we need not shift (shift left by zero bytes) 1606 Similarly to the byte pattern, we invert the bits of the index, but we 1607 AND with 0x4 (i.e. clear all bits of the index and invert bit 61). 1608 Of course, the shift is still by 8 bytes, so we must multiply by 2. 1609 */ 1610 dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)); 1611 1612 // Number 2. above: 1613 // - Now that we set up the shift amount, we shift in the VMX register 1614 dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC); 1615 1616 // Number 3. above: 1617 // - The doubleword containing our element is moved to a GPR 1618 dag LE_MV_VHALF = (MFVSRD 1619 (EXTRACT_SUBREG 1620 (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)), 1621 sub_64)); 1622 1623 /* Number 4. above: 1624 - Truncate the element number to the range 0-3 (4-7 are symmetrical 1625 and out of range values are truncated accordingly) 1626 - Multiply by 16 as we need to shift right by the number of bits 1627 - Shift right in the GPR by the calculated value 1628 */ 1629 dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59), 1630 sub_32); 1631 dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT), 1632 sub_32); 1633 1634 /* LE variable word 1635 Number 1. above: 1636 - For elements 0-1, we shift left by 8 since they're on the right 1637 - For elements 2-3, we need not shift 1638 */ 1639 dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)); 1640 1641 // Number 2. above: 1642 // - Now that we set up the shift amount, we shift in the VMX register 1643 dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC); 1644 1645 // Number 3. above: 1646 // - The doubleword containing our element is moved to a GPR 1647 dag LE_MV_VWORD = (MFVSRD 1648 (EXTRACT_SUBREG 1649 (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)), 1650 sub_64)); 1651 1652 /* Number 4. above: 1653 - Truncate the element number to the range 0-1 (2-3 are symmetrical 1654 and out of range values are truncated accordingly) 1655 - Multiply by 32 as we need to shift right by the number of bits 1656 - Shift right in the GPR by the calculated value 1657 */ 1658 dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58), 1659 sub_32); 1660 dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT), 1661 sub_32); 1662 1663 /* LE variable doubleword 1664 Number 1. above: 1665 - For element 0, we shift left by 8 since it's on the right 1666 - For element 1, we need not shift 1667 */ 1668 dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)); 1669 1670 // Number 2. above: 1671 // - Now that we set up the shift amount, we shift in the VMX register 1672 dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC); 1673 1674 // Number 3. above: 1675 // - The doubleword containing our element is moved to a GPR 1676 // - Number 4. is not needed for the doubleword as the value is 64-bits 1677 dag LE_VARIABLE_DWORD = 1678 (MFVSRD (EXTRACT_SUBREG 1679 (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)), 1680 sub_64)); 1681 1682 /* LE variable float 1683 - Shift the vector to line up the desired element to BE Word 0 1684 - Convert 32-bit float to a 64-bit single precision float 1685 */ 1686 dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)); 1687 dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC); 1688 dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE); 1689 1690 /* LE variable double 1691 Same as the LE doubleword except there is no move. 1692 */ 1693 dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC), 1694 (COPY_TO_REGCLASS $S, VRRC), 1695 LE_VDWORD_PERM_VEC); 1696 dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC); 1697 1698 /* BE variable byte 1699 The algorithm here is the same as the LE variable byte except: 1700 - The shift in the VMX register is by 0/8 for opposite element numbers so 1701 we simply AND the element number with 0x8 1702 - The order of elements after the move to GPR is reversed, so we invert 1703 the bits of the index prior to truncating to the range 0-7 1704 */ 1705 dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8)); 1706 dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC); 1707 dag BE_MV_VBYTE = (MFVSRD 1708 (EXTRACT_SUBREG 1709 (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)), 1710 sub_64)); 1711 dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60), 1712 sub_32); 1713 dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT), 1714 sub_32); 1715 1716 /* BE variable halfword 1717 The algorithm here is the same as the LE variable halfword except: 1718 - The shift in the VMX register is by 0/8 for opposite element numbers so 1719 we simply AND the element number with 0x4 and multiply by 2 1720 - The order of elements after the move to GPR is reversed, so we invert 1721 the bits of the index prior to truncating to the range 0-3 1722 */ 1723 dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62)); 1724 dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC); 1725 dag BE_MV_VHALF = (MFVSRD 1726 (EXTRACT_SUBREG 1727 (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)), 1728 sub_64)); 1729 dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59), 1730 sub_32); 1731 dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT), 1732 sub_32); 1733 1734 /* BE variable word 1735 The algorithm is the same as the LE variable word except: 1736 - The shift in the VMX register happens for opposite element numbers 1737 - The order of elements after the move to GPR is reversed, so we invert 1738 the bits of the index prior to truncating to the range 0-1 1739 */ 1740 dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61)); 1741 dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC); 1742 dag BE_MV_VWORD = (MFVSRD 1743 (EXTRACT_SUBREG 1744 (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)), 1745 sub_64)); 1746 dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58), 1747 sub_32); 1748 dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT), 1749 sub_32); 1750 1751 /* BE variable doubleword 1752 Same as the LE doubleword except we shift in the VMX register for opposite 1753 element indices. 1754 */ 1755 dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60)); 1756 dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC); 1757 dag BE_VARIABLE_DWORD = 1758 (MFVSRD (EXTRACT_SUBREG 1759 (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)), 1760 sub_64)); 1761 1762 /* BE variable float 1763 - Shift the vector to line up the desired element to BE Word 0 1764 - Convert 32-bit float to a 64-bit single precision float 1765 */ 1766 dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61)); 1767 dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC); 1768 dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE); 1769 1770 /* BE variable double 1771 Same as the BE doubleword except there is no move. 1772 */ 1773 dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC), 1774 (COPY_TO_REGCLASS $S, VRRC), 1775 BE_VDWORD_PERM_VEC); 1776 dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC); 1777} 1778 1779let AddedComplexity = 400 in { 1780// v4f32 scalar <-> vector conversions (BE) 1781let Predicates = [IsBigEndian, HasP8Vector] in { 1782 def : Pat<(v4f32 (scalar_to_vector f32:$A)), 1783 (v4f32 (XSCVDPSPN $A))>; 1784 def : Pat<(f32 (vector_extract v4f32:$S, 0)), 1785 (f32 (XSCVSPDPN $S))>; 1786 def : Pat<(f32 (vector_extract v4f32:$S, 1)), 1787 (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 1788 def : Pat<(f32 (vector_extract v4f32:$S, 2)), 1789 (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 1790 def : Pat<(f32 (vector_extract v4f32:$S, 3)), 1791 (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 1792 def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 1793 (f32 VectorExtractions.BE_VARIABLE_FLOAT)>; 1794} // IsBigEndian, HasP8Vector 1795 1796// Variable index vector_extract for v2f64 does not require P8Vector 1797let Predicates = [IsBigEndian, HasVSX] in 1798 def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 1799 (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>; 1800 1801let Predicates = [IsBigEndian, HasDirectMove] in { 1802 // v16i8 scalar <-> vector conversions (BE) 1803 def : Pat<(v16i8 (scalar_to_vector i32:$A)), 1804 (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>; 1805 def : Pat<(v8i16 (scalar_to_vector i32:$A)), 1806 (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>; 1807 def : Pat<(v4i32 (scalar_to_vector i32:$A)), 1808 (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>; 1809 def : Pat<(v2i64 (scalar_to_vector i64:$A)), 1810 (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>; 1811 def : Pat<(i32 (vector_extract v16i8:$S, 0)), 1812 (i32 VectorExtractions.LE_BYTE_15)>; 1813 def : Pat<(i32 (vector_extract v16i8:$S, 1)), 1814 (i32 VectorExtractions.LE_BYTE_14)>; 1815 def : Pat<(i32 (vector_extract v16i8:$S, 2)), 1816 (i32 VectorExtractions.LE_BYTE_13)>; 1817 def : Pat<(i32 (vector_extract v16i8:$S, 3)), 1818 (i32 VectorExtractions.LE_BYTE_12)>; 1819 def : Pat<(i32 (vector_extract v16i8:$S, 4)), 1820 (i32 VectorExtractions.LE_BYTE_11)>; 1821 def : Pat<(i32 (vector_extract v16i8:$S, 5)), 1822 (i32 VectorExtractions.LE_BYTE_10)>; 1823 def : Pat<(i32 (vector_extract v16i8:$S, 6)), 1824 (i32 VectorExtractions.LE_BYTE_9)>; 1825 def : Pat<(i32 (vector_extract v16i8:$S, 7)), 1826 (i32 VectorExtractions.LE_BYTE_8)>; 1827 def : Pat<(i32 (vector_extract v16i8:$S, 8)), 1828 (i32 VectorExtractions.LE_BYTE_7)>; 1829 def : Pat<(i32 (vector_extract v16i8:$S, 9)), 1830 (i32 VectorExtractions.LE_BYTE_6)>; 1831 def : Pat<(i32 (vector_extract v16i8:$S, 10)), 1832 (i32 VectorExtractions.LE_BYTE_5)>; 1833 def : Pat<(i32 (vector_extract v16i8:$S, 11)), 1834 (i32 VectorExtractions.LE_BYTE_4)>; 1835 def : Pat<(i32 (vector_extract v16i8:$S, 12)), 1836 (i32 VectorExtractions.LE_BYTE_3)>; 1837 def : Pat<(i32 (vector_extract v16i8:$S, 13)), 1838 (i32 VectorExtractions.LE_BYTE_2)>; 1839 def : Pat<(i32 (vector_extract v16i8:$S, 14)), 1840 (i32 VectorExtractions.LE_BYTE_1)>; 1841 def : Pat<(i32 (vector_extract v16i8:$S, 15)), 1842 (i32 VectorExtractions.LE_BYTE_0)>; 1843 def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 1844 (i32 VectorExtractions.BE_VARIABLE_BYTE)>; 1845 1846 // v8i16 scalar <-> vector conversions (BE) 1847 def : Pat<(i32 (vector_extract v8i16:$S, 0)), 1848 (i32 VectorExtractions.LE_HALF_7)>; 1849 def : Pat<(i32 (vector_extract v8i16:$S, 1)), 1850 (i32 VectorExtractions.LE_HALF_6)>; 1851 def : Pat<(i32 (vector_extract v8i16:$S, 2)), 1852 (i32 VectorExtractions.LE_HALF_5)>; 1853 def : Pat<(i32 (vector_extract v8i16:$S, 3)), 1854 (i32 VectorExtractions.LE_HALF_4)>; 1855 def : Pat<(i32 (vector_extract v8i16:$S, 4)), 1856 (i32 VectorExtractions.LE_HALF_3)>; 1857 def : Pat<(i32 (vector_extract v8i16:$S, 5)), 1858 (i32 VectorExtractions.LE_HALF_2)>; 1859 def : Pat<(i32 (vector_extract v8i16:$S, 6)), 1860 (i32 VectorExtractions.LE_HALF_1)>; 1861 def : Pat<(i32 (vector_extract v8i16:$S, 7)), 1862 (i32 VectorExtractions.LE_HALF_0)>; 1863 def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 1864 (i32 VectorExtractions.BE_VARIABLE_HALF)>; 1865 1866 // v4i32 scalar <-> vector conversions (BE) 1867 def : Pat<(i32 (vector_extract v4i32:$S, 0)), 1868 (i32 VectorExtractions.LE_WORD_3)>; 1869 def : Pat<(i32 (vector_extract v4i32:$S, 1)), 1870 (i32 VectorExtractions.LE_WORD_2)>; 1871 def : Pat<(i32 (vector_extract v4i32:$S, 2)), 1872 (i32 VectorExtractions.LE_WORD_1)>; 1873 def : Pat<(i32 (vector_extract v4i32:$S, 3)), 1874 (i32 VectorExtractions.LE_WORD_0)>; 1875 def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 1876 (i32 VectorExtractions.BE_VARIABLE_WORD)>; 1877 1878 // v2i64 scalar <-> vector conversions (BE) 1879 def : Pat<(i64 (vector_extract v2i64:$S, 0)), 1880 (i64 VectorExtractions.LE_DWORD_1)>; 1881 def : Pat<(i64 (vector_extract v2i64:$S, 1)), 1882 (i64 VectorExtractions.LE_DWORD_0)>; 1883 def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 1884 (i64 VectorExtractions.BE_VARIABLE_DWORD)>; 1885} // IsBigEndian, HasDirectMove 1886 1887// v4f32 scalar <-> vector conversions (LE) 1888let Predicates = [IsLittleEndian, HasP8Vector] in { 1889 def : Pat<(v4f32 (scalar_to_vector f32:$A)), 1890 (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>; 1891 def : Pat<(f32 (vector_extract v4f32:$S, 0)), 1892 (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 1893 def : Pat<(f32 (vector_extract v4f32:$S, 1)), 1894 (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 1895 def : Pat<(f32 (vector_extract v4f32:$S, 2)), 1896 (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 1897 def : Pat<(f32 (vector_extract v4f32:$S, 3)), 1898 (f32 (XSCVSPDPN $S))>; 1899 def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 1900 (f32 VectorExtractions.LE_VARIABLE_FLOAT)>; 1901} // IsLittleEndian, HasP8Vector 1902 1903// Variable index vector_extract for v2f64 does not require P8Vector 1904let Predicates = [IsLittleEndian, HasVSX] in 1905 def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 1906 (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>; 1907 1908def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>; 1909def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1910 1911// Variable index unsigned vector_extract on Power9 1912let Predicates = [HasP9Altivec, IsLittleEndian] in { 1913 def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 1914 (VEXTUBRX $Idx, $S)>; 1915 1916 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 1917 (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>; 1918 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 1919 (VEXTUHRX (LI8 0), $S)>; 1920 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 1921 (VEXTUHRX (LI8 2), $S)>; 1922 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 1923 (VEXTUHRX (LI8 4), $S)>; 1924 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 1925 (VEXTUHRX (LI8 6), $S)>; 1926 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 1927 (VEXTUHRX (LI8 8), $S)>; 1928 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 1929 (VEXTUHRX (LI8 10), $S)>; 1930 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 1931 (VEXTUHRX (LI8 12), $S)>; 1932 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 1933 (VEXTUHRX (LI8 14), $S)>; 1934 1935 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 1936 (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>; 1937 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 1938 (VEXTUWRX (LI8 0), $S)>; 1939 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 1940 (VEXTUWRX (LI8 4), $S)>; 1941 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 1942 (VEXTUWRX (LI8 8), $S)>; 1943 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 1944 (VEXTUWRX (LI8 12), $S)>; 1945 1946 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 1947 (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>; 1948 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 1949 (EXTSW (VEXTUWRX (LI8 0), $S))>; 1950 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 1951 (EXTSW (VEXTUWRX (LI8 4), $S))>; 1952 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 1953 (EXTSW (VEXTUWRX (LI8 8), $S))>; 1954 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 1955 (EXTSW (VEXTUWRX (LI8 12), $S))>; 1956} 1957let Predicates = [HasP9Altivec, IsBigEndian] in { 1958 def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 1959 (VEXTUBLX $Idx, $S)>; 1960 1961 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 1962 (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>; 1963 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 1964 (VEXTUHLX (LI8 0), $S)>; 1965 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 1966 (VEXTUHLX (LI8 2), $S)>; 1967 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 1968 (VEXTUHLX (LI8 4), $S)>; 1969 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 1970 (VEXTUHLX (LI8 6), $S)>; 1971 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 1972 (VEXTUHLX (LI8 8), $S)>; 1973 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 1974 (VEXTUHLX (LI8 10), $S)>; 1975 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 1976 (VEXTUHLX (LI8 12), $S)>; 1977 def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 1978 (VEXTUHLX (LI8 14), $S)>; 1979 1980 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 1981 (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>; 1982 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 1983 (VEXTUWLX (LI8 0), $S)>; 1984 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 1985 (VEXTUWLX (LI8 4), $S)>; 1986 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 1987 (VEXTUWLX (LI8 8), $S)>; 1988 def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 1989 (VEXTUWLX (LI8 12), $S)>; 1990 1991 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 1992 (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>; 1993 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 1994 (EXTSW (VEXTUWLX (LI8 0), $S))>; 1995 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 1996 (EXTSW (VEXTUWLX (LI8 4), $S))>; 1997 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 1998 (EXTSW (VEXTUWLX (LI8 8), $S))>; 1999 def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 2000 (EXTSW (VEXTUWLX (LI8 12), $S))>; 2001} 2002 2003let Predicates = [IsLittleEndian, HasDirectMove] in { 2004 // v16i8 scalar <-> vector conversions (LE) 2005 def : Pat<(v16i8 (scalar_to_vector i32:$A)), 2006 (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>; 2007 def : Pat<(v8i16 (scalar_to_vector i32:$A)), 2008 (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>; 2009 def : Pat<(v4i32 (scalar_to_vector i32:$A)), 2010 (v4i32 MovesToVSR.LE_WORD_0)>; 2011 def : Pat<(v2i64 (scalar_to_vector i64:$A)), 2012 (v2i64 MovesToVSR.LE_DWORD_0)>; 2013 def : Pat<(i32 (vector_extract v16i8:$S, 0)), 2014 (i32 VectorExtractions.LE_BYTE_0)>; 2015 def : Pat<(i32 (vector_extract v16i8:$S, 1)), 2016 (i32 VectorExtractions.LE_BYTE_1)>; 2017 def : Pat<(i32 (vector_extract v16i8:$S, 2)), 2018 (i32 VectorExtractions.LE_BYTE_2)>; 2019 def : Pat<(i32 (vector_extract v16i8:$S, 3)), 2020 (i32 VectorExtractions.LE_BYTE_3)>; 2021 def : Pat<(i32 (vector_extract v16i8:$S, 4)), 2022 (i32 VectorExtractions.LE_BYTE_4)>; 2023 def : Pat<(i32 (vector_extract v16i8:$S, 5)), 2024 (i32 VectorExtractions.LE_BYTE_5)>; 2025 def : Pat<(i32 (vector_extract v16i8:$S, 6)), 2026 (i32 VectorExtractions.LE_BYTE_6)>; 2027 def : Pat<(i32 (vector_extract v16i8:$S, 7)), 2028 (i32 VectorExtractions.LE_BYTE_7)>; 2029 def : Pat<(i32 (vector_extract v16i8:$S, 8)), 2030 (i32 VectorExtractions.LE_BYTE_8)>; 2031 def : Pat<(i32 (vector_extract v16i8:$S, 9)), 2032 (i32 VectorExtractions.LE_BYTE_9)>; 2033 def : Pat<(i32 (vector_extract v16i8:$S, 10)), 2034 (i32 VectorExtractions.LE_BYTE_10)>; 2035 def : Pat<(i32 (vector_extract v16i8:$S, 11)), 2036 (i32 VectorExtractions.LE_BYTE_11)>; 2037 def : Pat<(i32 (vector_extract v16i8:$S, 12)), 2038 (i32 VectorExtractions.LE_BYTE_12)>; 2039 def : Pat<(i32 (vector_extract v16i8:$S, 13)), 2040 (i32 VectorExtractions.LE_BYTE_13)>; 2041 def : Pat<(i32 (vector_extract v16i8:$S, 14)), 2042 (i32 VectorExtractions.LE_BYTE_14)>; 2043 def : Pat<(i32 (vector_extract v16i8:$S, 15)), 2044 (i32 VectorExtractions.LE_BYTE_15)>; 2045 def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 2046 (i32 VectorExtractions.LE_VARIABLE_BYTE)>; 2047 2048 // v8i16 scalar <-> vector conversions (LE) 2049 def : Pat<(i32 (vector_extract v8i16:$S, 0)), 2050 (i32 VectorExtractions.LE_HALF_0)>; 2051 def : Pat<(i32 (vector_extract v8i16:$S, 1)), 2052 (i32 VectorExtractions.LE_HALF_1)>; 2053 def : Pat<(i32 (vector_extract v8i16:$S, 2)), 2054 (i32 VectorExtractions.LE_HALF_2)>; 2055 def : Pat<(i32 (vector_extract v8i16:$S, 3)), 2056 (i32 VectorExtractions.LE_HALF_3)>; 2057 def : Pat<(i32 (vector_extract v8i16:$S, 4)), 2058 (i32 VectorExtractions.LE_HALF_4)>; 2059 def : Pat<(i32 (vector_extract v8i16:$S, 5)), 2060 (i32 VectorExtractions.LE_HALF_5)>; 2061 def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2062 (i32 VectorExtractions.LE_HALF_6)>; 2063 def : Pat<(i32 (vector_extract v8i16:$S, 7)), 2064 (i32 VectorExtractions.LE_HALF_7)>; 2065 def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 2066 (i32 VectorExtractions.LE_VARIABLE_HALF)>; 2067 2068 // v4i32 scalar <-> vector conversions (LE) 2069 def : Pat<(i32 (vector_extract v4i32:$S, 0)), 2070 (i32 VectorExtractions.LE_WORD_0)>; 2071 def : Pat<(i32 (vector_extract v4i32:$S, 1)), 2072 (i32 VectorExtractions.LE_WORD_1)>; 2073 def : Pat<(i32 (vector_extract v4i32:$S, 2)), 2074 (i32 VectorExtractions.LE_WORD_2)>; 2075 def : Pat<(i32 (vector_extract v4i32:$S, 3)), 2076 (i32 VectorExtractions.LE_WORD_3)>; 2077 def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 2078 (i32 VectorExtractions.LE_VARIABLE_WORD)>; 2079 2080 // v2i64 scalar <-> vector conversions (LE) 2081 def : Pat<(i64 (vector_extract v2i64:$S, 0)), 2082 (i64 VectorExtractions.LE_DWORD_0)>; 2083 def : Pat<(i64 (vector_extract v2i64:$S, 1)), 2084 (i64 VectorExtractions.LE_DWORD_1)>; 2085 def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 2086 (i64 VectorExtractions.LE_VARIABLE_DWORD)>; 2087} // IsLittleEndian, HasDirectMove 2088 2089let Predicates = [HasDirectMove, HasVSX] in { 2090// bitconvert f32 -> i32 2091// (convert to 32-bit fp single, shift right 1 word, move to GPR) 2092def : Pat<(i32 (bitconvert f32:$S)), 2093 (i32 (MFVSRWZ (EXTRACT_SUBREG 2094 (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3), 2095 sub_64)))>; 2096// bitconvert i32 -> f32 2097// (move to FPR, shift left 1 word, convert to 64-bit fp single) 2098def : Pat<(f32 (bitconvert i32:$A)), 2099 (f32 (XSCVSPDPN 2100 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>; 2101 2102// bitconvert f64 -> i64 2103// (move to GPR, nothing else needed) 2104def : Pat<(i64 (bitconvert f64:$S)), 2105 (i64 (MFVSRD $S))>; 2106 2107// bitconvert i64 -> f64 2108// (move to FPR, nothing else needed) 2109def : Pat<(f64 (bitconvert i64:$S)), 2110 (f64 (MTVSRD $S))>; 2111} 2112 2113// Materialize a zero-vector of long long 2114def : Pat<(v2i64 immAllZerosV), 2115 (v2i64 (XXLXORz))>; 2116} 2117 2118def AlignValues { 2119 dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3)); 2120 dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC); 2121} 2122 2123// The following VSX instructions were introduced in Power ISA 3.0 2124def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">; 2125let AddedComplexity = 400, Predicates = [HasP9Vector] in { 2126 2127 // [PO VRT XO VRB XO /] 2128 class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2129 list<dag> pattern> 2130 : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB), 2131 !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2132 2133 // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /] 2134 class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2135 list<dag> pattern> 2136 : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT; 2137 2138 // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less), 2139 // So we use different operand class for VRB 2140 class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2141 RegisterOperand vbtype, list<dag> pattern> 2142 : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB), 2143 !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2144 2145 let UseVSXReg = 1 in { 2146 // [PO T XO B XO BX /] 2147 class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2148 list<dag> pattern> 2149 : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB), 2150 !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>; 2151 2152 // [PO T XO B XO BX TX] 2153 class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2154 RegisterOperand vtype, list<dag> pattern> 2155 : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB), 2156 !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>; 2157 2158 // [PO T A B XO AX BX TX], src and dest register use different operand class 2159 class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc, 2160 RegisterOperand xty, RegisterOperand aty, RegisterOperand bty, 2161 InstrItinClass itin, list<dag> pattern> 2162 : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB), 2163 !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>; 2164 } // UseVSXReg = 1 2165 2166 // [PO VRT VRA VRB XO /] 2167 class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2168 list<dag> pattern> 2169 : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB), 2170 !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>; 2171 2172 // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /] 2173 class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc, 2174 list<dag> pattern> 2175 : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT; 2176 2177 //===--------------------------------------------------------------------===// 2178 // Quad-Precision Scalar Move Instructions: 2179 2180 // Copy Sign 2181 def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>; 2182 2183 // Absolute/Negative-Absolute/Negate 2184 def XSABSQP : X_VT5_XO5_VB5<63, 0, 804, "xsabsqp" , []>; 2185 def XSNABSQP : X_VT5_XO5_VB5<63, 8, 804, "xsnabsqp", []>; 2186 def XSNEGQP : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>; 2187 2188 //===--------------------------------------------------------------------===// 2189 // Quad-Precision Scalar Floating-Point Arithmetic Instructions: 2190 2191 // Add/Divide/Multiply/Subtract 2192 def XSADDQP : X_VT5_VA5_VB5 <63, 4, "xsaddqp" , []>; 2193 def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo", []>; 2194 def XSDIVQP : X_VT5_VA5_VB5 <63, 548, "xsdivqp" , []>; 2195 def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>; 2196 def XSMULQP : X_VT5_VA5_VB5 <63, 36, "xsmulqp" , []>; 2197 def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo", []>; 2198 def XSSUBQP : X_VT5_VA5_VB5 <63, 516, "xssubqp" , []>; 2199 def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>; 2200 2201 // Square-Root 2202 def XSSQRTQP : X_VT5_XO5_VB5 <63, 27, 804, "xssqrtqp" , []>; 2203 def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>; 2204 2205 // (Negative) Multiply-{Add/Subtract} 2206 def XSMADDQP : X_VT5_VA5_VB5 <63, 388, "xsmaddqp" , []>; 2207 def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>; 2208 def XSMSUBQP : X_VT5_VA5_VB5 <63, 420, "xsmsubqp" , []>; 2209 def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>; 2210 def XSNMADDQP : X_VT5_VA5_VB5 <63, 452, "xsnmaddqp" , []>; 2211 def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>; 2212 def XSNMSUBQP : X_VT5_VA5_VB5 <63, 484, "xsnmsubqp" , []>; 2213 def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>; 2214 2215 //===--------------------------------------------------------------------===// 2216 // Quad/Double-Precision Compare Instructions: 2217 2218 // [PO BF // VRA VRB XO /] 2219 class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2220 list<dag> pattern> 2221 : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB), 2222 !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> { 2223 let Pattern = pattern; 2224 } 2225 2226 // QP Compare Ordered/Unordered 2227 def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>; 2228 def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>; 2229 2230 // DP/QP Compare Exponents 2231 def XSCMPEXPDP : XX3Form_1<60, 59, 2232 (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 2233 "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>, 2234 UseVSXReg; 2235 def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>; 2236 2237 // DP Compare ==, >=, >, != 2238 // Use vsrc for XT, because the entire register of XT is set. 2239 // XT.dword[1] = 0x0000_0000_0000_0000 2240 def XSCMPEQDP : XX3_XT5_XA5_XB5<60, 3, "xscmpeqdp", vsrc, vsfrc, vsfrc, 2241 IIC_FPCompare, []>; 2242 def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc, 2243 IIC_FPCompare, []>; 2244 def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc, 2245 IIC_FPCompare, []>; 2246 def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc, 2247 IIC_FPCompare, []>; 2248 let UseVSXReg = 1 in { 2249 // Vector Compare Not Equal 2250 def XVCMPNEDP : XX3Form_Rc<60, 123, 2251 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 2252 "xvcmpnedp $XT, $XA, $XB", IIC_VecFPCompare, []>; 2253 let Defs = [CR6] in 2254 def XVCMPNEDPo : XX3Form_Rc<60, 123, 2255 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 2256 "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>, 2257 isDOT; 2258 def XVCMPNESP : XX3Form_Rc<60, 91, 2259 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 2260 "xvcmpnesp $XT, $XA, $XB", IIC_VecFPCompare, []>; 2261 let Defs = [CR6] in 2262 def XVCMPNESPo : XX3Form_Rc<60, 91, 2263 (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 2264 "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>, 2265 isDOT; 2266 } // UseVSXReg = 1 2267 2268 //===--------------------------------------------------------------------===// 2269 // Quad-Precision Floating-Point Conversion Instructions: 2270 2271 // Convert DP -> QP 2272 def XSCVDPQP : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>; 2273 2274 // Round & Convert QP -> DP (dword[1] is set to zero) 2275 def XSCVQPDP : X_VT5_XO5_VB5 <63, 20, 836, "xscvqpdp" , []>; 2276 def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>; 2277 2278 // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero) 2279 def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>; 2280 def XSCVQPSWZ : X_VT5_XO5_VB5<63, 9, 836, "xscvqpswz", []>; 2281 def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>; 2282 def XSCVQPUWZ : X_VT5_XO5_VB5<63, 1, 836, "xscvqpuwz", []>; 2283 2284 // Convert (Un)Signed DWord -> QP 2285 def XSCVSDQP : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>; 2286 def XSCVUDQP : X_VT5_XO5_VB5_TyVB<63, 2, 836, "xscvudqp", vfrc, []>; 2287 2288 let UseVSXReg = 1 in { 2289 //===--------------------------------------------------------------------===// 2290 // Round to Floating-Point Integer Instructions 2291 2292 // (Round &) Convert DP <-> HP 2293 // Note! xscvdphp's src and dest register both use the left 64 bits, so we use 2294 // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits, 2295 // but we still use vsfrc for it. 2296 def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>; 2297 def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>; 2298 2299 // Vector HP -> SP 2300 def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>; 2301 def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc, 2302 [(set v4f32:$XT, 2303 (int_ppc_vsx_xvcvsphp v4f32:$XB))]>; 2304 2305 } // UseVSXReg = 1 2306 2307 // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a 2308 // separate pattern so that it can convert the input register class from 2309 // VRRC(v8i16) to VSRC. 2310 def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)), 2311 (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>; 2312 2313 class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc, 2314 list<dag> pattern> 2315 : Z23Form_1<opcode, xo, 2316 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc), 2317 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> { 2318 let RC = ex; 2319 } 2320 2321 // Round to Quad-Precision Integer [with Inexact] 2322 def XSRQPI : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 0, "xsrqpi" , []>; 2323 def XSRQPIX : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 1, "xsrqpix", []>; 2324 2325 // Round Quad-Precision to Double-Extended Precision (fp80) 2326 def XSRQPXP : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>; 2327 2328 //===--------------------------------------------------------------------===// 2329 // Insert/Extract Instructions 2330 2331 // Insert Exponent DP/QP 2332 // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU 2333 def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB), 2334 "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg; 2335 // vB NOTE: only vB.dword[0] is used, that's why we don't use 2336 // X_VT5_VA5_VB5 form 2337 def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB), 2338 "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>; 2339 2340 // Extract Exponent/Significand DP/QP 2341 def XSXEXPDP : XX2_RT5_XO5_XB6<60, 0, 347, "xsxexpdp", []>; 2342 def XSXSIGDP : XX2_RT5_XO5_XB6<60, 1, 347, "xsxsigdp", []>; 2343 2344 def XSXEXPQP : X_VT5_XO5_VB5 <63, 2, 804, "xsxexpqp", []>; 2345 def XSXSIGQP : X_VT5_XO5_VB5 <63, 18, 804, "xsxsigqp", []>; 2346 2347 // Vector Insert Word 2348 let UseVSXReg = 1 in { 2349 // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB. 2350 def XXINSERTW : 2351 XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT), 2352 (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM), 2353 "xxinsertw $XT, $XB, $UIM", IIC_VecFP, 2354 [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB, 2355 imm32SExt16:$UIM))]>, 2356 RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">; 2357 2358 // Vector Extract Unsigned Word 2359 def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165, 2360 (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM), 2361 "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>; 2362 } // UseVSXReg = 1 2363 2364 // Vector Insert Exponent DP/SP 2365 def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc, 2366 IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>; 2367 def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc, 2368 IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>; 2369 2370 // Vector Extract Exponent/Significand DP/SP 2371 def XVXEXPDP : XX2_XT6_XO5_XB6<60, 0, 475, "xvxexpdp", vsrc, 2372 [(set v2i64: $XT, 2373 (int_ppc_vsx_xvxexpdp v2f64:$XB))]>; 2374 def XVXEXPSP : XX2_XT6_XO5_XB6<60, 8, 475, "xvxexpsp", vsrc, 2375 [(set v4i32: $XT, 2376 (int_ppc_vsx_xvxexpsp v4f32:$XB))]>; 2377 def XVXSIGDP : XX2_XT6_XO5_XB6<60, 1, 475, "xvxsigdp", vsrc, 2378 [(set v2i64: $XT, 2379 (int_ppc_vsx_xvxsigdp v2f64:$XB))]>; 2380 def XVXSIGSP : XX2_XT6_XO5_XB6<60, 9, 475, "xvxsigsp", vsrc, 2381 [(set v4i32: $XT, 2382 (int_ppc_vsx_xvxsigsp v4f32:$XB))]>; 2383 2384 let AddedComplexity = 400, Predicates = [HasP9Vector] in { 2385 // Extra patterns expanding to vector Extract Word/Insert Word 2386 def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)), 2387 (v4i32 (XXINSERTW $A, $B, imm:$IMM))>; 2388 def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)), 2389 (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>; 2390 } // AddedComplexity = 400, HasP9Vector 2391 2392 //===--------------------------------------------------------------------===// 2393 2394 // Test Data Class SP/DP/QP 2395 let UseVSXReg = 1 in { 2396 def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298, 2397 (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 2398 "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>; 2399 def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362, 2400 (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 2401 "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>; 2402 } // UseVSXReg = 1 2403 def XSTSTDCQP : X_BF3_DCMX7_RS5 <63, 708, 2404 (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB), 2405 "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>; 2406 2407 // Vector Test Data Class SP/DP 2408 let UseVSXReg = 1 in { 2409 def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5, 2410 (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 2411 "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP, 2412 [(set v4i32: $XT, 2413 (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>; 2414 def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5, 2415 (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 2416 "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP, 2417 [(set v2i64: $XT, 2418 (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>; 2419 } // UseVSXReg = 1 2420 2421 //===--------------------------------------------------------------------===// 2422 2423 // Maximum/Minimum Type-C/Type-J DP 2424 // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT 2425 def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc, 2426 IIC_VecFP, []>; 2427 def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc, 2428 IIC_VecFP, []>; 2429 def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc, 2430 IIC_VecFP, []>; 2431 def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc, 2432 IIC_VecFP, []>; 2433 2434 //===--------------------------------------------------------------------===// 2435 2436 // Vector Byte-Reverse H/W/D/Q Word 2437 def XXBRH : XX2_XT6_XO5_XB6<60, 7, 475, "xxbrh", vsrc, []>; 2438 def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>; 2439 def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>; 2440 def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>; 2441 2442 // Vector Reverse 2443 def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)), 2444 (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 2445 def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)), 2446 (v4i32 (XXBRW $A))>; 2447 def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)), 2448 (v2i64 (XXBRD $A))>; 2449 def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)), 2450 (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 2451 2452 // Vector Permute 2453 def XXPERM : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc, 2454 IIC_VecPerm, []>; 2455 def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc, 2456 IIC_VecPerm, []>; 2457 2458 // Vector Splat Immediate Byte 2459 def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8), 2460 "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg; 2461 2462 //===--------------------------------------------------------------------===// 2463 // Vector/Scalar Load/Store Instructions 2464 2465 // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 2466 // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 2467 let mayLoad = 1, mayStore = 0 in { 2468 // Load Vector 2469 def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src), 2470 "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg; 2471 // Load DWord 2472 def LXSD : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src), 2473 "lxsd $vD, $src", IIC_LdStLFD, []>; 2474 // Load SP from src, convert it to DP, and place in dword[0] 2475 def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src), 2476 "lxssp $vD, $src", IIC_LdStLFD, []>; 2477 2478 // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different 2479 // "out" and "in" dag 2480 class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2481 RegisterOperand vtype, list<dag> pattern> 2482 : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src), 2483 !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg; 2484 2485 // Load as Integer Byte/Halfword & Zero Indexed 2486 def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc, 2487 [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>; 2488 def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc, 2489 [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>; 2490 2491 // Load Vector Halfword*8/Byte*16 Indexed 2492 def LXVH8X : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>; 2493 def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>; 2494 2495 // Load Vector Indexed 2496 def LXVX : X_XT6_RA5_RB5<31, 268, "lxvx" , vsrc, 2497 [(set v2f64:$XT, (load xaddr:$src))]>; 2498 // Load Vector (Left-justified) with Length 2499 def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 2500 "lxvl $XT, $src, $rB", IIC_LdStLoad, 2501 [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>, 2502 UseVSXReg; 2503 def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 2504 "lxvll $XT, $src, $rB", IIC_LdStLoad, 2505 [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>, 2506 UseVSXReg; 2507 2508 // Load Vector Word & Splat Indexed 2509 def LXVWSX : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>; 2510 } // mayLoad 2511 2512 // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 2513 // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 2514 let mayStore = 1, mayLoad = 0 in { 2515 // Store Vector 2516 def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst), 2517 "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg; 2518 // Store DWord 2519 def STXSD : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst), 2520 "stxsd $vS, $dst", IIC_LdStSTFD, []>; 2521 // Convert DP of dword[0] to SP, and Store to dst 2522 def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst), 2523 "stxssp $vS, $dst", IIC_LdStSTFD, []>; 2524 2525 // [PO S RA RB XO SX] 2526 class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2527 RegisterOperand vtype, list<dag> pattern> 2528 : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst), 2529 !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg; 2530 2531 // Store as Integer Byte/Halfword Indexed 2532 def STXSIBX : X_XS6_RA5_RB5<31, 909, "stxsibx" , vsfrc, 2533 [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>; 2534 def STXSIHX : X_XS6_RA5_RB5<31, 941, "stxsihx" , vsfrc, 2535 [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>; 2536 let isCodeGenOnly = 1 in { 2537 def STXSIBXv : X_XS6_RA5_RB5<31, 909, "stxsibx" , vrrc, []>; 2538 def STXSIHXv : X_XS6_RA5_RB5<31, 941, "stxsihx" , vrrc, []>; 2539 } 2540 2541 // Store Vector Halfword*8/Byte*16 Indexed 2542 def STXVH8X : X_XS6_RA5_RB5<31, 940, "stxvh8x" , vsrc, []>; 2543 def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>; 2544 2545 // Store Vector Indexed 2546 def STXVX : X_XS6_RA5_RB5<31, 396, "stxvx" , vsrc, 2547 [(store v2f64:$XT, xaddr:$dst)]>; 2548 2549 // Store Vector (Left-justified) with Length 2550 def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB), 2551 "stxvl $XT, $dst, $rB", IIC_LdStLoad, 2552 [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>, 2553 UseVSXReg; 2554 def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB), 2555 "stxvll $XT, $dst, $rB", IIC_LdStLoad, 2556 [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>, 2557 UseVSXReg; 2558 } // mayStore 2559 2560 let Predicates = [IsLittleEndian] in { 2561 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))), 2562 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 2563 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))), 2564 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 2565 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))), 2566 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 2567 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))), 2568 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 2569 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))), 2570 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 2571 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))), 2572 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 2573 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))), 2574 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 2575 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))), 2576 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 2577 } 2578 2579 let Predicates = [IsBigEndian] in { 2580 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))), 2581 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 2582 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))), 2583 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 2584 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))), 2585 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 2586 def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))), 2587 (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 2588 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))), 2589 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 2590 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))), 2591 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 2592 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))), 2593 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 2594 def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))), 2595 (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 2596 } 2597 2598 // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead 2599 // of f64 2600 def : Pat<(v8i16 (PPCmtvsrz i32:$A)), 2601 (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 2602 def : Pat<(v16i8 (PPCmtvsrz i32:$A)), 2603 (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 2604 2605 // Patterns for which instructions from ISA 3.0 are a better match 2606 let Predicates = [IsLittleEndian, HasP9Vector] in { 2607 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))), 2608 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 2609 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))), 2610 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 2611 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))), 2612 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 2613 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))), 2614 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 2615 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))), 2616 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 2617 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))), 2618 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 2619 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))), 2620 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 2621 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))), 2622 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 2623 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 2624 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 2625 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 2626 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 2627 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 2628 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 2629 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 2630 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 2631 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 2632 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 2633 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 2634 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 2635 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 2636 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 2637 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 2638 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 2639 } // IsLittleEndian, HasP9Vector 2640 2641 let Predicates = [IsBigEndian, HasP9Vector] in { 2642 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))), 2643 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 2644 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))), 2645 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 2646 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))), 2647 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 2648 def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))), 2649 (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 2650 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))), 2651 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 2652 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))), 2653 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 2654 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))), 2655 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 2656 def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))), 2657 (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 2658 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 2659 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 2660 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 2661 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 2662 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 2663 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 2664 def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 2665 (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 2666 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 2667 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 2668 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 2669 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 2670 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 2671 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 2672 def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 2673 (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 2674 } // IsLittleEndian, HasP9Vector 2675 2676 // D-Form Load/Store 2677 def : Pat<(v4i32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>; 2678 def : Pat<(v4f32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>; 2679 def : Pat<(v2i64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>; 2680 def : Pat<(v2f64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>; 2681 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iqaddr:$src)), (LXV memrix16:$src)>; 2682 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iqaddr:$src)), (LXV memrix16:$src)>; 2683 2684 def : Pat<(quadwOffsetStore v4f32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>; 2685 def : Pat<(quadwOffsetStore v4i32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>; 2686 def : Pat<(quadwOffsetStore v2f64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>; 2687 def : Pat<(quadwOffsetStore v2i64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>; 2688 def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iqaddr:$dst), 2689 (STXV $rS, memrix16:$dst)>; 2690 def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iqaddr:$dst), 2691 (STXV $rS, memrix16:$dst)>; 2692 2693 2694 def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 2695 def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 2696 def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 2697 def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 2698 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>; 2699 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>; 2700 def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst), 2701 (STXVX $rS, xoaddr:$dst)>; 2702 def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst), 2703 (STXVX $rS, xoaddr:$dst)>; 2704 def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst), 2705 (STXVX $rS, xoaddr:$dst)>; 2706 def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst), 2707 (STXVX $rS, xoaddr:$dst)>; 2708 def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), 2709 (STXVX $rS, xoaddr:$dst)>; 2710 def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), 2711 (STXVX $rS, xoaddr:$dst)>; 2712 def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))), 2713 (v4i32 (LXVWSX xoaddr:$src))>; 2714 def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))), 2715 (v4f32 (LXVWSX xoaddr:$src))>; 2716 def : Pat<(v4f32 (scalar_to_vector (f32 (fpround (extloadf32 xoaddr:$src))))), 2717 (v4f32 (LXVWSX xoaddr:$src))>; 2718 2719 // Build vectors from i8 loads 2720 def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)), 2721 (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>; 2722 def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)), 2723 (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>; 2724 def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)), 2725 (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>; 2726 def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)), 2727 (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>; 2728 def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)), 2729 (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>; 2730 def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)), 2731 (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>; 2732 2733 // Build vectors from i16 loads 2734 def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)), 2735 (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>; 2736 def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)), 2737 (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>; 2738 def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)), 2739 (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>; 2740 def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)), 2741 (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>; 2742 def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)), 2743 (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>; 2744 2745 let Predicates = [IsBigEndian, HasP9Vector] in { 2746 // Scalar stores of i8 2747 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 2748 (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>; 2749 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 2750 (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>; 2751 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 2752 (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>; 2753 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 2754 (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>; 2755 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 2756 (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>; 2757 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 2758 (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>; 2759 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 2760 (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>; 2761 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 2762 (STXSIBXv $S, xoaddr:$dst)>; 2763 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 2764 (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>; 2765 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 2766 (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>; 2767 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 2768 (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>; 2769 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 2770 (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>; 2771 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 2772 (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>; 2773 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 2774 (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>; 2775 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 2776 (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>; 2777 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 2778 (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>; 2779 2780 // Scalar stores of i16 2781 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 2782 (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>; 2783 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 2784 (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>; 2785 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 2786 (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>; 2787 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 2788 (STXSIHXv $S, xoaddr:$dst)>; 2789 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 2790 (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>; 2791 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 2792 (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>; 2793 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 2794 (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>; 2795 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 2796 (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>; 2797 } // IsBigEndian, HasP9Vector 2798 2799 let Predicates = [IsLittleEndian, HasP9Vector] in { 2800 // Scalar stores of i8 2801 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 2802 (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>; 2803 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 2804 (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>; 2805 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 2806 (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>; 2807 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 2808 (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>; 2809 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 2810 (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>; 2811 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 2812 (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>; 2813 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 2814 (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>; 2815 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 2816 (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>; 2817 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 2818 (STXSIBXv $S, xoaddr:$dst)>; 2819 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 2820 (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>; 2821 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 2822 (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>; 2823 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 2824 (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>; 2825 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 2826 (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>; 2827 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 2828 (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>; 2829 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 2830 (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>; 2831 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 2832 (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>; 2833 2834 // Scalar stores of i16 2835 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 2836 (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>; 2837 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 2838 (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>; 2839 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 2840 (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>; 2841 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 2842 (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>; 2843 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 2844 (STXSIHXv $S, xoaddr:$dst)>; 2845 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 2846 (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>; 2847 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 2848 (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>; 2849 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 2850 (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>; 2851 } // IsLittleEndian, HasP9Vector 2852 2853 2854 // Vector sign extensions 2855 def : Pat<(f64 (PPCVexts f64:$A, 1)), 2856 (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>; 2857 def : Pat<(f64 (PPCVexts f64:$A, 2)), 2858 (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>; 2859 2860 let isPseudo = 1 in { 2861 def DFLOADf32 : Pseudo<(outs vssrc:$XT), (ins memrix:$src), 2862 "#DFLOADf32", 2863 [(set f32:$XT, (load ixaddr:$src))]>; 2864 def DFLOADf64 : Pseudo<(outs vsfrc:$XT), (ins memrix:$src), 2865 "#DFLOADf64", 2866 [(set f64:$XT, (load ixaddr:$src))]>; 2867 def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst), 2868 "#DFSTOREf32", 2869 [(store f32:$XT, ixaddr:$dst)]>; 2870 def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst), 2871 "#DFSTOREf64", 2872 [(store f64:$XT, ixaddr:$dst)]>; 2873 } 2874 def : Pat<(f64 (extloadf32 ixaddr:$src)), 2875 (COPY_TO_REGCLASS (DFLOADf32 ixaddr:$src), VSFRC)>; 2876 def : Pat<(f32 (fpround (extloadf32 ixaddr:$src))), 2877 (f32 (DFLOADf32 ixaddr:$src))>; 2878} // end HasP9Vector, AddedComplexity 2879 2880let Predicates = [HasP9Vector] in { 2881 let isPseudo = 1 in { 2882 let mayStore = 1 in { 2883 def SPILLTOVSR_STX : Pseudo<(outs), (ins spilltovsrrc:$XT, memrr:$dst), 2884 "#SPILLTOVSR_STX", []>; 2885 def SPILLTOVSR_ST : Pseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst), 2886 "#SPILLTOVSR_ST", []>; 2887 } 2888 let mayLoad = 1 in { 2889 def SPILLTOVSR_LDX : Pseudo<(outs spilltovsrrc:$XT), (ins memrr:$src), 2890 "#SPILLTOVSR_LDX", []>; 2891 def SPILLTOVSR_LD : Pseudo<(outs spilltovsrrc:$XT), (ins memrix:$src), 2892 "#SPILLTOVSR_LD", []>; 2893 2894 } 2895 } 2896} 2897// Integer extend helper dags 32 -> 64 2898def AnyExts { 2899 dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32); 2900 dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32); 2901 dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32); 2902 dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32); 2903} 2904 2905def DblToFlt { 2906 dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0)))); 2907 dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1)))); 2908 dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0)))); 2909 dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1)))); 2910} 2911 2912def ByteToWord { 2913 dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8)); 2914 dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8)); 2915 dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8)); 2916 dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8)); 2917 dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8)); 2918 dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8)); 2919 dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8)); 2920 dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8)); 2921} 2922 2923def ByteToDWord { 2924 dag LE_A0 = (i64 (sext_inreg 2925 (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8)); 2926 dag LE_A1 = (i64 (sext_inreg 2927 (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8)); 2928 dag BE_A0 = (i64 (sext_inreg 2929 (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8)); 2930 dag BE_A1 = (i64 (sext_inreg 2931 (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8)); 2932} 2933 2934def HWordToWord { 2935 dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16)); 2936 dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16)); 2937 dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16)); 2938 dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16)); 2939 dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16)); 2940 dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16)); 2941 dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16)); 2942 dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16)); 2943} 2944 2945def HWordToDWord { 2946 dag LE_A0 = (i64 (sext_inreg 2947 (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16)); 2948 dag LE_A1 = (i64 (sext_inreg 2949 (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16)); 2950 dag BE_A0 = (i64 (sext_inreg 2951 (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16)); 2952 dag BE_A1 = (i64 (sext_inreg 2953 (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16)); 2954} 2955 2956def WordToDWord { 2957 dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0)))); 2958 dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2)))); 2959 dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1)))); 2960 dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3)))); 2961} 2962 2963def FltToIntLoad { 2964 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A))))); 2965} 2966def FltToUIntLoad { 2967 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A))))); 2968} 2969def FltToLongLoad { 2970 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A))))); 2971} 2972def FltToLongLoadP9 { 2973 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ixaddr:$A))))); 2974} 2975def FltToULongLoad { 2976 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A))))); 2977} 2978def FltToULongLoadP9 { 2979 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ixaddr:$A))))); 2980} 2981def FltToLong { 2982 dag A = (i64 (PPCmfvsr (PPCfctidz (fpextend f32:$A)))); 2983} 2984def FltToULong { 2985 dag A = (i64 (PPCmfvsr (PPCfctiduz (fpextend f32:$A)))); 2986} 2987def DblToInt { 2988 dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A)))); 2989} 2990def DblToUInt { 2991 dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A)))); 2992} 2993def DblToLong { 2994 dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A)))); 2995} 2996def DblToULong { 2997 dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A)))); 2998} 2999def DblToIntLoad { 3000 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A))))); 3001} 3002def DblToIntLoadP9 { 3003 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ixaddr:$A))))); 3004} 3005def DblToUIntLoad { 3006 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A))))); 3007} 3008def DblToUIntLoadP9 { 3009 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ixaddr:$A))))); 3010} 3011def DblToLongLoad { 3012 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A))))); 3013} 3014def DblToULongLoad { 3015 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A))))); 3016} 3017 3018// FP merge dags (for f32 -> v4f32) 3019def MrgFP { 3020 dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC), 3021 (COPY_TO_REGCLASS $C, VSRC), 0)); 3022 dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC), 3023 (COPY_TO_REGCLASS $D, VSRC), 0)); 3024 dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0)); 3025 dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3)); 3026 dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0)); 3027 dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3)); 3028} 3029 3030// Patterns for BUILD_VECTOR nodes. 3031def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">; 3032let AddedComplexity = 400 in { 3033 3034 let Predicates = [HasVSX] in { 3035 // Build vectors of floating point converted to i32. 3036 def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A, 3037 DblToInt.A, DblToInt.A)), 3038 (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>; 3039 def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A, 3040 DblToUInt.A, DblToUInt.A)), 3041 (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>; 3042 def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)), 3043 (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 3044 (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>; 3045 def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)), 3046 (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 3047 (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>; 3048 def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 3049 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3050 (XSCVDPSXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>; 3051 def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 3052 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3053 (XSCVDPUXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>; 3054 def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)), 3055 (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>; 3056 3057 // Build vectors of floating point converted to i64. 3058 def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)), 3059 (v2i64 (XXPERMDIs 3060 (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>; 3061 def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)), 3062 (v2i64 (XXPERMDIs 3063 (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>; 3064 def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)), 3065 (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>; 3066 def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)), 3067 (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>; 3068 } 3069 3070 let Predicates = [HasVSX, NoP9Vector] in { 3071 // Load-and-splat with fp-to-int conversion (using X-Form VSX loads). 3072 def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)), 3073 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3074 (XSCVDPSXWS (LXSDX xoaddr:$A)), VSRC), 1))>; 3075 def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)), 3076 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3077 (XSCVDPUXWS (LXSDX xoaddr:$A)), VSRC), 1))>; 3078 def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)), 3079 (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 3080 (LXSSPX xoaddr:$A), VSFRC)), 0))>; 3081 def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)), 3082 (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 3083 (LXSSPX xoaddr:$A), VSFRC)), 0))>; 3084 } 3085 3086 // Big endian, available on all targets with VSX 3087 let Predicates = [IsBigEndian, HasVSX] in { 3088 def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 3089 (v2f64 (XXPERMDI 3090 (COPY_TO_REGCLASS $A, VSRC), 3091 (COPY_TO_REGCLASS $B, VSRC), 0))>; 3092 3093 def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)), 3094 (VMRGEW MrgFP.AC, MrgFP.BD)>; 3095 def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 3096 DblToFlt.B0, DblToFlt.B1)), 3097 (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>; 3098 } 3099 3100 let Predicates = [IsLittleEndian, HasVSX] in { 3101 // Little endian, available on all targets with VSX 3102 def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 3103 (v2f64 (XXPERMDI 3104 (COPY_TO_REGCLASS $B, VSRC), 3105 (COPY_TO_REGCLASS $A, VSRC), 0))>; 3106 3107 def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)), 3108 (VMRGEW MrgFP.AC, MrgFP.BD)>; 3109 def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 3110 DblToFlt.B0, DblToFlt.B1)), 3111 (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>; 3112 } 3113 3114 let Predicates = [HasDirectMove] in { 3115 // Endianness-neutral constant splat on P8 and newer targets. The reason 3116 // for this pattern is that on targets with direct moves, we don't expand 3117 // BUILD_VECTOR nodes for v4i32. 3118 def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A, 3119 immSExt5NonZero:$A, immSExt5NonZero:$A)), 3120 (v4i32 (VSPLTISW imm:$A))>; 3121 } 3122 3123 let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in { 3124 // Big endian integer vectors using direct moves. 3125 def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 3126 (v2i64 (XXPERMDI 3127 (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 3128 (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>; 3129 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 3130 (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 3131 (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0), 3132 (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 3133 (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>; 3134 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 3135 (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 3136 } 3137 3138 let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in { 3139 // Little endian integer vectors using direct moves. 3140 def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 3141 (v2i64 (XXPERMDI 3142 (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 3143 (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>; 3144 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 3145 (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 3146 (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0), 3147 (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 3148 (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>; 3149 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 3150 (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 3151 } 3152 3153 let Predicates = [HasP9Vector] in { 3154 // Endianness-neutral patterns for const splats with ISA 3.0 instructions. 3155 def : Pat<(v4i32 (scalar_to_vector i32:$A)), 3156 (v4i32 (MTVSRWS $A))>; 3157 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 3158 (v4i32 (MTVSRWS $A))>; 3159 def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 3160 immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 3161 immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 3162 immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 3163 immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 3164 immAnyExt8:$A)), 3165 (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>; 3166 def : Pat<(v16i8 immAllOnesV), 3167 (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>; 3168 def : Pat<(v8i16 immAllOnesV), 3169 (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>; 3170 def : Pat<(v4i32 immAllOnesV), 3171 (v4i32 (XXSPLTIB 255))>; 3172 def : Pat<(v2i64 immAllOnesV), 3173 (v2i64 (XXSPLTIB 255))>; 3174 def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 3175 (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>; 3176 def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 3177 (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>; 3178 def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)), 3179 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3180 (XSCVDPSXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>; 3181 def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)), 3182 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3183 (XSCVDPUXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>; 3184 def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)), 3185 (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 3186 (DFLOADf32 ixaddr:$A), 3187 VSFRC)), 0))>; 3188 def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)), 3189 (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 3190 (DFLOADf32 ixaddr:$A), 3191 VSFRC)), 0))>; 3192 } 3193 3194 let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in { 3195 def : Pat<(i64 (extractelt v2i64:$A, 1)), 3196 (i64 (MFVSRLD $A))>; 3197 // Better way to build integer vectors if we have MTVSRDD. Big endian. 3198 def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)), 3199 (v2i64 (MTVSRDD $rB, $rA))>; 3200 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 3201 (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC), 3202 (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC))>; 3203 } 3204 3205 let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in { 3206 def : Pat<(i64 (extractelt v2i64:$A, 0)), 3207 (i64 (MFVSRLD $A))>; 3208 // Better way to build integer vectors if we have MTVSRDD. Little endian. 3209 def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)), 3210 (v2i64 (MTVSRDD $rB, $rA))>; 3211 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 3212 (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC), 3213 (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC))>; 3214 } 3215 // P9 Altivec instructions that can be used to build vectors. 3216 // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete 3217 // with complexities of existing build vector patterns in this file. 3218 let Predicates = [HasP9Altivec, IsLittleEndian] in { 3219 def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)), 3220 (v2i64 (VEXTSW2D $A))>; 3221 def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)), 3222 (v2i64 (VEXTSH2D $A))>; 3223 def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1, 3224 HWordToWord.LE_A2, HWordToWord.LE_A3)), 3225 (v4i32 (VEXTSH2W $A))>; 3226 def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1, 3227 ByteToWord.LE_A2, ByteToWord.LE_A3)), 3228 (v4i32 (VEXTSB2W $A))>; 3229 def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)), 3230 (v2i64 (VEXTSB2D $A))>; 3231 } 3232 3233 let Predicates = [HasP9Altivec, IsBigEndian] in { 3234 def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)), 3235 (v2i64 (VEXTSW2D $A))>; 3236 def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)), 3237 (v2i64 (VEXTSH2D $A))>; 3238 def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1, 3239 HWordToWord.BE_A2, HWordToWord.BE_A3)), 3240 (v4i32 (VEXTSH2W $A))>; 3241 def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1, 3242 ByteToWord.BE_A2, ByteToWord.BE_A3)), 3243 (v4i32 (VEXTSB2W $A))>; 3244 def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)), 3245 (v2i64 (VEXTSB2D $A))>; 3246 } 3247 3248 let Predicates = [HasP9Altivec] in { 3249 def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)), 3250 (v2i64 (VEXTSB2D $A))>; 3251 def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)), 3252 (v2i64 (VEXTSH2D $A))>; 3253 def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)), 3254 (v2i64 (VEXTSW2D $A))>; 3255 def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)), 3256 (v4i32 (VEXTSB2W $A))>; 3257 def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)), 3258 (v4i32 (VEXTSH2W $A))>; 3259 } 3260} 3261