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