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