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), VSRC), 2))>; 3315 3316 def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))), 3317 (v2i64 (XXPERMDIs 3318 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>; 3319 3320 def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))), 3321 (v4i32 (XXPERMDIs 3322 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>; 3323 3324 def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))), 3325 (v4f32 (XXPERMDIs 3326 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 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 let Predicates = [IsBigEndian, HasP9Vector] in { 3374 // Scalar stores of i8 3375 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 3376 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>; 3377 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 3378 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3379 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 3380 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>; 3381 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 3382 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3383 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 3384 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>; 3385 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 3386 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3387 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 3388 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>; 3389 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 3390 (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3391 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 3392 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>; 3393 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 3394 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3395 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 3396 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>; 3397 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 3398 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3399 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 3400 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>; 3401 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 3402 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3403 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 3404 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>; 3405 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 3406 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3407 3408 // Scalar stores of i16 3409 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 3410 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3411 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 3412 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3413 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 3414 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3415 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 3416 (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3417 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 3418 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3419 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 3420 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3421 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 3422 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3423 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 3424 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3425 } // IsBigEndian, HasP9Vector 3426 3427 let Predicates = [IsLittleEndian, HasP9Vector] in { 3428 // Scalar stores of i8 3429 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 3430 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3431 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 3432 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>; 3433 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 3434 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3435 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 3436 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>; 3437 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 3438 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3439 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 3440 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>; 3441 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 3442 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3443 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 3444 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>; 3445 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 3446 (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3447 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 3448 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>; 3449 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 3450 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3451 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 3452 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>; 3453 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 3454 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3455 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 3456 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>; 3457 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 3458 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3459 def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 3460 (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>; 3461 3462 // Scalar stores of i16 3463 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 3464 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3465 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 3466 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3467 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 3468 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3469 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 3470 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3471 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 3472 (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3473 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 3474 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3475 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 3476 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3477 def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 3478 (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3479 } // IsLittleEndian, HasP9Vector 3480 3481 3482 // Vector sign extensions 3483 def : Pat<(f64 (PPCVexts f64:$A, 1)), 3484 (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>; 3485 def : Pat<(f64 (PPCVexts f64:$A, 2)), 3486 (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>; 3487 3488 def DFLOADf32 : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src), 3489 "#DFLOADf32", 3490 [(set f32:$XT, (load iaddrX4:$src))]>; 3491 def DFLOADf64 : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src), 3492 "#DFLOADf64", 3493 [(set f64:$XT, (load iaddrX4:$src))]>; 3494 def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst), 3495 "#DFSTOREf32", 3496 [(store f32:$XT, iaddrX4:$dst)]>; 3497 def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst), 3498 "#DFSTOREf64", 3499 [(store f64:$XT, iaddrX4:$dst)]>; 3500 3501 def : Pat<(f64 (extloadf32 iaddrX4:$src)), 3502 (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>; 3503 def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))), 3504 (f32 (DFLOADf32 iaddrX4:$src))>; 3505 3506 def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)), 3507 (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>; 3508 def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)), 3509 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>; 3510 3511 let AddedComplexity = 400 in { 3512 // The following pseudoinstructions are used to ensure the utilization 3513 // of all 64 VSX registers. 3514 let Predicates = [IsLittleEndian, HasP9Vector] in { 3515 def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))), 3516 (v2i64 (XXPERMDIs 3517 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>; 3518 def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))), 3519 (v2i64 (XXPERMDIs 3520 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>; 3521 3522 def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))), 3523 (v2f64 (XXPERMDIs 3524 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>; 3525 def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))), 3526 (v2f64 (XXPERMDIs 3527 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>; 3528 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src), 3529 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3530 sub_64), xaddrX4:$src)>; 3531 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src), 3532 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3533 sub_64), xaddrX4:$src)>; 3534 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src), 3535 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3536 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src), 3537 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3538 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src), 3539 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3540 sub_64), iaddrX4:$src)>; 3541 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src), 3542 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3543 iaddrX4:$src)>; 3544 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src), 3545 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3546 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src), 3547 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3548 } // IsLittleEndian, HasP9Vector 3549 3550 let Predicates = [IsBigEndian, HasP9Vector] in { 3551 def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))), 3552 (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>; 3553 def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))), 3554 (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>; 3555 3556 def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))), 3557 (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>; 3558 def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))), 3559 (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>; 3560 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src), 3561 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3562 sub_64), xaddrX4:$src)>; 3563 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src), 3564 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3565 sub_64), xaddrX4:$src)>; 3566 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src), 3567 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3568 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src), 3569 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3570 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src), 3571 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3572 sub_64), iaddrX4:$src)>; 3573 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src), 3574 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3575 sub_64), iaddrX4:$src)>; 3576 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src), 3577 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3578 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src), 3579 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3580 } // IsBigEndian, HasP9Vector 3581 } 3582 3583 let Predicates = [IsBigEndian, HasP9Vector] in { 3584 3585 // (Un)Signed DWord vector extract -> QP 3586 def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3587 (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3588 def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3589 (f128 (XSCVSDQP 3590 (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3591 def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3592 (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3593 def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3594 (f128 (XSCVUDQP 3595 (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3596 3597 // (Un)Signed Word vector extract -> QP 3598 def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))), 3599 (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 3600 foreach Idx = [0,2,3] in { 3601 def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 3602 (f128 (XSCVSDQP (EXTRACT_SUBREG 3603 (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>; 3604 } 3605 foreach Idx = 0-3 in { 3606 def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 3607 (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>; 3608 } 3609 3610 // (Un)Signed HWord vector extract -> QP 3611 foreach Idx = 0-7 in { 3612 def : Pat<(f128 (sint_to_fp 3613 (i32 (sext_inreg 3614 (vector_extract v8i16:$src, Idx), i16)))), 3615 (f128 (XSCVSDQP (EXTRACT_SUBREG 3616 (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)), 3617 sub_64)))>; 3618 // The SDAG adds the `and` since an `i16` is being extracted as an `i32`. 3619 def : Pat<(f128 (uint_to_fp 3620 (and (i32 (vector_extract v8i16:$src, Idx)), 65535))), 3621 (f128 (XSCVUDQP (EXTRACT_SUBREG 3622 (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>; 3623 } 3624 3625 // (Un)Signed Byte vector extract -> QP 3626 foreach Idx = 0-15 in { 3627 def : Pat<(f128 (sint_to_fp 3628 (i32 (sext_inreg (vector_extract v16i8:$src, Idx), 3629 i8)))), 3630 (f128 (XSCVSDQP (EXTRACT_SUBREG 3631 (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>; 3632 def : Pat<(f128 (uint_to_fp 3633 (and (i32 (vector_extract v16i8:$src, Idx)), 255))), 3634 (f128 (XSCVUDQP 3635 (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>; 3636 } 3637 3638 // Unsiged int in vsx register -> QP 3639 def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 3640 (f128 (XSCVUDQP 3641 (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>; 3642 } // IsBigEndian, HasP9Vector 3643 3644 let Predicates = [IsLittleEndian, HasP9Vector] in { 3645 3646 // (Un)Signed DWord vector extract -> QP 3647 def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3648 (f128 (XSCVSDQP 3649 (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3650 def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3651 (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3652 def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3653 (f128 (XSCVUDQP 3654 (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3655 def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3656 (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3657 3658 // (Un)Signed Word vector extract -> QP 3659 foreach Idx = [[0,3],[1,2],[3,0]] in { 3660 def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 3661 (f128 (XSCVSDQP (EXTRACT_SUBREG 3662 (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)), 3663 sub_64)))>; 3664 } 3665 def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))), 3666 (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 3667 3668 foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in { 3669 def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 3670 (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>; 3671 } 3672 3673 // (Un)Signed HWord vector extract -> QP 3674 // The Nested foreach lists identifies the vector element and corresponding 3675 // register byte location. 3676 foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in { 3677 def : Pat<(f128 (sint_to_fp 3678 (i32 (sext_inreg 3679 (vector_extract v8i16:$src, !head(Idx)), i16)))), 3680 (f128 (XSCVSDQP 3681 (EXTRACT_SUBREG (VEXTSH2D 3682 (VEXTRACTUH !head(!tail(Idx)), $src)), 3683 sub_64)))>; 3684 def : Pat<(f128 (uint_to_fp 3685 (and (i32 (vector_extract v8i16:$src, !head(Idx))), 3686 65535))), 3687 (f128 (XSCVUDQP (EXTRACT_SUBREG 3688 (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>; 3689 } 3690 3691 // (Un)Signed Byte vector extract -> QP 3692 foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7], 3693 [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in { 3694 def : Pat<(f128 (sint_to_fp 3695 (i32 (sext_inreg 3696 (vector_extract v16i8:$src, !head(Idx)), i8)))), 3697 (f128 (XSCVSDQP 3698 (EXTRACT_SUBREG 3699 (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)), 3700 sub_64)))>; 3701 def : Pat<(f128 (uint_to_fp 3702 (and (i32 (vector_extract v16i8:$src, !head(Idx))), 3703 255))), 3704 (f128 (XSCVUDQP 3705 (EXTRACT_SUBREG 3706 (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; 3707 } 3708 3709 // Unsiged int in vsx register -> QP 3710 def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 3711 (f128 (XSCVUDQP 3712 (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>; 3713 } // IsLittleEndian, HasP9Vector 3714 3715 // Convert (Un)Signed DWord in memory -> QP 3716 def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))), 3717 (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>; 3718 def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))), 3719 (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>; 3720 def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))), 3721 (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>; 3722 def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))), 3723 (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>; 3724 3725 // Convert Unsigned HWord in memory -> QP 3726 def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)), 3727 (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>; 3728 3729 // Convert Unsigned Byte in memory -> QP 3730 def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)), 3731 (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>; 3732 3733 // Truncate & Convert QP -> (Un)Signed (D)Word. 3734 def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>; 3735 def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>; 3736 def : Pat<(i32 (fp_to_sint f128:$src)), 3737 (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>; 3738 def : Pat<(i32 (fp_to_uint f128:$src)), 3739 (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>; 3740 3741 // Instructions for store(fptosi). 3742 // The 8-byte version is repeated here due to availability of D-Form STXSD. 3743 def : Pat<(PPCstore_scal_int_from_vsr 3744 (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8), 3745 (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 3746 xaddrX4:$dst)>; 3747 def : Pat<(PPCstore_scal_int_from_vsr 3748 (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8), 3749 (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 3750 iaddrX4:$dst)>; 3751 def : Pat<(PPCstore_scal_int_from_vsr 3752 (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4), 3753 (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3754 def : Pat<(PPCstore_scal_int_from_vsr 3755 (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2), 3756 (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3757 def : Pat<(PPCstore_scal_int_from_vsr 3758 (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1), 3759 (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3760 def : Pat<(PPCstore_scal_int_from_vsr 3761 (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8), 3762 (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>; 3763 def : Pat<(PPCstore_scal_int_from_vsr 3764 (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8), 3765 (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>; 3766 def : Pat<(PPCstore_scal_int_from_vsr 3767 (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2), 3768 (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>; 3769 def : Pat<(PPCstore_scal_int_from_vsr 3770 (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1), 3771 (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>; 3772 3773 // Instructions for store(fptoui). 3774 def : Pat<(PPCstore_scal_int_from_vsr 3775 (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8), 3776 (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 3777 xaddrX4:$dst)>; 3778 def : Pat<(PPCstore_scal_int_from_vsr 3779 (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8), 3780 (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 3781 iaddrX4:$dst)>; 3782 def : Pat<(PPCstore_scal_int_from_vsr 3783 (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4), 3784 (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3785 def : Pat<(PPCstore_scal_int_from_vsr 3786 (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2), 3787 (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3788 def : Pat<(PPCstore_scal_int_from_vsr 3789 (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1), 3790 (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3791 def : Pat<(PPCstore_scal_int_from_vsr 3792 (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8), 3793 (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>; 3794 def : Pat<(PPCstore_scal_int_from_vsr 3795 (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8), 3796 (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>; 3797 def : Pat<(PPCstore_scal_int_from_vsr 3798 (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2), 3799 (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>; 3800 def : Pat<(PPCstore_scal_int_from_vsr 3801 (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1), 3802 (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>; 3803 3804 // Round & Convert QP -> DP/SP 3805 def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>; 3806 def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>; 3807 3808 // Convert SP -> QP 3809 def : Pat<(f128 (fpextend f32:$src)), 3810 (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>; 3811 3812 def : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)), 3813 (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC), 3814 (COPY_TO_REGCLASS $XB, VSSRC)), 3815 VSSRC))>; 3816 def : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)), 3817 (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC), 3818 (COPY_TO_REGCLASS $XB, VSSRC)), 3819 VSSRC))>; 3820 3821} // end HasP9Vector, AddedComplexity 3822 3823let AddedComplexity = 400 in { 3824 let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in { 3825 def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)), 3826 (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 3827 } 3828 let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in { 3829 def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)), 3830 (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 3831 } 3832} 3833 3834let Predicates = [HasP9Vector], hasSideEffects = 0 in { 3835 let mayStore = 1 in { 3836 def SPILLTOVSR_STX : PseudoXFormMemOp<(outs), 3837 (ins spilltovsrrc:$XT, memrr:$dst), 3838 "#SPILLTOVSR_STX", []>; 3839 def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst), 3840 "#SPILLTOVSR_ST", []>; 3841 } 3842 let mayLoad = 1 in { 3843 def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT), 3844 (ins memrr:$src), 3845 "#SPILLTOVSR_LDX", []>; 3846 def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src), 3847 "#SPILLTOVSR_LD", []>; 3848 3849 } 3850} 3851// Integer extend helper dags 32 -> 64 3852def AnyExts { 3853 dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32); 3854 dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32); 3855 dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32); 3856 dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32); 3857} 3858 3859def DblToFlt { 3860 dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0)))); 3861 dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1)))); 3862 dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0)))); 3863 dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1)))); 3864} 3865 3866def ExtDbl { 3867 dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0)))))); 3868 dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1)))))); 3869 dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0)))))); 3870 dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1)))))); 3871 dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0)))))); 3872 dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1)))))); 3873 dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0)))))); 3874 dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1)))))); 3875} 3876 3877def ByteToWord { 3878 dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8)); 3879 dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8)); 3880 dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8)); 3881 dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8)); 3882 dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8)); 3883 dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8)); 3884 dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8)); 3885 dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8)); 3886} 3887 3888def ByteToDWord { 3889 dag LE_A0 = (i64 (sext_inreg 3890 (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8)); 3891 dag LE_A1 = (i64 (sext_inreg 3892 (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8)); 3893 dag BE_A0 = (i64 (sext_inreg 3894 (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8)); 3895 dag BE_A1 = (i64 (sext_inreg 3896 (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8)); 3897} 3898 3899def HWordToWord { 3900 dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16)); 3901 dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16)); 3902 dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16)); 3903 dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16)); 3904 dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16)); 3905 dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16)); 3906 dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16)); 3907 dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16)); 3908} 3909 3910def HWordToDWord { 3911 dag LE_A0 = (i64 (sext_inreg 3912 (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16)); 3913 dag LE_A1 = (i64 (sext_inreg 3914 (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16)); 3915 dag BE_A0 = (i64 (sext_inreg 3916 (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16)); 3917 dag BE_A1 = (i64 (sext_inreg 3918 (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16)); 3919} 3920 3921def WordToDWord { 3922 dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0)))); 3923 dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2)))); 3924 dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1)))); 3925 dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3)))); 3926} 3927 3928def FltToIntLoad { 3929 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A))))); 3930} 3931def FltToUIntLoad { 3932 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A))))); 3933} 3934def FltToLongLoad { 3935 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A))))); 3936} 3937def FltToLongLoadP9 { 3938 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A))))); 3939} 3940def FltToULongLoad { 3941 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A))))); 3942} 3943def FltToULongLoadP9 { 3944 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A))))); 3945} 3946def FltToLong { 3947 dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A))))); 3948} 3949def FltToULong { 3950 dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A))))); 3951} 3952def DblToInt { 3953 dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A)))); 3954 dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B)))); 3955 dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C)))); 3956 dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D)))); 3957} 3958def DblToUInt { 3959 dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A)))); 3960 dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B)))); 3961 dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C)))); 3962 dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D)))); 3963} 3964def DblToLong { 3965 dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A)))); 3966} 3967def DblToULong { 3968 dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A)))); 3969} 3970def DblToIntLoad { 3971 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A))))); 3972} 3973def DblToIntLoadP9 { 3974 dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A))))); 3975} 3976def DblToUIntLoad { 3977 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A))))); 3978} 3979def DblToUIntLoadP9 { 3980 dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A))))); 3981} 3982def DblToLongLoad { 3983 dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A))))); 3984} 3985def DblToULongLoad { 3986 dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A))))); 3987} 3988 3989// FP load dags (for f32 -> v4f32) 3990def LoadFP { 3991 dag A = (f32 (load xoaddr:$A)); 3992 dag B = (f32 (load xoaddr:$B)); 3993 dag C = (f32 (load xoaddr:$C)); 3994 dag D = (f32 (load xoaddr:$D)); 3995} 3996 3997// FP merge dags (for f32 -> v4f32) 3998def MrgFP { 3999 dag LD32A = (COPY_TO_REGCLASS (LIWZX xoaddr:$A), VSRC); 4000 dag LD32B = (COPY_TO_REGCLASS (LIWZX xoaddr:$B), VSRC); 4001 dag LD32C = (COPY_TO_REGCLASS (LIWZX xoaddr:$C), VSRC); 4002 dag LD32D = (COPY_TO_REGCLASS (LIWZX xoaddr:$D), VSRC); 4003 dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC), 4004 (COPY_TO_REGCLASS $C, VSRC), 0)); 4005 dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC), 4006 (COPY_TO_REGCLASS $D, VSRC), 0)); 4007 dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0)); 4008 dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3)); 4009 dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0)); 4010 dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3)); 4011} 4012 4013// Word-element merge dags - conversions from f64 to i32 merged into vectors. 4014def MrgWords { 4015 // For big endian, we merge low and hi doublewords (A, B). 4016 dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0)); 4017 dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3)); 4018 dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1)); 4019 dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0)); 4020 dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1)); 4021 dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0)); 4022 4023 // For little endian, we merge low and hi doublewords (B, A). 4024 dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0)); 4025 dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3)); 4026 dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1)); 4027 dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0)); 4028 dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1)); 4029 dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0)); 4030 4031 // For big endian, we merge hi doublewords of (A, C) and (B, D), convert 4032 // then merge. 4033 dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC), 4034 (COPY_TO_REGCLASS f64:$C, VSRC), 0)); 4035 dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC), 4036 (COPY_TO_REGCLASS f64:$D, VSRC), 0)); 4037 dag CVACS = (v4i32 (XVCVDPSXWS AC)); 4038 dag CVBDS = (v4i32 (XVCVDPSXWS BD)); 4039 dag CVACU = (v4i32 (XVCVDPUXWS AC)); 4040 dag CVBDU = (v4i32 (XVCVDPUXWS BD)); 4041 4042 // For little endian, we merge hi doublewords of (D, B) and (C, A), convert 4043 // then merge. 4044 dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC), 4045 (COPY_TO_REGCLASS f64:$B, VSRC), 0)); 4046 dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC), 4047 (COPY_TO_REGCLASS f64:$A, VSRC), 0)); 4048 dag CVDBS = (v4i32 (XVCVDPSXWS DB)); 4049 dag CVCAS = (v4i32 (XVCVDPSXWS CA)); 4050 dag CVDBU = (v4i32 (XVCVDPUXWS DB)); 4051 dag CVCAU = (v4i32 (XVCVDPUXWS CA)); 4052} 4053 4054// Patterns for BUILD_VECTOR nodes. 4055let AddedComplexity = 400 in { 4056 4057 let Predicates = [HasVSX] in { 4058 // Build vectors of floating point converted to i32. 4059 def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A, 4060 DblToInt.A, DblToInt.A)), 4061 (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>; 4062 def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A, 4063 DblToUInt.A, DblToUInt.A)), 4064 (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>; 4065 def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)), 4066 (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 4067 (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>; 4068 def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)), 4069 (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 4070 (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>; 4071 def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 4072 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4073 (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>; 4074 def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 4075 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4076 (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>; 4077 def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)), 4078 (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>; 4079 def : Pat<(v2f64 (PPCldsplat xoaddr:$A)), 4080 (v2f64 (LXVDSX xoaddr:$A))>; 4081 def : Pat<(v2i64 (PPCldsplat xoaddr:$A)), 4082 (v2i64 (LXVDSX xoaddr:$A))>; 4083 4084 // Build vectors of floating point converted to i64. 4085 def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)), 4086 (v2i64 (XXPERMDIs 4087 (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>; 4088 def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)), 4089 (v2i64 (XXPERMDIs 4090 (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>; 4091 def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)), 4092 (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>; 4093 def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)), 4094 (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>; 4095 } 4096 4097 let Predicates = [HasVSX, NoP9Vector] in { 4098 // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads). 4099 def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)), 4100 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4101 (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>; 4102 def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)), 4103 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4104 (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>; 4105 def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)), 4106 (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 4107 (XFLOADf32 xoaddr:$A), VSFRC)), 0))>; 4108 def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)), 4109 (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 4110 (XFLOADf32 xoaddr:$A), VSFRC)), 0))>; 4111 } 4112 4113 let Predicates = [IsBigEndian, HasP8Vector] in { 4114 def : Pat<DWToSPExtractConv.BVU, 4115 (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3), 4116 (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>; 4117 def : Pat<DWToSPExtractConv.BVS, 4118 (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3), 4119 (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>; 4120 def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src), 4121 (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4122 def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src), 4123 (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4124 4125 // Elements in a register on a BE system are in order <0, 1, 2, 3>. 4126 // The store instructions store the second word from the left. 4127 // So to align element zero, we need to modulo-left-shift by 3 words. 4128 // Similar logic applies for elements 2 and 3. 4129 foreach Idx = [ [0,3], [2,1], [3,2] ] in { 4130 def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src), 4131 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 4132 sub_64), xoaddr:$src)>; 4133 def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src), 4134 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 4135 sub_64), xoaddr:$src)>; 4136 } 4137 } 4138 4139 let Predicates = [HasP8Vector, IsBigEndian, NoP9Vector] in { 4140 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src), 4141 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4142 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src), 4143 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4144 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src), 4145 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 4146 xoaddr:$src)>; 4147 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src), 4148 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 4149 xoaddr:$src)>; 4150 } 4151 4152 // Big endian, available on all targets with VSX 4153 let Predicates = [IsBigEndian, HasVSX] in { 4154 def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 4155 (v2f64 (XXPERMDI 4156 (COPY_TO_REGCLASS $A, VSRC), 4157 (COPY_TO_REGCLASS $B, VSRC), 0))>; 4158 // Using VMRGEW to assemble the final vector would be a lower latency 4159 // solution. However, we choose to go with the slightly higher latency 4160 // XXPERMDI for 2 reasons: 4161 // 1. This is likely to occur in unrolled loops where regpressure is high, 4162 // so we want to use the latter as it has access to all 64 VSX registers. 4163 // 2. Using Altivec instructions in this sequence would likely cause the 4164 // allocation of Altivec registers even for the loads which in turn would 4165 // force the use of LXSIWZX for the loads, adding a cycle of latency to 4166 // each of the loads which would otherwise be able to use LFIWZX. 4167 def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)), 4168 (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B), 4169 (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>; 4170 def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)), 4171 (VMRGEW MrgFP.AC, MrgFP.BD)>; 4172 def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 4173 DblToFlt.B0, DblToFlt.B1)), 4174 (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>; 4175 4176 // Convert 4 doubles to a vector of ints. 4177 def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 4178 DblToInt.C, DblToInt.D)), 4179 (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>; 4180 def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 4181 DblToUInt.C, DblToUInt.D)), 4182 (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>; 4183 def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 4184 ExtDbl.B0S, ExtDbl.B1S)), 4185 (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>; 4186 def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 4187 ExtDbl.B0U, ExtDbl.B1U)), 4188 (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>; 4189 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4190 (f64 (fpextend (extractelt v4f32:$A, 1))))), 4191 (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>; 4192 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 4193 (f64 (fpextend (extractelt v4f32:$A, 0))))), 4194 (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)), 4195 (XVCVSPDP (XXMRGHW $A, $A)), 2))>; 4196 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4197 (f64 (fpextend (extractelt v4f32:$A, 2))))), 4198 (v2f64 (XVCVSPDP $A))>; 4199 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 4200 (f64 (fpextend (extractelt v4f32:$A, 3))))), 4201 (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>; 4202 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))), 4203 (f64 (fpextend (extractelt v4f32:$A, 3))))), 4204 (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>; 4205 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 4206 (f64 (fpextend (extractelt v4f32:$A, 2))))), 4207 (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)), 4208 (XVCVSPDP (XXMRGLW $A, $A)), 2))>; 4209 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4210 (f64 (fpextend (extractelt v4f32:$B, 0))))), 4211 (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>; 4212 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 4213 (f64 (fpextend (extractelt v4f32:$B, 3))))), 4214 (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3), 4215 (XXPERMDI $A, $B, 3), 1)))>; 4216 def : Pat<WToDPExtractConv.BV02S, 4217 (v2f64 (XVCVSXWDP $A))>; 4218 def : Pat<WToDPExtractConv.BV13S, 4219 (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 3)))>; 4220 def : Pat<WToDPExtractConv.BV02U, 4221 (v2f64 (XVCVUXWDP $A))>; 4222 def : Pat<WToDPExtractConv.BV13U, 4223 (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 3)))>; 4224 } 4225 4226 let Predicates = [IsLittleEndian, HasP8Vector] in { 4227 def : Pat<DWToSPExtractConv.BVU, 4228 (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3), 4229 (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>; 4230 def : Pat<DWToSPExtractConv.BVS, 4231 (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3), 4232 (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>; 4233 def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src), 4234 (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4235 def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src), 4236 (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4237 4238 // Elements in a register on a LE system are in order <3, 2, 1, 0>. 4239 // The store instructions store the second word from the left. 4240 // So to align element 3, we need to modulo-left-shift by 3 words. 4241 // Similar logic applies for elements 0 and 1. 4242 foreach Idx = [ [0,2], [1,1], [3,3] ] in { 4243 def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src), 4244 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 4245 sub_64), xoaddr:$src)>; 4246 def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src), 4247 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 4248 sub_64), xoaddr:$src)>; 4249 } 4250 } 4251 4252 let Predicates = [HasP8Vector, IsLittleEndian, NoP9Vector] in { 4253 def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src), 4254 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 4255 xoaddr:$src)>; 4256 def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src), 4257 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 4258 xoaddr:$src)>; 4259 def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src), 4260 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4261 def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src), 4262 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 4263 } 4264 4265 let Predicates = [IsLittleEndian, HasVSX] in { 4266 // Little endian, available on all targets with VSX 4267 def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 4268 (v2f64 (XXPERMDI 4269 (COPY_TO_REGCLASS $B, VSRC), 4270 (COPY_TO_REGCLASS $A, VSRC), 0))>; 4271 // Using VMRGEW to assemble the final vector would be a lower latency 4272 // solution. However, we choose to go with the slightly higher latency 4273 // XXPERMDI for 2 reasons: 4274 // 1. This is likely to occur in unrolled loops where regpressure is high, 4275 // so we want to use the latter as it has access to all 64 VSX registers. 4276 // 2. Using Altivec instructions in this sequence would likely cause the 4277 // allocation of Altivec registers even for the loads which in turn would 4278 // force the use of LXSIWZX for the loads, adding a cycle of latency to 4279 // each of the loads which would otherwise be able to use LFIWZX. 4280 def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)), 4281 (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C), 4282 (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>; 4283 def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)), 4284 (VMRGEW MrgFP.AC, MrgFP.BD)>; 4285 def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 4286 DblToFlt.B0, DblToFlt.B1)), 4287 (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>; 4288 4289 // Convert 4 doubles to a vector of ints. 4290 def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 4291 DblToInt.C, DblToInt.D)), 4292 (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>; 4293 def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 4294 DblToUInt.C, DblToUInt.D)), 4295 (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>; 4296 def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 4297 ExtDbl.B0S, ExtDbl.B1S)), 4298 (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>; 4299 def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 4300 ExtDbl.B0U, ExtDbl.B1U)), 4301 (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>; 4302 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4303 (f64 (fpextend (extractelt v4f32:$A, 1))))), 4304 (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>; 4305 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 4306 (f64 (fpextend (extractelt v4f32:$A, 0))))), 4307 (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)), 4308 (XVCVSPDP (XXMRGLW $A, $A)), 2))>; 4309 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4310 (f64 (fpextend (extractelt v4f32:$A, 2))))), 4311 (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>; 4312 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 4313 (f64 (fpextend (extractelt v4f32:$A, 3))))), 4314 (v2f64 (XVCVSPDP $A))>; 4315 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))), 4316 (f64 (fpextend (extractelt v4f32:$A, 3))))), 4317 (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>; 4318 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 4319 (f64 (fpextend (extractelt v4f32:$A, 2))))), 4320 (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)), 4321 (XVCVSPDP (XXMRGHW $A, $A)), 2))>; 4322 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 4323 (f64 (fpextend (extractelt v4f32:$B, 0))))), 4324 (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3), 4325 (XXPERMDI $B, $A, 3), 1)))>; 4326 def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 4327 (f64 (fpextend (extractelt v4f32:$B, 3))))), 4328 (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>; 4329 def : Pat<WToDPExtractConv.BV02S, 4330 (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>; 4331 def : Pat<WToDPExtractConv.BV13S, 4332 (v2f64 (XVCVSXWDP $A))>; 4333 def : Pat<WToDPExtractConv.BV02U, 4334 (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>; 4335 def : Pat<WToDPExtractConv.BV13U, 4336 (v2f64 (XVCVUXWDP $A))>; 4337 } 4338 4339 let Predicates = [HasDirectMove] in { 4340 // Endianness-neutral constant splat on P8 and newer targets. The reason 4341 // for this pattern is that on targets with direct moves, we don't expand 4342 // BUILD_VECTOR nodes for v4i32. 4343 def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A, 4344 immSExt5NonZero:$A, immSExt5NonZero:$A)), 4345 (v4i32 (VSPLTISW imm:$A))>; 4346 } 4347 4348 let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in { 4349 // Big endian integer vectors using direct moves. 4350 def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 4351 (v2i64 (XXPERMDI 4352 (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 4353 (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>; 4354 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4355 (XXPERMDI 4356 (COPY_TO_REGCLASS 4357 (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC), 4358 (COPY_TO_REGCLASS 4359 (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>; 4360 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4361 (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 4362 } 4363 4364 let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in { 4365 // Little endian integer vectors using direct moves. 4366 def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 4367 (v2i64 (XXPERMDI 4368 (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 4369 (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>; 4370 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4371 (XXPERMDI 4372 (COPY_TO_REGCLASS 4373 (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC), 4374 (COPY_TO_REGCLASS 4375 (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>; 4376 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4377 (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 4378 } 4379 4380 let Predicates = [HasP8Vector] in { 4381 def : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))), 4382 (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 4383 def : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))), 4384 (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 4385 def : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))), 4386 (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 4387 def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))), 4388 (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 4389 } 4390 4391 let Predicates = [HasP9Vector] in { 4392 // Endianness-neutral patterns for const splats with ISA 3.0 instructions. 4393 def : Pat<(v4i32 (scalar_to_vector i32:$A)), 4394 (v4i32 (MTVSRWS $A))>; 4395 def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4396 (v4i32 (MTVSRWS $A))>; 4397 def : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4398 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4399 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4400 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4401 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4402 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4403 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 4404 immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)), 4405 (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>; 4406 def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 4407 (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>; 4408 def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 4409 (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>; 4410 def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)), 4411 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4412 (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>; 4413 def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)), 4414 (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4415 (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>; 4416 def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)), 4417 (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 4418 (DFLOADf32 iaddrX4:$A), 4419 VSFRC)), 0))>; 4420 def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)), 4421 (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 4422 (DFLOADf32 iaddrX4:$A), 4423 VSFRC)), 0))>; 4424 def : Pat<(v4f32 (PPCldsplat xoaddr:$A)), 4425 (v4f32 (LXVWSX xoaddr:$A))>; 4426 def : Pat<(v4i32 (PPCldsplat xoaddr:$A)), 4427 (v4i32 (LXVWSX xoaddr:$A))>; 4428 } 4429 4430 let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in { 4431 def : Pat<(i64 (extractelt v2i64:$A, 1)), 4432 (i64 (MFVSRLD $A))>; 4433 // Better way to build integer vectors if we have MTVSRDD. Big endian. 4434 def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)), 4435 (v2i64 (MTVSRDD $rB, $rA))>; 4436 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4437 (MTVSRDD 4438 (RLDIMI AnyExts.B, AnyExts.A, 32, 0), 4439 (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>; 4440 } 4441 4442 let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in { 4443 def : Pat<(i64 (extractelt v2i64:$A, 0)), 4444 (i64 (MFVSRLD $A))>; 4445 // Better way to build integer vectors if we have MTVSRDD. Little endian. 4446 def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)), 4447 (v2i64 (MTVSRDD $rB, $rA))>; 4448 def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4449 (MTVSRDD 4450 (RLDIMI AnyExts.C, AnyExts.D, 32, 0), 4451 (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>; 4452 } 4453 // P9 Altivec instructions that can be used to build vectors. 4454 // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete 4455 // with complexities of existing build vector patterns in this file. 4456 let Predicates = [HasP9Altivec, IsLittleEndian] in { 4457 def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)), 4458 (v2i64 (VEXTSW2D $A))>; 4459 def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)), 4460 (v2i64 (VEXTSH2D $A))>; 4461 def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1, 4462 HWordToWord.LE_A2, HWordToWord.LE_A3)), 4463 (v4i32 (VEXTSH2W $A))>; 4464 def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1, 4465 ByteToWord.LE_A2, ByteToWord.LE_A3)), 4466 (v4i32 (VEXTSB2W $A))>; 4467 def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)), 4468 (v2i64 (VEXTSB2D $A))>; 4469 } 4470 4471 let Predicates = [HasP9Altivec, IsBigEndian] in { 4472 def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)), 4473 (v2i64 (VEXTSW2D $A))>; 4474 def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)), 4475 (v2i64 (VEXTSH2D $A))>; 4476 def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1, 4477 HWordToWord.BE_A2, HWordToWord.BE_A3)), 4478 (v4i32 (VEXTSH2W $A))>; 4479 def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1, 4480 ByteToWord.BE_A2, ByteToWord.BE_A3)), 4481 (v4i32 (VEXTSB2W $A))>; 4482 def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)), 4483 (v2i64 (VEXTSB2D $A))>; 4484 } 4485} 4486 4487// Put this P9Altivec related definition here since it's possible to be 4488// selected to VSX instruction xvnegsp, avoid possible undef. 4489let Predicates = [HasP9Altivec] in { 4490 4491 def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))), 4492 (v4i32 (VABSDUW $A, $B))>; 4493 4494 def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))), 4495 (v8i16 (VABSDUH $A, $B))>; 4496 4497 def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))), 4498 (v16i8 (VABSDUB $A, $B))>; 4499 4500 // As PPCVABSD description, the last operand indicates whether do the 4501 // sign bit flip. 4502 def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))), 4503 (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>; 4504} 4505