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