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