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