1//===- TargetSelectionDAG.td - Common code for DAG isels ---*- 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 defines the target-independent interfaces used by SelectionDAG 10// instruction selection generators. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Selection DAG Type Constraint definitions. 16// 17// Note that the semantics of these constraints are hard coded into tblgen. To 18// modify or add constraints, you have to hack tblgen. 19// 20 21class SDTypeConstraint<int opnum> { 22 int OperandNum = opnum; 23} 24 25// SDTCisVT - The specified operand has exactly this VT. 26class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { 27 ValueType VT = vt; 28} 29 30class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>; 31 32// SDTCisInt - The specified operand has integer type. 33class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>; 34 35// SDTCisFP - The specified operand has floating-point type. 36class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>; 37 38// SDTCisVec - The specified operand has a vector type. 39class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>; 40 41// SDTCisSameAs - The two specified operands have identical types. 42class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 43 int OtherOperandNum = OtherOp; 44} 45 46// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is 47// smaller than the 'Other' operand. 48class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 49 int OtherOperandNum = OtherOp; 50} 51 52class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{ 53 int BigOperandNum = BigOp; 54} 55 56/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same 57/// type as the element type of OtherOp, which is a vector type. 58class SDTCisEltOfVec<int ThisOp, int OtherOp> 59 : SDTypeConstraint<ThisOp> { 60 int OtherOpNum = OtherOp; 61} 62 63/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type 64/// with length less that of OtherOp, which is a vector type. 65class SDTCisSubVecOfVec<int ThisOp, int OtherOp> 66 : SDTypeConstraint<ThisOp> { 67 int OtherOpNum = OtherOp; 68} 69 70// SDTCVecEltisVT - The specified operand is vector type with element type 71// of VT. 72class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { 73 ValueType VT = vt; 74} 75 76// SDTCisSameNumEltsAs - The two specified operands have identical number 77// of elements. 78class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 79 int OtherOperandNum = OtherOp; 80} 81 82// SDTCisSameSizeAs - The two specified operands have identical size. 83class SDTCisSameSizeAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 84 int OtherOperandNum = OtherOp; 85} 86 87//===----------------------------------------------------------------------===// 88// Selection DAG Type Profile definitions. 89// 90// These use the constraints defined above to describe the type requirements of 91// the various nodes. These are not hard coded into tblgen, allowing targets to 92// add their own if needed. 93// 94 95// SDTypeProfile - This profile describes the type requirements of a Selection 96// DAG node. 97class SDTypeProfile<int numresults, int numoperands, 98 list<SDTypeConstraint> constraints> { 99 int NumResults = numresults; 100 int NumOperands = numoperands; 101 list<SDTypeConstraint> Constraints = constraints; 102} 103 104// Builtin profiles. 105def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. 106def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. 107def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. 108def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. 109def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. 110def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert. 111 112def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. 113 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> 114]>; 115def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl 116 SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> 117]>; 118def SDTIntShiftDOp: SDTypeProfile<1, 3, [ // fshl, fshr 119 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3> 120]>; 121def SDTIntSatNoShOp : SDTypeProfile<1, 2, [ // ssat with no shift 122 SDTCisSameAs<0, 1>, SDTCisInt<2> 123]>; 124def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem 125 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0> 126]>; 127def SDTIntScaledBinOp : SDTypeProfile<1, 3, [ // smulfix, sdivfix, etc 128 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3> 129]>; 130 131def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. 132 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> 133]>; 134def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. 135 SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> 136]>; 137def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. 138 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> 139]>; 140def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // bitreverse 141 SDTCisSameAs<0, 1>, SDTCisInt<0> 142]>; 143def SDTIntBitCountUnaryOp : SDTypeProfile<1, 1, [ // ctlz, cttz 144 SDTCisInt<0>, SDTCisInt<1> 145]>; 146def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext 147 SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> 148]>; 149def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc 150 SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> 151]>; 152def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc 153 SDTCisSameAs<0, 1>, SDTCisFP<0> 154]>; 155def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround 156 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> 157]>; 158def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend 159 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> 160]>; 161def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp 162 SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1> 163]>; 164def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int 165 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1> 166]>; 167def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg 168 SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, 169 SDTCisVTSmallerThanOp<2, 1> 170]>; 171def SDTExtInvec : SDTypeProfile<1, 1, [ // sext_invec 172 SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>, 173 SDTCisOpSmallerThanOp<1, 0> 174]>; 175 176def SDTSetCC : SDTypeProfile<1, 3, [ // setcc 177 SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> 178]>; 179 180def SDTSelect : SDTypeProfile<1, 3, [ // select 181 SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> 182]>; 183 184def SDTVSelect : SDTypeProfile<1, 3, [ // vselect 185 SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> 186]>; 187 188def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc 189 SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, 190 SDTCisVT<5, OtherVT> 191]>; 192 193def SDTBr : SDTypeProfile<0, 1, [ // br 194 SDTCisVT<0, OtherVT> 195]>; 196 197def SDTBrCC : SDTypeProfile<0, 4, [ // brcc 198 SDTCisVT<0, OtherVT>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> 199]>; 200 201def SDTBrcond : SDTypeProfile<0, 2, [ // brcond 202 SDTCisInt<0>, SDTCisVT<1, OtherVT> 203]>; 204 205def SDTBrind : SDTypeProfile<0, 1, [ // brind 206 SDTCisPtrTy<0> 207]>; 208 209def SDTCatchret : SDTypeProfile<0, 2, [ // catchret 210 SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT> 211]>; 212 213def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap 214 215def SDTLoad : SDTypeProfile<1, 1, [ // load 216 SDTCisPtrTy<1> 217]>; 218 219def SDTStore : SDTypeProfile<0, 2, [ // store 220 SDTCisPtrTy<1> 221]>; 222 223def SDTIStore : SDTypeProfile<1, 3, [ // indexed store 224 SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> 225]>; 226 227def SDTMaskedStore: SDTypeProfile<0, 4, [ // masked store 228 SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameNumEltsAs<0, 3> 229]>; 230 231def SDTMaskedLoad: SDTypeProfile<1, 4, [ // masked load 232 SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameAs<0, 4>, 233 SDTCisSameNumEltsAs<0, 3> 234]>; 235 236def SDTVecShuffle : SDTypeProfile<1, 2, [ 237 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> 238]>; 239def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract 240 SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> 241]>; 242def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert 243 SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> 244]>; 245def SDTVecReduce : SDTypeProfile<1, 1, [ // vector reduction 246 SDTCisInt<0>, SDTCisVec<1> 247]>; 248 249def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract 250 SDTCisSubVecOfVec<0,1>, SDTCisInt<2> 251]>; 252def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert 253 SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> 254]>; 255 256def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch 257 SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> 258]>; 259 260def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barrier 261 SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, 262 SDTCisInt<0> 263]>; 264def SDTAtomicFence : SDTypeProfile<0, 2, [ 265 SDTCisSameAs<0,1>, SDTCisPtrTy<0> 266]>; 267def SDTAtomic3 : SDTypeProfile<1, 3, [ 268 SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> 269]>; 270def SDTAtomic2 : SDTypeProfile<1, 2, [ 271 SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> 272]>; 273 274def SDTFPAtomic2 : SDTypeProfile<1, 2, [ 275 SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1> 276]>; 277 278def SDTAtomicStore : SDTypeProfile<0, 2, [ 279 SDTCisPtrTy<0>, SDTCisInt<1> 280]>; 281def SDTAtomicLoad : SDTypeProfile<1, 1, [ 282 SDTCisInt<0>, SDTCisPtrTy<1> 283]>; 284 285def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su 286 SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> 287]>; 288 289class SDCallSeqStart<list<SDTypeConstraint> constraints> : 290 SDTypeProfile<0, 2, constraints>; 291class SDCallSeqEnd<list<SDTypeConstraint> constraints> : 292 SDTypeProfile<0, 2, constraints>; 293 294//===----------------------------------------------------------------------===// 295// Selection DAG Node definitions. 296// 297class SDNode<string opcode, SDTypeProfile typeprof, 298 list<SDNodeProperty> props = [], string sdclass = "SDNode"> 299 : SDPatternOperator { 300 string Opcode = opcode; 301 string SDClass = sdclass; 302 let Properties = props; 303 SDTypeProfile TypeProfile = typeprof; 304} 305 306// Special TableGen-recognized dag nodes 307def set; 308def implicit; 309def node; 310def srcvalue; 311 312def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; 313def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">; 314def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; 315def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; 316def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; 317def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; 318def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; 319def vscale : SDNode<"ISD::VSCALE" , SDTIntUnaryOp, []>; 320def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], 321 "GlobalAddressSDNode">; 322def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], 323 "GlobalAddressSDNode">; 324def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], 325 "GlobalAddressSDNode">; 326def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], 327 "GlobalAddressSDNode">; 328def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], 329 "ConstantPoolSDNode">; 330def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], 331 "ConstantPoolSDNode">; 332def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], 333 "JumpTableSDNode">; 334def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], 335 "JumpTableSDNode">; 336def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], 337 "FrameIndexSDNode">; 338def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], 339 "FrameIndexSDNode">; 340def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], 341 "ExternalSymbolSDNode">; 342def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], 343 "ExternalSymbolSDNode">; 344def mcsym: SDNode<"ISD::MCSymbol", SDTPtrLeaf, [], "MCSymbolSDNode">; 345def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [], 346 "BlockAddressSDNode">; 347def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [], 348 "BlockAddressSDNode">; 349 350def add : SDNode<"ISD::ADD" , SDTIntBinOp , 351 [SDNPCommutative, SDNPAssociative]>; 352def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; 353def mul : SDNode<"ISD::MUL" , SDTIntBinOp, 354 [SDNPCommutative, SDNPAssociative]>; 355def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; 356def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; 357def smullohi : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; 358def umullohi : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; 359def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; 360def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; 361def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; 362def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; 363def sdivrem : SDNode<"ISD::SDIVREM" , SDTIntBinHiLoOp>; 364def udivrem : SDNode<"ISD::UDIVREM" , SDTIntBinHiLoOp>; 365def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; 366def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; 367def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; 368def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; 369def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; 370def fshl : SDNode<"ISD::FSHL" , SDTIntShiftDOp>; 371def fshr : SDNode<"ISD::FSHR" , SDTIntShiftDOp>; 372def and : SDNode<"ISD::AND" , SDTIntBinOp, 373 [SDNPCommutative, SDNPAssociative]>; 374def or : SDNode<"ISD::OR" , SDTIntBinOp, 375 [SDNPCommutative, SDNPAssociative]>; 376def xor : SDNode<"ISD::XOR" , SDTIntBinOp, 377 [SDNPCommutative, SDNPAssociative]>; 378def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, 379 [SDNPCommutative, SDNPOutGlue]>; 380def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, 381 [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>; 382def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, 383 [SDNPOutGlue]>; 384def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, 385 [SDNPOutGlue, SDNPInGlue]>; 386def smin : SDNode<"ISD::SMIN" , SDTIntBinOp, 387 [SDNPCommutative, SDNPAssociative]>; 388def smax : SDNode<"ISD::SMAX" , SDTIntBinOp, 389 [SDNPCommutative, SDNPAssociative]>; 390def umin : SDNode<"ISD::UMIN" , SDTIntBinOp, 391 [SDNPCommutative, SDNPAssociative]>; 392def umax : SDNode<"ISD::UMAX" , SDTIntBinOp, 393 [SDNPCommutative, SDNPAssociative]>; 394 395def saddsat : SDNode<"ISD::SADDSAT" , SDTIntBinOp, [SDNPCommutative]>; 396def uaddsat : SDNode<"ISD::UADDSAT" , SDTIntBinOp, [SDNPCommutative]>; 397def ssubsat : SDNode<"ISD::SSUBSAT" , SDTIntBinOp>; 398def usubsat : SDNode<"ISD::USUBSAT" , SDTIntBinOp>; 399 400def smulfix : SDNode<"ISD::SMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>; 401def smulfixsat : SDNode<"ISD::SMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>; 402def umulfix : SDNode<"ISD::UMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>; 403def umulfixsat : SDNode<"ISD::UMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>; 404def sdivfix : SDNode<"ISD::SDIVFIX" , SDTIntScaledBinOp>; 405def sdivfixsat : SDNode<"ISD::SDIVFIXSAT", SDTIntScaledBinOp>; 406def udivfix : SDNode<"ISD::UDIVFIX" , SDTIntScaledBinOp>; 407def udivfixsat : SDNode<"ISD::UDIVFIXSAT", SDTIntScaledBinOp>; 408 409def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; 410def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>; 411def zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>; 412 413def abs : SDNode<"ISD::ABS" , SDTIntUnaryOp>; 414def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>; 415def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; 416def ctlz : SDNode<"ISD::CTLZ" , SDTIntBitCountUnaryOp>; 417def cttz : SDNode<"ISD::CTTZ" , SDTIntBitCountUnaryOp>; 418def ctpop : SDNode<"ISD::CTPOP" , SDTIntBitCountUnaryOp>; 419def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>; 420def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>; 421def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; 422def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; 423def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; 424def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; 425def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>; 426def addrspacecast : SDNode<"ISD::ADDRSPACECAST", SDTUnaryOp>; 427def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; 428def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; 429 430def vecreduce_add : SDNode<"ISD::VECREDUCE_ADD", SDTVecReduce>; 431def vecreduce_smax : SDNode<"ISD::VECREDUCE_SMAX", SDTVecReduce>; 432def vecreduce_umax : SDNode<"ISD::VECREDUCE_UMAX", SDTVecReduce>; 433def vecreduce_smin : SDNode<"ISD::VECREDUCE_SMIN", SDTVecReduce>; 434def vecreduce_umin : SDNode<"ISD::VECREDUCE_UMIN", SDTVecReduce>; 435 436def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; 437def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; 438def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; 439def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; 440def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; 441def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>; 442def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp>; 443def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; 444def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp, 445 [SDNPCommutative, SDNPAssociative]>; 446def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp, 447 [SDNPCommutative, SDNPAssociative]>; 448def fminnum_ieee : SDNode<"ISD::FMINNUM_IEEE", SDTFPBinOp, 449 [SDNPCommutative]>; 450def fmaxnum_ieee : SDNode<"ISD::FMAXNUM_IEEE", SDTFPBinOp, 451 [SDNPCommutative]>; 452def fminimum : SDNode<"ISD::FMINIMUM" , SDTFPBinOp, 453 [SDNPCommutative, SDNPAssociative]>; 454def fmaximum : SDNode<"ISD::FMAXIMUM" , SDTFPBinOp, 455 [SDNPCommutative, SDNPAssociative]>; 456def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; 457def fcanonicalize : SDNode<"ISD::FCANONICALIZE", SDTFPUnaryOp>; 458def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; 459def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; 460def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; 461def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; 462def fexp2 : SDNode<"ISD::FEXP2" , SDTFPUnaryOp>; 463def fpow : SDNode<"ISD::FPOW" , SDTFPBinOp>; 464def flog2 : SDNode<"ISD::FLOG2" , SDTFPUnaryOp>; 465def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; 466def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; 467def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; 468def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; 469def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; 470def fround : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; 471 472def lround : SDNode<"ISD::LROUND" , SDTFPToIntOp>; 473def llround : SDNode<"ISD::LLROUND" , SDTFPToIntOp>; 474def lrint : SDNode<"ISD::LRINT" , SDTFPToIntOp>; 475def llrint : SDNode<"ISD::LLRINT" , SDTFPToIntOp>; 476 477def fpround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; 478def fpextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; 479def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; 480 481def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; 482def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; 483def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; 484def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; 485def f16_to_fp : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>; 486def fp_to_f16 : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>; 487 488def strict_fadd : SDNode<"ISD::STRICT_FADD", 489 SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>; 490def strict_fsub : SDNode<"ISD::STRICT_FSUB", 491 SDTFPBinOp, [SDNPHasChain]>; 492def strict_fmul : SDNode<"ISD::STRICT_FMUL", 493 SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>; 494def strict_fdiv : SDNode<"ISD::STRICT_FDIV", 495 SDTFPBinOp, [SDNPHasChain]>; 496def strict_frem : SDNode<"ISD::STRICT_FREM", 497 SDTFPBinOp, [SDNPHasChain]>; 498def strict_fma : SDNode<"ISD::STRICT_FMA", 499 SDTFPTernaryOp, [SDNPHasChain]>; 500def strict_fsqrt : SDNode<"ISD::STRICT_FSQRT", 501 SDTFPUnaryOp, [SDNPHasChain]>; 502def strict_fsin : SDNode<"ISD::STRICT_FSIN", 503 SDTFPUnaryOp, [SDNPHasChain]>; 504def strict_fcos : SDNode<"ISD::STRICT_FCOS", 505 SDTFPUnaryOp, [SDNPHasChain]>; 506def strict_fexp2 : SDNode<"ISD::STRICT_FEXP2", 507 SDTFPUnaryOp, [SDNPHasChain]>; 508def strict_fpow : SDNode<"ISD::STRICT_FPOW", 509 SDTFPBinOp, [SDNPHasChain]>; 510def strict_flog2 : SDNode<"ISD::STRICT_FLOG2", 511 SDTFPUnaryOp, [SDNPHasChain]>; 512def strict_frint : SDNode<"ISD::STRICT_FRINT", 513 SDTFPUnaryOp, [SDNPHasChain]>; 514def strict_lrint : SDNode<"ISD::STRICT_LRINT", 515 SDTFPToIntOp, [SDNPHasChain]>; 516def strict_llrint : SDNode<"ISD::STRICT_LLRINT", 517 SDTFPToIntOp, [SDNPHasChain]>; 518def strict_fnearbyint : SDNode<"ISD::STRICT_FNEARBYINT", 519 SDTFPUnaryOp, [SDNPHasChain]>; 520def strict_fceil : SDNode<"ISD::STRICT_FCEIL", 521 SDTFPUnaryOp, [SDNPHasChain]>; 522def strict_ffloor : SDNode<"ISD::STRICT_FFLOOR", 523 SDTFPUnaryOp, [SDNPHasChain]>; 524def strict_lround : SDNode<"ISD::STRICT_LROUND", 525 SDTFPToIntOp, [SDNPHasChain]>; 526def strict_llround : SDNode<"ISD::STRICT_LLROUND", 527 SDTFPToIntOp, [SDNPHasChain]>; 528def strict_fround : SDNode<"ISD::STRICT_FROUND", 529 SDTFPUnaryOp, [SDNPHasChain]>; 530def strict_ftrunc : SDNode<"ISD::STRICT_FTRUNC", 531 SDTFPUnaryOp, [SDNPHasChain]>; 532def strict_fminnum : SDNode<"ISD::STRICT_FMINNUM", 533 SDTFPBinOp, [SDNPHasChain, 534 SDNPCommutative, SDNPAssociative]>; 535def strict_fmaxnum : SDNode<"ISD::STRICT_FMAXNUM", 536 SDTFPBinOp, [SDNPHasChain, 537 SDNPCommutative, SDNPAssociative]>; 538def strict_fminimum : SDNode<"ISD::STRICT_FMINIMUM", 539 SDTFPBinOp, [SDNPHasChain, 540 SDNPCommutative, SDNPAssociative]>; 541def strict_fmaximum : SDNode<"ISD::STRICT_FMAXIMUM", 542 SDTFPBinOp, [SDNPHasChain, 543 SDNPCommutative, SDNPAssociative]>; 544def strict_fpround : SDNode<"ISD::STRICT_FP_ROUND", 545 SDTFPRoundOp, [SDNPHasChain]>; 546def strict_fpextend : SDNode<"ISD::STRICT_FP_EXTEND", 547 SDTFPExtendOp, [SDNPHasChain]>; 548def strict_fp_to_sint : SDNode<"ISD::STRICT_FP_TO_SINT", 549 SDTFPToIntOp, [SDNPHasChain]>; 550def strict_fp_to_uint : SDNode<"ISD::STRICT_FP_TO_UINT", 551 SDTFPToIntOp, [SDNPHasChain]>; 552def strict_sint_to_fp : SDNode<"ISD::STRICT_SINT_TO_FP", 553 SDTIntToFPOp, [SDNPHasChain]>; 554def strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP", 555 SDTIntToFPOp, [SDNPHasChain]>; 556 557def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; 558def select : SDNode<"ISD::SELECT" , SDTSelect>; 559def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>; 560def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; 561 562def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>; 563def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; 564def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; 565def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; 566def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret, 567 [SDNPHasChain, SDNPSideEffect]>; 568def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>; 569 570def trap : SDNode<"ISD::TRAP" , SDTNone, 571 [SDNPHasChain, SDNPSideEffect]>; 572def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone, 573 [SDNPHasChain, SDNPSideEffect]>; 574 575def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, 576 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 577 SDNPMemOperand]>; 578 579def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, 580 [SDNPHasChain, SDNPSideEffect]>; 581 582def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, 583 [SDNPHasChain, SDNPSideEffect]>; 584 585def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, 586 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 587def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, 588 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 589def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2, 590 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 591def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2, 592 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 593def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2, 594 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 595def atomic_load_clr : SDNode<"ISD::ATOMIC_LOAD_CLR" , SDTAtomic2, 596 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 597def atomic_load_or : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2, 598 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 599def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2, 600 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 601def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2, 602 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 603def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2, 604 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 605def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2, 606 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 607def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, 608 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 609def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, 610 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 611def atomic_load_fadd : SDNode<"ISD::ATOMIC_LOAD_FADD" , SDTFPAtomic2, 612 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 613def atomic_load_fsub : SDNode<"ISD::ATOMIC_LOAD_FSUB" , SDTFPAtomic2, 614 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 615 616def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, 617 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 618def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, 619 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 620 621def masked_st : SDNode<"ISD::MSTORE", SDTMaskedStore, 622 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 623def masked_ld : SDNode<"ISD::MLOAD", SDTMaskedLoad, 624 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 625 626// Do not use ld, st directly. Use load, extload, sextload, zextload, store, 627// and truncst (see below). 628def ld : SDNode<"ISD::LOAD" , SDTLoad, 629 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 630def st : SDNode<"ISD::STORE" , SDTStore, 631 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 632def ist : SDNode<"ISD::STORE" , SDTIStore, 633 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 634 635def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; 636def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>; 637def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, 638 []>; 639 640// vector_extract/vector_insert are deprecated. extractelt/insertelt 641// are preferred. 642def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", 643 SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; 644def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", 645 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; 646def concat_vectors : SDNode<"ISD::CONCAT_VECTORS", 647 SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>; 648 649// This operator does not do subvector type checking. The ARM 650// backend, at least, needs it. 651def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR", 652 SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>, 653 []>; 654 655// This operator does subvector type checking. 656def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>; 657def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>; 658 659// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use 660// these internally. Don't reference these directly. 661def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", 662 SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, 663 [SDNPHasChain]>; 664def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", 665 SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, 666 [SDNPHasChain]>; 667def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", 668 SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; 669 670def SDT_assert : SDTypeProfile<1, 1, 671 [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>; 672def assertsext : SDNode<"ISD::AssertSext", SDT_assert>; 673def assertzext : SDNode<"ISD::AssertZext", SDT_assert>; 674def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>; 675 676 677//===----------------------------------------------------------------------===// 678// Selection DAG Condition Codes 679 680class CondCode<string fcmpName = "", string icmpName = ""> { 681 string ICmpPredicate = icmpName; 682 string FCmpPredicate = fcmpName; 683} 684 685// ISD::CondCode enums, and mapping to CmpInst::Predicate names 686def SETOEQ : CondCode<"FCMP_OEQ">; 687def SETOGT : CondCode<"FCMP_OGT">; 688def SETOGE : CondCode<"FCMP_OGE">; 689def SETOLT : CondCode<"FCMP_OLT">; 690def SETOLE : CondCode<"FCMP_OLE">; 691def SETONE : CondCode<"FCMP_ONE">; 692def SETO : CondCode<"FCMP_ORD">; 693def SETUO : CondCode<"FCMP_UNO">; 694def SETUEQ : CondCode<"FCMP_UEQ">; 695def SETUGT : CondCode<"FCMP_UGT", "ICMP_UGT">; 696def SETUGE : CondCode<"FCMP_UGE", "ICMP_UGE">; 697def SETULT : CondCode<"FCMP_ULT", "ICMP_ULT">; 698def SETULE : CondCode<"FCMP_ULE", "ICMP_ULE">; 699def SETUNE : CondCode<"FCMP_UNE">; 700def SETEQ : CondCode<"", "ICMP_EQ">; 701def SETGT : CondCode<"", "ICMP_SGT">; 702def SETGE : CondCode<"", "ICMP_SGE">; 703def SETLT : CondCode<"", "ICMP_SLT">; 704def SETLE : CondCode<"", "ICMP_SLE">; 705def SETNE : CondCode<"", "ICMP_NE">; 706 707//===----------------------------------------------------------------------===// 708// Selection DAG Node Transformation Functions. 709// 710// This mechanism allows targets to manipulate nodes in the output DAG once a 711// match has been formed. This is typically used to manipulate immediate 712// values. 713// 714class SDNodeXForm<SDNode opc, code xformFunction> { 715 SDNode Opcode = opc; 716 code XFormFunction = xformFunction; 717} 718 719def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>; 720 721//===----------------------------------------------------------------------===// 722// Selection DAG Pattern Fragments. 723// 724// Pattern fragments are reusable chunks of dags that match specific things. 725// They can take arguments and have C++ predicates that control whether they 726// match. They are intended to make the patterns for common instructions more 727// compact and readable. 728// 729 730/// PatFrags - Represents a set of pattern fragments. Each single fragment 731/// can match something on the DAG, from a single node to multiple nested other 732/// fragments. The whole set of fragments matches if any of the single 733/// fragments match. This allows e.g. matching and "add with overflow" and 734/// a regular "add" with the same fragment set. 735/// 736class PatFrags<dag ops, list<dag> frags, code pred = [{}], 737 SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator { 738 dag Operands = ops; 739 list<dag> Fragments = frags; 740 code PredicateCode = pred; 741 code GISelPredicateCode = [{}]; 742 code ImmediateCode = [{}]; 743 SDNodeXForm OperandTransform = xform; 744 745 // When this is set, the PredicateCode may refer to a constant Operands 746 // vector which contains the captured nodes of the DAG, in the order listed 747 // by the Operands field above. 748 // 749 // This is useful when Fragments involves associative / commutative 750 // operators: a single piece of code can easily refer to all operands even 751 // when re-associated / commuted variants of the fragment are matched. 752 bit PredicateCodeUsesOperands = 0; 753 754 // Define a few pre-packaged predicates. This helps GlobalISel import 755 // existing rules from SelectionDAG for many common cases. 756 // They will be tested prior to the code in pred and must not be used in 757 // ImmLeaf and its subclasses. 758 759 // Is the desired pre-packaged predicate for a load? 760 bit IsLoad = ?; 761 // Is the desired pre-packaged predicate for a store? 762 bit IsStore = ?; 763 // Is the desired pre-packaged predicate for an atomic? 764 bit IsAtomic = ?; 765 766 // cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 767 // cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 768 bit IsUnindexed = ?; 769 770 // cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD 771 bit IsNonExtLoad = ?; 772 // cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; 773 bit IsAnyExtLoad = ?; 774 // cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 775 bit IsSignExtLoad = ?; 776 // cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; 777 bit IsZeroExtLoad = ?; 778 // !cast<StoreSDNode>(N)->isTruncatingStore(); 779 // cast<StoreSDNode>(N)->isTruncatingStore(); 780 bit IsTruncStore = ?; 781 782 // cast<MemSDNode>(N)->getAddressSpace() == 783 // If this empty, accept any address space. 784 list<int> AddressSpaces = ?; 785 786 // cast<MemSDNode>(N)->getAlignment() >= 787 // If this is empty, accept any alignment. 788 int MinAlignment = ?; 789 790 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic 791 bit IsAtomicOrderingMonotonic = ?; 792 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire 793 bit IsAtomicOrderingAcquire = ?; 794 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release 795 bit IsAtomicOrderingRelease = ?; 796 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease 797 bit IsAtomicOrderingAcquireRelease = ?; 798 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent 799 bit IsAtomicOrderingSequentiallyConsistent = ?; 800 801 // isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 802 // !isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 803 bit IsAtomicOrderingAcquireOrStronger = ?; 804 805 // isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 806 // !isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 807 bit IsAtomicOrderingReleaseOrStronger = ?; 808 809 // cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>; 810 // cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>; 811 ValueType MemoryVT = ?; 812 // cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; 813 // cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; 814 ValueType ScalarMemoryVT = ?; 815} 816 817// PatFrag - A version of PatFrags matching only a single fragment. 818class PatFrag<dag ops, dag frag, code pred = [{}], 819 SDNodeXForm xform = NOOP_SDNodeXForm> 820 : PatFrags<ops, [frag], pred, xform>; 821 822// OutPatFrag is a pattern fragment that is used as part of an output pattern 823// (not an input pattern). These do not have predicates or transforms, but are 824// used to avoid repeated subexpressions in output patterns. 825class OutPatFrag<dag ops, dag frag> 826 : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>; 827 828// PatLeaf's are pattern fragments that have no operands. This is just a helper 829// to define immediates and other common things concisely. 830class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> 831 : PatFrag<(ops), frag, pred, xform>; 832 833 834// ImmLeaf is a pattern fragment with a constraint on the immediate. The 835// constraint is a function that is run on the immediate (always with the value 836// sign extended out to an int64_t) as Imm. For example: 837// 838// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>; 839// 840// this is a more convenient form to match 'imm' nodes in than PatLeaf and also 841// is preferred over using PatLeaf because it allows the code generator to 842// reason more about the constraint. 843// 844// If FastIsel should ignore all instructions that have an operand of this type, 845// the FastIselShouldIgnore flag can be set. This is an optimization to reduce 846// the code size of the generated fast instruction selector. 847class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm, 848 SDNode ImmNode = imm> 849 : PatFrag<(ops), (vt ImmNode), [{}], xform> { 850 let ImmediateCode = pred; 851 bit FastIselShouldIgnore = 0; 852 853 // Is the data type of the immediate an APInt? 854 bit IsAPInt = 0; 855 856 // Is the data type of the immediate an APFloat? 857 bit IsAPFloat = 0; 858} 859 860// Convenience wrapper for ImmLeaf to use timm/TargetConstant instead 861// of imm/Constant. 862class TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm, 863 SDNode ImmNode = timm> : ImmLeaf<vt, pred, xform, ImmNode>; 864 865// An ImmLeaf except that Imm is an APInt. This is useful when you need to 866// zero-extend the immediate instead of sign-extend it. 867// 868// Note that FastISel does not currently understand IntImmLeaf and will not 869// generate code for rules that make use of it. As such, it does not make sense 870// to replace ImmLeaf with IntImmLeaf. However, replacing PatLeaf with an 871// IntImmLeaf will allow GlobalISel to import the rule. 872class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> 873 : ImmLeaf<vt, pred, xform> { 874 let IsAPInt = 1; 875 let FastIselShouldIgnore = 1; 876} 877 878// An ImmLeaf except that Imm is an APFloat. 879// 880// Note that FastISel does not currently understand FPImmLeaf and will not 881// generate code for rules that make use of it. 882class FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> 883 : ImmLeaf<vt, pred, xform, fpimm> { 884 let IsAPFloat = 1; 885 let FastIselShouldIgnore = 1; 886} 887 888// Leaf fragments. 889 890def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; 891def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; 892 893// Use ISD::isBuildVectorAllOnes or ISD::isBuildVectorAllZeros to look for 894// the corresponding build_vector. Will look through bitcasts except when used 895// as a pattern root. 896def immAllOnesV; // ISD::isBuildVectorAllOnes 897def immAllZerosV; // ISD::isBuildVectorAllZeros 898 899// Other helper fragments. 900def not : PatFrag<(ops node:$in), (xor node:$in, -1)>; 901def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; 902def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; 903 904// null_frag - The null pattern operator is used in multiclass instantiations 905// which accept an SDPatternOperator for use in matching patterns for internal 906// definitions. When expanding a pattern, if the null fragment is referenced 907// in the expansion, the pattern is discarded and it is as-if '[]' had been 908// specified. This allows multiclasses to have the isel patterns be optional. 909def null_frag : SDPatternOperator; 910 911// load fragments. 912def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> { 913 let IsLoad = 1; 914 let IsUnindexed = 1; 915} 916def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 917 let IsLoad = 1; 918 let IsNonExtLoad = 1; 919} 920 921// extending load fragments. 922def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 923 let IsLoad = 1; 924 let IsAnyExtLoad = 1; 925} 926def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 927 let IsLoad = 1; 928 let IsSignExtLoad = 1; 929} 930def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 931 let IsLoad = 1; 932 let IsZeroExtLoad = 1; 933} 934 935def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 936 let IsLoad = 1; 937 let MemoryVT = i1; 938} 939def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 940 let IsLoad = 1; 941 let MemoryVT = i8; 942} 943def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 944 let IsLoad = 1; 945 let MemoryVT = i16; 946} 947def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 948 let IsLoad = 1; 949 let MemoryVT = i32; 950} 951def extloadf16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 952 let IsLoad = 1; 953 let MemoryVT = f16; 954} 955def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 956 let IsLoad = 1; 957 let MemoryVT = f32; 958} 959def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 960 let IsLoad = 1; 961 let MemoryVT = f64; 962} 963 964def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 965 let IsLoad = 1; 966 let MemoryVT = i1; 967} 968def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 969 let IsLoad = 1; 970 let MemoryVT = i8; 971} 972def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 973 let IsLoad = 1; 974 let MemoryVT = i16; 975} 976def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 977 let IsLoad = 1; 978 let MemoryVT = i32; 979} 980 981def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 982 let IsLoad = 1; 983 let MemoryVT = i1; 984} 985def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 986 let IsLoad = 1; 987 let MemoryVT = i8; 988} 989def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 990 let IsLoad = 1; 991 let MemoryVT = i16; 992} 993def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 994 let IsLoad = 1; 995 let MemoryVT = i32; 996} 997 998def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 999 let IsLoad = 1; 1000 let ScalarMemoryVT = i1; 1001} 1002def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1003 let IsLoad = 1; 1004 let ScalarMemoryVT = i8; 1005} 1006def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1007 let IsLoad = 1; 1008 let ScalarMemoryVT = i16; 1009} 1010def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1011 let IsLoad = 1; 1012 let ScalarMemoryVT = i32; 1013} 1014def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1015 let IsLoad = 1; 1016 let ScalarMemoryVT = f32; 1017} 1018def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1019 let IsLoad = 1; 1020 let ScalarMemoryVT = f64; 1021} 1022 1023def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1024 let IsLoad = 1; 1025 let ScalarMemoryVT = i1; 1026} 1027def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1028 let IsLoad = 1; 1029 let ScalarMemoryVT = i8; 1030} 1031def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1032 let IsLoad = 1; 1033 let ScalarMemoryVT = i16; 1034} 1035def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1036 let IsLoad = 1; 1037 let ScalarMemoryVT = i32; 1038} 1039 1040def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1041 let IsLoad = 1; 1042 let ScalarMemoryVT = i1; 1043} 1044def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1045 let IsLoad = 1; 1046 let ScalarMemoryVT = i8; 1047} 1048def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1049 let IsLoad = 1; 1050 let ScalarMemoryVT = i16; 1051} 1052def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1053 let IsLoad = 1; 1054 let ScalarMemoryVT = i32; 1055} 1056 1057// store fragments. 1058def unindexedstore : PatFrag<(ops node:$val, node:$ptr), 1059 (st node:$val, node:$ptr)> { 1060 let IsStore = 1; 1061 let IsUnindexed = 1; 1062} 1063def store : PatFrag<(ops node:$val, node:$ptr), 1064 (unindexedstore node:$val, node:$ptr)> { 1065 let IsStore = 1; 1066 let IsTruncStore = 0; 1067} 1068 1069// truncstore fragments. 1070def truncstore : PatFrag<(ops node:$val, node:$ptr), 1071 (unindexedstore node:$val, node:$ptr)> { 1072 let IsStore = 1; 1073 let IsTruncStore = 1; 1074} 1075def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), 1076 (truncstore node:$val, node:$ptr)> { 1077 let IsStore = 1; 1078 let MemoryVT = i8; 1079} 1080def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), 1081 (truncstore node:$val, node:$ptr)> { 1082 let IsStore = 1; 1083 let MemoryVT = i16; 1084} 1085def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), 1086 (truncstore node:$val, node:$ptr)> { 1087 let IsStore = 1; 1088 let MemoryVT = i32; 1089} 1090def truncstoref16 : PatFrag<(ops node:$val, node:$ptr), 1091 (truncstore node:$val, node:$ptr)> { 1092 let IsStore = 1; 1093 let MemoryVT = f16; 1094} 1095def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), 1096 (truncstore node:$val, node:$ptr)> { 1097 let IsStore = 1; 1098 let MemoryVT = f32; 1099} 1100def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), 1101 (truncstore node:$val, node:$ptr)> { 1102 let IsStore = 1; 1103 let MemoryVT = f64; 1104} 1105 1106def truncstorevi8 : PatFrag<(ops node:$val, node:$ptr), 1107 (truncstore node:$val, node:$ptr)> { 1108 let IsStore = 1; 1109 let ScalarMemoryVT = i8; 1110} 1111 1112def truncstorevi16 : PatFrag<(ops node:$val, node:$ptr), 1113 (truncstore node:$val, node:$ptr)> { 1114 let IsStore = 1; 1115 let ScalarMemoryVT = i16; 1116} 1117 1118def truncstorevi32 : PatFrag<(ops node:$val, node:$ptr), 1119 (truncstore node:$val, node:$ptr)> { 1120 let IsStore = 1; 1121 let ScalarMemoryVT = i32; 1122} 1123 1124// indexed store fragments. 1125def istore : PatFrag<(ops node:$val, node:$base, node:$offset), 1126 (ist node:$val, node:$base, node:$offset)> { 1127 let IsStore = 1; 1128 let IsTruncStore = 0; 1129} 1130 1131def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), 1132 (istore node:$val, node:$base, node:$offset), [{ 1133 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1134 return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; 1135}]>; 1136 1137def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset), 1138 (ist node:$val, node:$base, node:$offset)> { 1139 let IsStore = 1; 1140 let IsTruncStore = 1; 1141} 1142def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), 1143 (itruncstore node:$val, node:$base, node:$offset), [{ 1144 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1145 return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; 1146}]>; 1147def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), 1148 (pre_truncst node:$val, node:$base, node:$offset)> { 1149 let IsStore = 1; 1150 let MemoryVT = i1; 1151} 1152def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1153 (pre_truncst node:$val, node:$base, node:$offset)> { 1154 let IsStore = 1; 1155 let MemoryVT = i8; 1156} 1157def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1158 (pre_truncst node:$val, node:$base, node:$offset)> { 1159 let IsStore = 1; 1160 let MemoryVT = i16; 1161} 1162def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1163 (pre_truncst node:$val, node:$base, node:$offset)> { 1164 let IsStore = 1; 1165 let MemoryVT = i32; 1166} 1167def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1168 (pre_truncst node:$val, node:$base, node:$offset)> { 1169 let IsStore = 1; 1170 let MemoryVT = f32; 1171} 1172def pre_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1173 (pre_truncst node:$val, node:$base, node:$offset)> { 1174 let IsStore = 1; 1175 let ScalarMemoryVT = i8; 1176} 1177def pre_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1178 (pre_truncst node:$val, node:$base, node:$offset)> { 1179 let IsStore = 1; 1180 let ScalarMemoryVT = i16; 1181} 1182 1183def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), 1184 (istore node:$val, node:$ptr, node:$offset), [{ 1185 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1186 return AM == ISD::POST_INC || AM == ISD::POST_DEC; 1187}]>; 1188 1189def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), 1190 (itruncstore node:$val, node:$base, node:$offset), [{ 1191 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1192 return AM == ISD::POST_INC || AM == ISD::POST_DEC; 1193}]>; 1194def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), 1195 (post_truncst node:$val, node:$base, node:$offset)> { 1196 let IsStore = 1; 1197 let MemoryVT = i1; 1198} 1199def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1200 (post_truncst node:$val, node:$base, node:$offset)> { 1201 let IsStore = 1; 1202 let MemoryVT = i8; 1203} 1204def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1205 (post_truncst node:$val, node:$base, node:$offset)> { 1206 let IsStore = 1; 1207 let MemoryVT = i16; 1208} 1209def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1210 (post_truncst node:$val, node:$base, node:$offset)> { 1211 let IsStore = 1; 1212 let MemoryVT = i32; 1213} 1214def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1215 (post_truncst node:$val, node:$base, node:$offset)> { 1216 let IsStore = 1; 1217 let MemoryVT = f32; 1218} 1219def post_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1220 (post_truncst node:$val, node:$base, node:$offset)> { 1221 let IsStore = 1; 1222 let ScalarMemoryVT = i8; 1223} 1224def post_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1225 (post_truncst node:$val, node:$base, node:$offset)> { 1226 let IsStore = 1; 1227 let ScalarMemoryVT = i16; 1228} 1229 1230// TODO: Split these into volatile and unordered flavors to enable 1231// selectively legal optimizations for each. (See D66309) 1232def simple_load : PatFrag<(ops node:$ptr), 1233 (load node:$ptr), [{ 1234 return cast<LoadSDNode>(N)->isSimple(); 1235}]>; 1236def simple_store : PatFrag<(ops node:$val, node:$ptr), 1237 (store node:$val, node:$ptr), [{ 1238 return cast<StoreSDNode>(N)->isSimple(); 1239}]>; 1240 1241// nontemporal store fragments. 1242def nontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1243 (store node:$val, node:$ptr), [{ 1244 return cast<StoreSDNode>(N)->isNonTemporal(); 1245}]>; 1246 1247def alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1248 (nontemporalstore node:$val, node:$ptr), [{ 1249 StoreSDNode *St = cast<StoreSDNode>(N); 1250 return St->getAlignment() >= St->getMemoryVT().getStoreSize(); 1251}]>; 1252 1253def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1254 (nontemporalstore node:$val, node:$ptr), [{ 1255 StoreSDNode *St = cast<StoreSDNode>(N); 1256 return St->getAlignment() < St->getMemoryVT().getStoreSize(); 1257}]>; 1258 1259// nontemporal load fragments. 1260def nontemporalload : PatFrag<(ops node:$ptr), 1261 (load node:$ptr), [{ 1262 return cast<LoadSDNode>(N)->isNonTemporal(); 1263}]>; 1264 1265def alignednontemporalload : PatFrag<(ops node:$ptr), 1266 (nontemporalload node:$ptr), [{ 1267 LoadSDNode *Ld = cast<LoadSDNode>(N); 1268 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); 1269}]>; 1270 1271// setcc convenience fragments. 1272def setoeq : PatFrag<(ops node:$lhs, node:$rhs), 1273 (setcc node:$lhs, node:$rhs, SETOEQ)>; 1274def setogt : PatFrag<(ops node:$lhs, node:$rhs), 1275 (setcc node:$lhs, node:$rhs, SETOGT)>; 1276def setoge : PatFrag<(ops node:$lhs, node:$rhs), 1277 (setcc node:$lhs, node:$rhs, SETOGE)>; 1278def setolt : PatFrag<(ops node:$lhs, node:$rhs), 1279 (setcc node:$lhs, node:$rhs, SETOLT)>; 1280def setole : PatFrag<(ops node:$lhs, node:$rhs), 1281 (setcc node:$lhs, node:$rhs, SETOLE)>; 1282def setone : PatFrag<(ops node:$lhs, node:$rhs), 1283 (setcc node:$lhs, node:$rhs, SETONE)>; 1284def seto : PatFrag<(ops node:$lhs, node:$rhs), 1285 (setcc node:$lhs, node:$rhs, SETO)>; 1286def setuo : PatFrag<(ops node:$lhs, node:$rhs), 1287 (setcc node:$lhs, node:$rhs, SETUO)>; 1288def setueq : PatFrag<(ops node:$lhs, node:$rhs), 1289 (setcc node:$lhs, node:$rhs, SETUEQ)>; 1290def setugt : PatFrag<(ops node:$lhs, node:$rhs), 1291 (setcc node:$lhs, node:$rhs, SETUGT)>; 1292def setuge : PatFrag<(ops node:$lhs, node:$rhs), 1293 (setcc node:$lhs, node:$rhs, SETUGE)>; 1294def setult : PatFrag<(ops node:$lhs, node:$rhs), 1295 (setcc node:$lhs, node:$rhs, SETULT)>; 1296def setule : PatFrag<(ops node:$lhs, node:$rhs), 1297 (setcc node:$lhs, node:$rhs, SETULE)>; 1298def setune : PatFrag<(ops node:$lhs, node:$rhs), 1299 (setcc node:$lhs, node:$rhs, SETUNE)>; 1300def seteq : PatFrag<(ops node:$lhs, node:$rhs), 1301 (setcc node:$lhs, node:$rhs, SETEQ)>; 1302def setgt : PatFrag<(ops node:$lhs, node:$rhs), 1303 (setcc node:$lhs, node:$rhs, SETGT)>; 1304def setge : PatFrag<(ops node:$lhs, node:$rhs), 1305 (setcc node:$lhs, node:$rhs, SETGE)>; 1306def setlt : PatFrag<(ops node:$lhs, node:$rhs), 1307 (setcc node:$lhs, node:$rhs, SETLT)>; 1308def setle : PatFrag<(ops node:$lhs, node:$rhs), 1309 (setcc node:$lhs, node:$rhs, SETLE)>; 1310def setne : PatFrag<(ops node:$lhs, node:$rhs), 1311 (setcc node:$lhs, node:$rhs, SETNE)>; 1312 1313// We don't have strict FP extended loads as single DAG nodes, but we can 1314// still provide convenience fragments to match those operations. 1315def strict_extloadf32 : PatFrag<(ops node:$ptr), 1316 (strict_fpextend (f32 (load node:$ptr)))>; 1317def strict_extloadf64 : PatFrag<(ops node:$ptr), 1318 (strict_fpextend (f64 (load node:$ptr)))>; 1319 1320// Convenience fragments to match both strict and non-strict fp operations 1321def any_fadd : PatFrags<(ops node:$lhs, node:$rhs), 1322 [(strict_fadd node:$lhs, node:$rhs), 1323 (fadd node:$lhs, node:$rhs)]>; 1324def any_fsub : PatFrags<(ops node:$lhs, node:$rhs), 1325 [(strict_fsub node:$lhs, node:$rhs), 1326 (fsub node:$lhs, node:$rhs)]>; 1327def any_fmul : PatFrags<(ops node:$lhs, node:$rhs), 1328 [(strict_fmul node:$lhs, node:$rhs), 1329 (fmul node:$lhs, node:$rhs)]>; 1330def any_fdiv : PatFrags<(ops node:$lhs, node:$rhs), 1331 [(strict_fdiv node:$lhs, node:$rhs), 1332 (fdiv node:$lhs, node:$rhs)]>; 1333def any_frem : PatFrags<(ops node:$lhs, node:$rhs), 1334 [(strict_frem node:$lhs, node:$rhs), 1335 (frem node:$lhs, node:$rhs)]>; 1336def any_fma : PatFrags<(ops node:$src1, node:$src2, node:$src3), 1337 [(strict_fma node:$src1, node:$src2, node:$src3), 1338 (fma node:$src1, node:$src2, node:$src3)]>; 1339def any_fsqrt : PatFrags<(ops node:$src), 1340 [(strict_fsqrt node:$src), 1341 (fsqrt node:$src)]>; 1342def any_fsin : PatFrags<(ops node:$src), 1343 [(strict_fsin node:$src), 1344 (fsin node:$src)]>; 1345def any_fcos : PatFrags<(ops node:$src), 1346 [(strict_fcos node:$src), 1347 (fcos node:$src)]>; 1348def any_fexp2 : PatFrags<(ops node:$src), 1349 [(strict_fexp2 node:$src), 1350 (fexp2 node:$src)]>; 1351def any_fpow : PatFrags<(ops node:$lhs, node:$rhs), 1352 [(strict_fpow node:$lhs, node:$rhs), 1353 (fpow node:$lhs, node:$rhs)]>; 1354def any_flog2 : PatFrags<(ops node:$src), 1355 [(strict_flog2 node:$src), 1356 (flog2 node:$src)]>; 1357def any_frint : PatFrags<(ops node:$src), 1358 [(strict_frint node:$src), 1359 (frint node:$src)]>; 1360def any_lrint : PatFrags<(ops node:$src), 1361 [(strict_lrint node:$src), 1362 (lrint node:$src)]>; 1363def any_llrint : PatFrags<(ops node:$src), 1364 [(strict_llrint node:$src), 1365 (llrint node:$src)]>; 1366def any_fnearbyint : PatFrags<(ops node:$src), 1367 [(strict_fnearbyint node:$src), 1368 (fnearbyint node:$src)]>; 1369def any_fceil : PatFrags<(ops node:$src), 1370 [(strict_fceil node:$src), 1371 (fceil node:$src)]>; 1372def any_ffloor : PatFrags<(ops node:$src), 1373 [(strict_ffloor node:$src), 1374 (ffloor node:$src)]>; 1375def any_lround : PatFrags<(ops node:$src), 1376 [(strict_lround node:$src), 1377 (lround node:$src)]>; 1378def any_llround : PatFrags<(ops node:$src), 1379 [(strict_llround node:$src), 1380 (llround node:$src)]>; 1381def any_fround : PatFrags<(ops node:$src), 1382 [(strict_fround node:$src), 1383 (fround node:$src)]>; 1384def any_ftrunc : PatFrags<(ops node:$src), 1385 [(strict_ftrunc node:$src), 1386 (ftrunc node:$src)]>; 1387def any_fmaxnum : PatFrags<(ops node:$lhs, node:$rhs), 1388 [(strict_fmaxnum node:$lhs, node:$rhs), 1389 (fmaxnum node:$lhs, node:$rhs)]>; 1390def any_fminnum : PatFrags<(ops node:$lhs, node:$rhs), 1391 [(strict_fminnum node:$lhs, node:$rhs), 1392 (fminnum node:$lhs, node:$rhs)]>; 1393def any_fmaximum : PatFrags<(ops node:$lhs, node:$rhs), 1394 [(strict_fmaximum node:$lhs, node:$rhs), 1395 (fmaximum node:$lhs, node:$rhs)]>; 1396def any_fminimum : PatFrags<(ops node:$lhs, node:$rhs), 1397 [(strict_fminimum node:$lhs, node:$rhs), 1398 (fminimum node:$lhs, node:$rhs)]>; 1399def any_fpround : PatFrags<(ops node:$src), 1400 [(strict_fpround node:$src), 1401 (fpround node:$src)]>; 1402def any_fpextend : PatFrags<(ops node:$src), 1403 [(strict_fpextend node:$src), 1404 (fpextend node:$src)]>; 1405def any_extloadf32 : PatFrags<(ops node:$ptr), 1406 [(strict_extloadf32 node:$ptr), 1407 (extloadf32 node:$ptr)]>; 1408def any_extloadf64 : PatFrags<(ops node:$ptr), 1409 [(strict_extloadf64 node:$ptr), 1410 (extloadf64 node:$ptr)]>; 1411def any_fp_to_sint : PatFrags<(ops node:$src), 1412 [(strict_fp_to_sint node:$src), 1413 (fp_to_sint node:$src)]>; 1414def any_fp_to_uint : PatFrags<(ops node:$src), 1415 [(strict_fp_to_uint node:$src), 1416 (fp_to_uint node:$src)]>; 1417def any_sint_to_fp : PatFrags<(ops node:$src), 1418 [(strict_sint_to_fp node:$src), 1419 (sint_to_fp node:$src)]>; 1420def any_uint_to_fp : PatFrags<(ops node:$src), 1421 [(strict_uint_to_fp node:$src), 1422 (uint_to_fp node:$src)]>; 1423 1424multiclass binary_atomic_op_ord<SDNode atomic_op> { 1425 def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val), 1426 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1427 let IsAtomic = 1; 1428 let IsAtomicOrderingMonotonic = 1; 1429 } 1430 def NAME#_acquire : PatFrag<(ops node:$ptr, node:$val), 1431 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1432 let IsAtomic = 1; 1433 let IsAtomicOrderingAcquire = 1; 1434 } 1435 def NAME#_release : PatFrag<(ops node:$ptr, node:$val), 1436 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1437 let IsAtomic = 1; 1438 let IsAtomicOrderingRelease = 1; 1439 } 1440 def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val), 1441 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1442 let IsAtomic = 1; 1443 let IsAtomicOrderingAcquireRelease = 1; 1444 } 1445 def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val), 1446 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1447 let IsAtomic = 1; 1448 let IsAtomicOrderingSequentiallyConsistent = 1; 1449 } 1450} 1451 1452multiclass ternary_atomic_op_ord<SDNode atomic_op> { 1453 def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1454 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1455 let IsAtomic = 1; 1456 let IsAtomicOrderingMonotonic = 1; 1457 } 1458 def NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1459 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1460 let IsAtomic = 1; 1461 let IsAtomicOrderingAcquire = 1; 1462 } 1463 def NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1464 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1465 let IsAtomic = 1; 1466 let IsAtomicOrderingRelease = 1; 1467 } 1468 def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1469 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1470 let IsAtomic = 1; 1471 let IsAtomicOrderingAcquireRelease = 1; 1472 } 1473 def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1474 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1475 let IsAtomic = 1; 1476 let IsAtomicOrderingSequentiallyConsistent = 1; 1477 } 1478} 1479 1480multiclass binary_atomic_op<SDNode atomic_op, bit IsInt = 1> { 1481 def _8 : PatFrag<(ops node:$ptr, node:$val), 1482 (atomic_op node:$ptr, node:$val)> { 1483 let IsAtomic = 1; 1484 let MemoryVT = !if(IsInt, i8, ?); 1485 } 1486 def _16 : PatFrag<(ops node:$ptr, node:$val), 1487 (atomic_op node:$ptr, node:$val)> { 1488 let IsAtomic = 1; 1489 let MemoryVT = !if(IsInt, i16, f16); 1490 } 1491 def _32 : PatFrag<(ops node:$ptr, node:$val), 1492 (atomic_op node:$ptr, node:$val)> { 1493 let IsAtomic = 1; 1494 let MemoryVT = !if(IsInt, i32, f32); 1495 } 1496 def _64 : PatFrag<(ops node:$ptr, node:$val), 1497 (atomic_op node:$ptr, node:$val)> { 1498 let IsAtomic = 1; 1499 let MemoryVT = !if(IsInt, i64, f64); 1500 } 1501 1502 defm NAME#_8 : binary_atomic_op_ord<atomic_op>; 1503 defm NAME#_16 : binary_atomic_op_ord<atomic_op>; 1504 defm NAME#_32 : binary_atomic_op_ord<atomic_op>; 1505 defm NAME#_64 : binary_atomic_op_ord<atomic_op>; 1506} 1507 1508multiclass ternary_atomic_op<SDNode atomic_op> { 1509 def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1510 (atomic_op node:$ptr, node:$cmp, node:$val)> { 1511 let IsAtomic = 1; 1512 let MemoryVT = i8; 1513 } 1514 def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1515 (atomic_op node:$ptr, node:$cmp, node:$val)> { 1516 let IsAtomic = 1; 1517 let MemoryVT = i16; 1518 } 1519 def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1520 (atomic_op node:$ptr, node:$cmp, node:$val)> { 1521 let IsAtomic = 1; 1522 let MemoryVT = i32; 1523 } 1524 def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1525 (atomic_op node:$ptr, node:$cmp, node:$val)> { 1526 let IsAtomic = 1; 1527 let MemoryVT = i64; 1528 } 1529 1530 defm NAME#_8 : ternary_atomic_op_ord<atomic_op>; 1531 defm NAME#_16 : ternary_atomic_op_ord<atomic_op>; 1532 defm NAME#_32 : ternary_atomic_op_ord<atomic_op>; 1533 defm NAME#_64 : ternary_atomic_op_ord<atomic_op>; 1534} 1535 1536defm atomic_load_add : binary_atomic_op<atomic_load_add>; 1537defm atomic_swap : binary_atomic_op<atomic_swap>; 1538defm atomic_load_sub : binary_atomic_op<atomic_load_sub>; 1539defm atomic_load_and : binary_atomic_op<atomic_load_and>; 1540defm atomic_load_clr : binary_atomic_op<atomic_load_clr>; 1541defm atomic_load_or : binary_atomic_op<atomic_load_or>; 1542defm atomic_load_xor : binary_atomic_op<atomic_load_xor>; 1543defm atomic_load_nand : binary_atomic_op<atomic_load_nand>; 1544defm atomic_load_min : binary_atomic_op<atomic_load_min>; 1545defm atomic_load_max : binary_atomic_op<atomic_load_max>; 1546defm atomic_load_umin : binary_atomic_op<atomic_load_umin>; 1547defm atomic_load_umax : binary_atomic_op<atomic_load_umax>; 1548defm atomic_store : binary_atomic_op<atomic_store>; 1549defm atomic_cmp_swap : ternary_atomic_op<atomic_cmp_swap>; 1550 1551def atomic_load_8 : 1552 PatFrag<(ops node:$ptr), 1553 (atomic_load node:$ptr)> { 1554 let IsAtomic = 1; 1555 let MemoryVT = i8; 1556} 1557def atomic_load_16 : 1558 PatFrag<(ops node:$ptr), 1559 (atomic_load node:$ptr)> { 1560 let IsAtomic = 1; 1561 let MemoryVT = i16; 1562} 1563def atomic_load_32 : 1564 PatFrag<(ops node:$ptr), 1565 (atomic_load node:$ptr)> { 1566 let IsAtomic = 1; 1567 let MemoryVT = i32; 1568} 1569def atomic_load_64 : 1570 PatFrag<(ops node:$ptr), 1571 (atomic_load node:$ptr)> { 1572 let IsAtomic = 1; 1573 let MemoryVT = i64; 1574} 1575 1576//===----------------------------------------------------------------------===// 1577// Selection DAG Pattern Support. 1578// 1579// Patterns are what are actually matched against by the target-flavored 1580// instruction selection DAG. Instructions defined by the target implicitly 1581// define patterns in most cases, but patterns can also be explicitly added when 1582// an operation is defined by a sequence of instructions (e.g. loading a large 1583// immediate value on RISC targets that do not support immediates as large as 1584// their GPRs). 1585// 1586 1587class Pattern<dag patternToMatch, list<dag> resultInstrs> { 1588 dag PatternToMatch = patternToMatch; 1589 list<dag> ResultInstrs = resultInstrs; 1590 list<Predicate> Predicates = []; // See class Instruction in Target.td. 1591 int AddedComplexity = 0; // See class Instruction in Target.td. 1592} 1593 1594// Pat - A simple (but common) form of a pattern, which produces a simple result 1595// not needing a full list. 1596class Pat<dag pattern, dag result> : Pattern<pattern, [result]>; 1597 1598//===----------------------------------------------------------------------===// 1599// Complex pattern definitions. 1600// 1601 1602// Complex patterns, e.g. X86 addressing mode, requires pattern matching code 1603// in C++. NumOperands is the number of operands returned by the select function; 1604// SelectFunc is the name of the function used to pattern match the max. pattern; 1605// RootNodes are the list of possible root nodes of the sub-dags to match. 1606// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; 1607// 1608class ComplexPattern<ValueType ty, int numops, string fn, 1609 list<SDNode> roots = [], list<SDNodeProperty> props = [], 1610 int complexity = -1> { 1611 ValueType Ty = ty; 1612 int NumOperands = numops; 1613 string SelectFunc = fn; 1614 list<SDNode> RootNodes = roots; 1615 list<SDNodeProperty> Properties = props; 1616 int Complexity = complexity; 1617} 1618