Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines the target-independent interfaces used by SelectionDAG |
| 11 | // instruction selection generators. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | //===----------------------------------------------------------------------===// |
| 16 | // Selection DAG Type Constraint definitions. |
| 17 | // |
| 18 | // Note that the semantics of these constraints are hard coded into tblgen. To |
| 19 | // modify or add constraints, you have to hack tblgen. |
| 20 | // |
| 21 | |
| 22 | class SDTypeConstraint<int opnum> { |
| 23 | int OperandNum = opnum; |
| 24 | } |
| 25 | |
| 26 | // SDTCisVT - The specified operand has exactly this VT. |
| 27 | class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { |
| 28 | ValueType VT = vt; |
| 29 | } |
| 30 | |
| 31 | class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>; |
| 32 | |
| 33 | // SDTCisInt - The specified operand has integer type. |
| 34 | class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>; |
| 35 | |
| 36 | // SDTCisFP - The specified operand has floating-point type. |
| 37 | class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>; |
| 38 | |
| 39 | // SDTCisVec - The specified operand has a vector type. |
| 40 | class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>; |
| 41 | |
| 42 | // SDTCisSameAs - The two specified operands have identical types. |
| 43 | class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { |
| 44 | int OtherOperandNum = OtherOp; |
| 45 | } |
| 46 | |
| 47 | // SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is |
| 48 | // smaller than the 'Other' operand. |
| 49 | class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { |
| 50 | int OtherOperandNum = OtherOp; |
| 51 | } |
| 52 | |
| 53 | class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{ |
| 54 | int BigOperandNum = BigOp; |
| 55 | } |
| 56 | |
| 57 | /// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same |
| 58 | /// type as the element type of OtherOp, which is a vector type. |
| 59 | class SDTCisEltOfVec<int ThisOp, int OtherOp> |
| 60 | : SDTypeConstraint<ThisOp> { |
| 61 | int OtherOpNum = OtherOp; |
| 62 | } |
| 63 | |
| 64 | /// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type |
| 65 | /// with length less that of OtherOp, which is a vector type. |
| 66 | class SDTCisSubVecOfVec<int ThisOp, int OtherOp> |
| 67 | : SDTypeConstraint<ThisOp> { |
| 68 | int OtherOpNum = OtherOp; |
| 69 | } |
| 70 | |
| 71 | // SDTCVecEltisVT - The specified operand is vector type with element type |
| 72 | // of VT. |
| 73 | class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { |
| 74 | ValueType VT = vt; |
| 75 | } |
| 76 | |
| 77 | // SDTCisSameNumEltsAs - The two specified operands have identical number |
| 78 | // of elements. |
| 79 | class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { |
| 80 | int OtherOperandNum = OtherOp; |
| 81 | } |
| 82 | |
| 83 | // SDTCisSameSizeAs - The two specified operands have identical size. |
| 84 | class SDTCisSameSizeAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { |
| 85 | int OtherOperandNum = OtherOp; |
| 86 | } |
| 87 | |
| 88 | //===----------------------------------------------------------------------===// |
| 89 | // Selection DAG Type Profile definitions. |
| 90 | // |
| 91 | // These use the constraints defined above to describe the type requirements of |
| 92 | // the various nodes. These are not hard coded into tblgen, allowing targets to |
| 93 | // add their own if needed. |
| 94 | // |
| 95 | |
| 96 | // SDTypeProfile - This profile describes the type requirements of a Selection |
| 97 | // DAG node. |
| 98 | class SDTypeProfile<int numresults, int numoperands, |
| 99 | list<SDTypeConstraint> constraints> { |
| 100 | int NumResults = numresults; |
| 101 | int NumOperands = numoperands; |
| 102 | list<SDTypeConstraint> Constraints = constraints; |
| 103 | } |
| 104 | |
| 105 | // Builtin profiles. |
| 106 | def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. |
| 107 | def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. |
| 108 | def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. |
| 109 | def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. |
| 110 | def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. |
| 111 | def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert. |
| 112 | |
| 113 | def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. |
| 114 | SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> |
| 115 | ]>; |
| 116 | def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl |
| 117 | SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> |
| 118 | ]>; |
| 119 | def SDTIntSatNoShOp : SDTypeProfile<1, 2, [ // ssat with no shift |
| 120 | SDTCisSameAs<0, 1>, SDTCisInt<2> |
| 121 | ]>; |
| 122 | def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem |
| 123 | SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0> |
| 124 | ]>; |
| 125 | |
| 126 | def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. |
| 127 | SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> |
| 128 | ]>; |
| 129 | def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. |
| 130 | SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> |
| 131 | ]>; |
| 132 | def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. |
| 133 | SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> |
| 134 | ]>; |
| 135 | def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz, cttz |
| 136 | SDTCisSameAs<0, 1>, SDTCisInt<0> |
| 137 | ]>; |
| 138 | def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext |
| 139 | SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> |
| 140 | ]>; |
| 141 | def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc |
| 142 | SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> |
| 143 | ]>; |
| 144 | def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc |
| 145 | SDTCisSameAs<0, 1>, SDTCisFP<0> |
| 146 | ]>; |
| 147 | def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround |
| 148 | SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> |
| 149 | ]>; |
| 150 | def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend |
| 151 | SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> |
| 152 | ]>; |
| 153 | def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp |
| 154 | SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1> |
| 155 | ]>; |
| 156 | def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int |
| 157 | SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1> |
| 158 | ]>; |
| 159 | def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg |
| 160 | SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, |
| 161 | SDTCisVTSmallerThanOp<2, 1> |
| 162 | ]>; |
| 163 | def SDTExtInvec : SDTypeProfile<1, 1, [ // sext_invec |
| 164 | SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>, |
| 165 | SDTCisOpSmallerThanOp<1, 0>, SDTCisSameSizeAs<0,1> |
| 166 | ]>; |
| 167 | |
| 168 | def SDTSetCC : SDTypeProfile<1, 3, [ // setcc |
| 169 | SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> |
| 170 | ]>; |
| 171 | |
| 172 | def SDTSelect : SDTypeProfile<1, 3, [ // select |
| 173 | SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> |
| 174 | ]>; |
| 175 | |
| 176 | def SDTVSelect : SDTypeProfile<1, 3, [ // vselect |
| 177 | SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> |
| 178 | ]>; |
| 179 | |
| 180 | def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc |
| 181 | SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, |
| 182 | SDTCisVT<5, OtherVT> |
| 183 | ]>; |
| 184 | |
| 185 | def SDTBr : SDTypeProfile<0, 1, [ // br |
| 186 | SDTCisVT<0, OtherVT> |
| 187 | ]>; |
| 188 | |
| 189 | def SDTBrCC : SDTypeProfile<0, 4, [ // brcc |
| 190 | SDTCisVT<0, OtherVT>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> |
| 191 | ]>; |
| 192 | |
| 193 | def SDTBrcond : SDTypeProfile<0, 2, [ // brcond |
| 194 | SDTCisInt<0>, SDTCisVT<1, OtherVT> |
| 195 | ]>; |
| 196 | |
| 197 | def SDTBrind : SDTypeProfile<0, 1, [ // brind |
| 198 | SDTCisPtrTy<0> |
| 199 | ]>; |
| 200 | |
| 201 | def SDTCatchret : SDTypeProfile<0, 2, [ // catchret |
| 202 | SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT> |
| 203 | ]>; |
| 204 | |
| 205 | def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap |
| 206 | |
| 207 | def SDTLoad : SDTypeProfile<1, 1, [ // load |
| 208 | SDTCisPtrTy<1> |
| 209 | ]>; |
| 210 | |
| 211 | def SDTStore : SDTypeProfile<0, 2, [ // store |
| 212 | SDTCisPtrTy<1> |
| 213 | ]>; |
| 214 | |
| 215 | def SDTIStore : SDTypeProfile<1, 3, [ // indexed store |
| 216 | SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> |
| 217 | ]>; |
| 218 | |
| 219 | def SDTMaskedStore: SDTypeProfile<0, 3, [ // masked store |
| 220 | SDTCisPtrTy<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisSameNumEltsAs<1, 2> |
| 221 | ]>; |
| 222 | |
| 223 | def SDTMaskedLoad: SDTypeProfile<1, 3, [ // masked load |
| 224 | SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisVec<2>, SDTCisSameAs<0, 3>, |
| 225 | SDTCisSameNumEltsAs<0, 2> |
| 226 | ]>; |
| 227 | |
| 228 | def SDTMaskedGather: SDTypeProfile<2, 3, [ // masked gather |
| 229 | SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<1, 3>, |
| 230 | SDTCisPtrTy<4>, SDTCVecEltisVT<1, i1>, SDTCisSameNumEltsAs<0, 1> |
| 231 | ]>; |
| 232 | |
| 233 | def SDTMaskedScatter: SDTypeProfile<1, 3, [ // masked scatter |
| 234 | SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>, SDTCisSameNumEltsAs<0, 1>, |
| 235 | SDTCVecEltisVT<0, i1>, SDTCisPtrTy<3> |
| 236 | ]>; |
| 237 | |
| 238 | def SDTVecShuffle : SDTypeProfile<1, 2, [ |
| 239 | SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> |
| 240 | ]>; |
| 241 | def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract |
| 242 | SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> |
| 243 | ]>; |
| 244 | def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert |
| 245 | SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> |
| 246 | ]>; |
| 247 | |
| 248 | def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract |
| 249 | SDTCisSubVecOfVec<0,1>, SDTCisInt<2> |
| 250 | ]>; |
| 251 | def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert |
| 252 | SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> |
| 253 | ]>; |
| 254 | |
| 255 | def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch |
| 256 | SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> |
| 257 | ]>; |
| 258 | |
| 259 | def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barrier |
| 260 | SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, |
| 261 | SDTCisInt<0> |
| 262 | ]>; |
| 263 | def SDTAtomicFence : SDTypeProfile<0, 2, [ |
| 264 | SDTCisSameAs<0,1>, SDTCisPtrTy<0> |
| 265 | ]>; |
| 266 | def SDTAtomic3 : SDTypeProfile<1, 3, [ |
| 267 | SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> |
| 268 | ]>; |
| 269 | def SDTAtomic2 : SDTypeProfile<1, 2, [ |
| 270 | SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> |
| 271 | ]>; |
| 272 | def SDTAtomicStore : SDTypeProfile<0, 2, [ |
| 273 | SDTCisPtrTy<0>, SDTCisInt<1> |
| 274 | ]>; |
| 275 | def SDTAtomicLoad : SDTypeProfile<1, 1, [ |
| 276 | SDTCisInt<0>, SDTCisPtrTy<1> |
| 277 | ]>; |
| 278 | |
| 279 | def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su |
| 280 | SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> |
| 281 | ]>; |
| 282 | |
| 283 | class SDCallSeqStart<list<SDTypeConstraint> constraints> : |
| 284 | SDTypeProfile<0, 2, constraints>; |
| 285 | class SDCallSeqEnd<list<SDTypeConstraint> constraints> : |
| 286 | SDTypeProfile<0, 2, constraints>; |
| 287 | |
| 288 | //===----------------------------------------------------------------------===// |
| 289 | // Selection DAG Node definitions. |
| 290 | // |
| 291 | class SDNode<string opcode, SDTypeProfile typeprof, |
| 292 | list<SDNodeProperty> props = [], string sdclass = "SDNode"> |
| 293 | : SDPatternOperator { |
| 294 | string Opcode = opcode; |
| 295 | string SDClass = sdclass; |
| 296 | let Properties = props; |
| 297 | SDTypeProfile TypeProfile = typeprof; |
| 298 | } |
| 299 | |
| 300 | // Special TableGen-recognized dag nodes |
| 301 | def set; |
| 302 | def implicit; |
| 303 | def node; |
| 304 | def srcvalue; |
| 305 | |
| 306 | def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; |
| 307 | def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">; |
| 308 | def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; |
| 309 | def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; |
| 310 | def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; |
| 311 | def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; |
| 312 | def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; |
| 313 | def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], |
| 314 | "GlobalAddressSDNode">; |
| 315 | def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], |
| 316 | "GlobalAddressSDNode">; |
| 317 | def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], |
| 318 | "GlobalAddressSDNode">; |
| 319 | def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], |
| 320 | "GlobalAddressSDNode">; |
| 321 | def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], |
| 322 | "ConstantPoolSDNode">; |
| 323 | def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], |
| 324 | "ConstantPoolSDNode">; |
| 325 | def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], |
| 326 | "JumpTableSDNode">; |
| 327 | def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], |
| 328 | "JumpTableSDNode">; |
| 329 | def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], |
| 330 | "FrameIndexSDNode">; |
| 331 | def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], |
| 332 | "FrameIndexSDNode">; |
| 333 | def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], |
| 334 | "ExternalSymbolSDNode">; |
| 335 | def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], |
| 336 | "ExternalSymbolSDNode">; |
| 337 | def mcsym: SDNode<"ISD::MCSymbol", SDTPtrLeaf, [], "MCSymbolSDNode">; |
| 338 | def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [], |
| 339 | "BlockAddressSDNode">; |
| 340 | def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [], |
| 341 | "BlockAddressSDNode">; |
| 342 | |
| 343 | def add : SDNode<"ISD::ADD" , SDTIntBinOp , |
| 344 | [SDNPCommutative, SDNPAssociative]>; |
| 345 | def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; |
| 346 | def mul : SDNode<"ISD::MUL" , SDTIntBinOp, |
| 347 | [SDNPCommutative, SDNPAssociative]>; |
| 348 | def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; |
| 349 | def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; |
| 350 | def smullohi : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; |
| 351 | def umullohi : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; |
| 352 | def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; |
| 353 | def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; |
| 354 | def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; |
| 355 | def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; |
| 356 | def sdivrem : SDNode<"ISD::SDIVREM" , SDTIntBinHiLoOp>; |
| 357 | def udivrem : SDNode<"ISD::UDIVREM" , SDTIntBinHiLoOp>; |
| 358 | def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; |
| 359 | def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; |
| 360 | def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; |
| 361 | def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; |
| 362 | def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; |
| 363 | def and : SDNode<"ISD::AND" , SDTIntBinOp, |
| 364 | [SDNPCommutative, SDNPAssociative]>; |
| 365 | def or : SDNode<"ISD::OR" , SDTIntBinOp, |
| 366 | [SDNPCommutative, SDNPAssociative]>; |
| 367 | def xor : SDNode<"ISD::XOR" , SDTIntBinOp, |
| 368 | [SDNPCommutative, SDNPAssociative]>; |
| 369 | def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, |
| 370 | [SDNPCommutative, SDNPOutGlue]>; |
| 371 | def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, |
| 372 | [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>; |
| 373 | def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, |
| 374 | [SDNPOutGlue]>; |
| 375 | def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, |
| 376 | [SDNPOutGlue, SDNPInGlue]>; |
| 377 | def smin : SDNode<"ISD::SMIN" , SDTIntBinOp, |
| 378 | [SDNPCommutative, SDNPAssociative]>; |
| 379 | def smax : SDNode<"ISD::SMAX" , SDTIntBinOp, |
| 380 | [SDNPCommutative, SDNPAssociative]>; |
| 381 | def umin : SDNode<"ISD::UMIN" , SDTIntBinOp, |
| 382 | [SDNPCommutative, SDNPAssociative]>; |
| 383 | def umax : SDNode<"ISD::UMAX" , SDTIntBinOp, |
| 384 | [SDNPCommutative, SDNPAssociative]>; |
| 385 | |
| 386 | def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; |
| 387 | def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>; |
| 388 | def zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>; |
| 389 | |
| 390 | def abs : SDNode<"ISD::ABS" , SDTIntUnaryOp>; |
| 391 | def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>; |
| 392 | def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; |
| 393 | def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; |
| 394 | def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>; |
| 395 | def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>; |
| 396 | def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntUnaryOp>; |
| 397 | def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntUnaryOp>; |
| 398 | def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; |
| 399 | def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; |
| 400 | def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; |
| 401 | def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; |
| 402 | def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>; |
| 403 | def addrspacecast : SDNode<"ISD::ADDRSPACECAST", SDTUnaryOp>; |
| 404 | def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; |
| 405 | def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; |
| 406 | |
| 407 | def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; |
| 408 | def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; |
| 409 | def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; |
| 410 | def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; |
| 411 | def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; |
| 412 | def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>; |
| 413 | def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp>; |
| 414 | def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; |
| 415 | def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp, |
| 416 | [SDNPCommutative, SDNPAssociative]>; |
| 417 | def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp, |
| 418 | [SDNPCommutative, SDNPAssociative]>; |
| 419 | def fminnan : SDNode<"ISD::FMINNAN" , SDTFPBinOp>; |
| 420 | def fmaxnan : SDNode<"ISD::FMAXNAN" , SDTFPBinOp>; |
| 421 | def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; |
| 422 | def fcanonicalize : SDNode<"ISD::FCANONICALIZE", SDTFPUnaryOp>; |
| 423 | def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; |
| 424 | def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; |
| 425 | def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; |
| 426 | def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; |
| 427 | def fexp2 : SDNode<"ISD::FEXP2" , SDTFPUnaryOp>; |
| 428 | def fpow : SDNode<"ISD::FPOW" , SDTFPBinOp>; |
| 429 | def flog2 : SDNode<"ISD::FLOG2" , SDTFPUnaryOp>; |
| 430 | def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; |
| 431 | def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; |
| 432 | def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; |
| 433 | def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; |
| 434 | def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; |
| 435 | def fround : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; |
| 436 | |
| 437 | def fpround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; |
| 438 | def fpextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; |
| 439 | def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; |
| 440 | |
| 441 | def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; |
| 442 | def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; |
| 443 | def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; |
| 444 | def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; |
| 445 | def f16_to_fp : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>; |
| 446 | def fp_to_f16 : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>; |
| 447 | |
| 448 | def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; |
| 449 | def select : SDNode<"ISD::SELECT" , SDTSelect>; |
| 450 | def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>; |
| 451 | def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; |
| 452 | |
| 453 | def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>; |
| 454 | def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; |
| 455 | def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; |
| 456 | def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; |
| 457 | def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret, |
| 458 | [SDNPHasChain, SDNPSideEffect]>; |
| 459 | def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>; |
| 460 | def catchpad : SDNode<"ISD::CATCHPAD" , SDTNone, |
| 461 | [SDNPHasChain, SDNPSideEffect]>; |
| 462 | |
| 463 | def trap : SDNode<"ISD::TRAP" , SDTNone, |
| 464 | [SDNPHasChain, SDNPSideEffect]>; |
| 465 | def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone, |
| 466 | [SDNPHasChain, SDNPSideEffect]>; |
| 467 | |
| 468 | def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, |
| 469 | [SDNPHasChain, SDNPMayLoad, SDNPMayStore, |
| 470 | SDNPMemOperand]>; |
| 471 | |
| 472 | def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, |
| 473 | [SDNPHasChain, SDNPSideEffect]>; |
| 474 | |
| 475 | def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, |
| 476 | [SDNPHasChain, SDNPSideEffect]>; |
| 477 | |
| 478 | def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, |
| 479 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 480 | def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, |
| 481 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 482 | def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2, |
| 483 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 484 | def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2, |
| 485 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 486 | def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2, |
| 487 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 488 | def atomic_load_clr : SDNode<"ISD::ATOMIC_LOAD_CLR" , SDTAtomic2, |
| 489 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 490 | def atomic_load_or : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2, |
| 491 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 492 | def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2, |
| 493 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 494 | def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2, |
| 495 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 496 | def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2, |
| 497 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 498 | def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2, |
| 499 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 500 | def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, |
| 501 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 502 | def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, |
| 503 | [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; |
| 504 | def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, |
| 505 | [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; |
| 506 | def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, |
| 507 | [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; |
| 508 | |
| 509 | def masked_store : SDNode<"ISD::MSTORE", SDTMaskedStore, |
| 510 | [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; |
| 511 | def masked_load : SDNode<"ISD::MLOAD", SDTMaskedLoad, |
| 512 | [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; |
| 513 | def masked_scatter : SDNode<"ISD::MSCATTER", SDTMaskedScatter, |
| 514 | [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; |
| 515 | def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather, |
| 516 | [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; |
| 517 | |
| 518 | // Do not use ld, st directly. Use load, extload, sextload, zextload, store, |
| 519 | // and truncst (see below). |
| 520 | def ld : SDNode<"ISD::LOAD" , SDTLoad, |
| 521 | [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; |
| 522 | def st : SDNode<"ISD::STORE" , SDTStore, |
| 523 | [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; |
| 524 | def ist : SDNode<"ISD::STORE" , SDTIStore, |
| 525 | [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; |
| 526 | |
| 527 | def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; |
| 528 | def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>; |
| 529 | def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, |
| 530 | []>; |
| 531 | |
| 532 | // vector_extract/vector_insert are deprecated. extractelt/insertelt |
| 533 | // are preferred. |
| 534 | def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", |
| 535 | SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; |
| 536 | def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", |
| 537 | SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; |
| 538 | def concat_vectors : SDNode<"ISD::CONCAT_VECTORS", |
| 539 | SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>; |
| 540 | |
| 541 | // This operator does not do subvector type checking. The ARM |
| 542 | // backend, at least, needs it. |
| 543 | def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR", |
| 544 | SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>, |
| 545 | []>; |
| 546 | |
| 547 | // This operator does subvector type checking. |
| 548 | def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>; |
| 549 | def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>; |
| 550 | |
| 551 | // Nodes for intrinsics, you should use the intrinsic itself and let tblgen use |
| 552 | // these internally. Don't reference these directly. |
| 553 | def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", |
| 554 | SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, |
| 555 | [SDNPHasChain]>; |
| 556 | def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", |
| 557 | SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, |
| 558 | [SDNPHasChain]>; |
| 559 | def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", |
| 560 | SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; |
| 561 | |
| 562 | def SDT_assertext : SDTypeProfile<1, 1, |
| 563 | [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>; |
| 564 | def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>; |
| 565 | def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>; |
| 566 | |
| 567 | |
| 568 | //===----------------------------------------------------------------------===// |
| 569 | // Selection DAG Condition Codes |
| 570 | |
| 571 | class CondCode; // ISD::CondCode enums |
| 572 | def SETOEQ : CondCode; def SETOGT : CondCode; |
| 573 | def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode; |
| 574 | def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode; |
| 575 | def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode; |
| 576 | def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode; |
| 577 | |
| 578 | def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode; |
| 579 | def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode; |
| 580 | |
| 581 | |
| 582 | //===----------------------------------------------------------------------===// |
| 583 | // Selection DAG Node Transformation Functions. |
| 584 | // |
| 585 | // This mechanism allows targets to manipulate nodes in the output DAG once a |
| 586 | // match has been formed. This is typically used to manipulate immediate |
| 587 | // values. |
| 588 | // |
| 589 | class SDNodeXForm<SDNode opc, code xformFunction> { |
| 590 | SDNode Opcode = opc; |
| 591 | code XFormFunction = xformFunction; |
| 592 | } |
| 593 | |
| 594 | def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>; |
| 595 | |
| 596 | //===----------------------------------------------------------------------===// |
| 597 | // PatPred Subclasses. |
| 598 | // |
| 599 | // These allow specifying different sorts of predicates that control whether a |
| 600 | // node is matched. |
| 601 | // |
| 602 | class PatPred; |
| 603 | |
| 604 | class CodePatPred<code predicate> : PatPred { |
| 605 | code PredicateCode = predicate; |
| 606 | } |
| 607 | |
| 608 | |
| 609 | //===----------------------------------------------------------------------===// |
| 610 | // Selection DAG Pattern Fragments. |
| 611 | // |
| 612 | // Pattern fragments are reusable chunks of dags that match specific things. |
| 613 | // They can take arguments and have C++ predicates that control whether they |
| 614 | // match. They are intended to make the patterns for common instructions more |
| 615 | // compact and readable. |
| 616 | // |
| 617 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 618 | /// PatFrags - Represents a set of pattern fragments. Each single fragment |
| 619 | /// can match something on the DAG, from a single node to multiple nested other |
| 620 | /// fragments. The whole set of fragments matches if any of the single |
| 621 | /// fragemnts match. This allows e.g. matching and "add with overflow" and |
| 622 | /// a regular "add" with the same fragment set. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 623 | /// |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 624 | class PatFrags<dag ops, list<dag> frags, code pred = [{}], |
| 625 | SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 626 | dag Operands = ops; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 627 | list<dag> Fragments = frags; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 628 | code PredicateCode = pred; |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 629 | code GISelPredicateCode = [{}]; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 630 | code ImmediateCode = [{}]; |
| 631 | SDNodeXForm OperandTransform = xform; |
| 632 | |
| 633 | // Define a few pre-packaged predicates. This helps GlobalISel import |
| 634 | // existing rules from SelectionDAG for many common cases. |
| 635 | // They will be tested prior to the code in pred and must not be used in |
| 636 | // ImmLeaf and its subclasses. |
| 637 | |
| 638 | // Is the desired pre-packaged predicate for a load? |
| 639 | bit IsLoad = ?; |
| 640 | // Is the desired pre-packaged predicate for a store? |
| 641 | bit IsStore = ?; |
| 642 | // Is the desired pre-packaged predicate for an atomic? |
| 643 | bit IsAtomic = ?; |
| 644 | |
| 645 | // cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; |
| 646 | // cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; |
| 647 | bit IsUnindexed = ?; |
| 648 | |
| 649 | // cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD |
| 650 | bit IsNonExtLoad = ?; |
| 651 | // cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; |
| 652 | bit IsAnyExtLoad = ?; |
| 653 | // cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; |
| 654 | bit IsSignExtLoad = ?; |
| 655 | // cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; |
| 656 | bit IsZeroExtLoad = ?; |
| 657 | // !cast<StoreSDNode>(N)->isTruncatingStore(); |
| 658 | // cast<StoreSDNode>(N)->isTruncatingStore(); |
| 659 | bit IsTruncStore = ?; |
| 660 | |
| 661 | // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic |
| 662 | bit IsAtomicOrderingMonotonic = ?; |
| 663 | // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire |
| 664 | bit IsAtomicOrderingAcquire = ?; |
| 665 | // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release |
| 666 | bit IsAtomicOrderingRelease = ?; |
| 667 | // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease |
| 668 | bit IsAtomicOrderingAcquireRelease = ?; |
| 669 | // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent |
| 670 | bit IsAtomicOrderingSequentiallyConsistent = ?; |
| 671 | |
| 672 | // isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) |
| 673 | // !isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) |
| 674 | bit IsAtomicOrderingAcquireOrStronger = ?; |
| 675 | |
| 676 | // isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) |
| 677 | // !isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) |
| 678 | bit IsAtomicOrderingReleaseOrStronger = ?; |
| 679 | |
| 680 | // cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>; |
| 681 | // cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>; |
| 682 | ValueType MemoryVT = ?; |
| 683 | // cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; |
| 684 | // cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; |
| 685 | ValueType ScalarMemoryVT = ?; |
| 686 | } |
| 687 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 688 | // PatFrag - A version of PatFrags matching only a single fragment. |
| 689 | class PatFrag<dag ops, dag frag, code pred = [{}], |
| 690 | SDNodeXForm xform = NOOP_SDNodeXForm> |
| 691 | : PatFrags<ops, [frag], pred, xform>; |
| 692 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 693 | // OutPatFrag is a pattern fragment that is used as part of an output pattern |
| 694 | // (not an input pattern). These do not have predicates or transforms, but are |
| 695 | // used to avoid repeated subexpressions in output patterns. |
| 696 | class OutPatFrag<dag ops, dag frag> |
| 697 | : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>; |
| 698 | |
| 699 | // PatLeaf's are pattern fragments that have no operands. This is just a helper |
| 700 | // to define immediates and other common things concisely. |
| 701 | class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> |
| 702 | : PatFrag<(ops), frag, pred, xform>; |
| 703 | |
| 704 | |
| 705 | // ImmLeaf is a pattern fragment with a constraint on the immediate. The |
| 706 | // constraint is a function that is run on the immediate (always with the value |
| 707 | // sign extended out to an int64_t) as Imm. For example: |
| 708 | // |
| 709 | // def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>; |
| 710 | // |
| 711 | // this is a more convenient form to match 'imm' nodes in than PatLeaf and also |
| 712 | // is preferred over using PatLeaf because it allows the code generator to |
| 713 | // reason more about the constraint. |
| 714 | // |
| 715 | // If FastIsel should ignore all instructions that have an operand of this type, |
| 716 | // the FastIselShouldIgnore flag can be set. This is an optimization to reduce |
| 717 | // the code size of the generated fast instruction selector. |
| 718 | class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm, |
| 719 | SDNode ImmNode = imm> |
| 720 | : PatFrag<(ops), (vt ImmNode), [{}], xform> { |
| 721 | let ImmediateCode = pred; |
| 722 | bit FastIselShouldIgnore = 0; |
| 723 | |
| 724 | // Is the data type of the immediate an APInt? |
| 725 | bit IsAPInt = 0; |
| 726 | |
| 727 | // Is the data type of the immediate an APFloat? |
| 728 | bit IsAPFloat = 0; |
| 729 | } |
| 730 | |
| 731 | // An ImmLeaf except that Imm is an APInt. This is useful when you need to |
| 732 | // zero-extend the immediate instead of sign-extend it. |
| 733 | // |
| 734 | // Note that FastISel does not currently understand IntImmLeaf and will not |
| 735 | // generate code for rules that make use of it. As such, it does not make sense |
| 736 | // to replace ImmLeaf with IntImmLeaf. However, replacing PatLeaf with an |
| 737 | // IntImmLeaf will allow GlobalISel to import the rule. |
| 738 | class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> |
| 739 | : ImmLeaf<vt, pred, xform> { |
| 740 | let IsAPInt = 1; |
| 741 | let FastIselShouldIgnore = 1; |
| 742 | } |
| 743 | |
| 744 | // An ImmLeaf except that Imm is an APFloat. |
| 745 | // |
| 746 | // Note that FastISel does not currently understand FPImmLeaf and will not |
| 747 | // generate code for rules that make use of it. |
| 748 | class FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> |
| 749 | : ImmLeaf<vt, pred, xform, fpimm> { |
| 750 | let IsAPFloat = 1; |
| 751 | let FastIselShouldIgnore = 1; |
| 752 | } |
| 753 | |
| 754 | // Leaf fragments. |
| 755 | |
| 756 | def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; |
| 757 | def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; |
| 758 | |
| 759 | def immAllOnesV: PatLeaf<(build_vector), [{ |
| 760 | return ISD::isBuildVectorAllOnes(N); |
| 761 | }]>; |
| 762 | def immAllZerosV: PatLeaf<(build_vector), [{ |
| 763 | return ISD::isBuildVectorAllZeros(N); |
| 764 | }]>; |
| 765 | |
| 766 | |
| 767 | |
| 768 | // Other helper fragments. |
| 769 | def not : PatFrag<(ops node:$in), (xor node:$in, -1)>; |
| 770 | def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; |
| 771 | def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; |
| 772 | |
| 773 | // null_frag - The null pattern operator is used in multiclass instantiations |
| 774 | // which accept an SDPatternOperator for use in matching patterns for internal |
| 775 | // definitions. When expanding a pattern, if the null fragment is referenced |
| 776 | // in the expansion, the pattern is discarded and it is as-if '[]' had been |
| 777 | // specified. This allows multiclasses to have the isel patterns be optional. |
| 778 | def null_frag : SDPatternOperator; |
| 779 | |
| 780 | // load fragments. |
| 781 | def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> { |
| 782 | let IsLoad = 1; |
| 783 | let IsUnindexed = 1; |
| 784 | } |
| 785 | def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { |
| 786 | let IsLoad = 1; |
| 787 | let IsNonExtLoad = 1; |
| 788 | } |
| 789 | |
| 790 | // extending load fragments. |
| 791 | def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { |
| 792 | let IsLoad = 1; |
| 793 | let IsAnyExtLoad = 1; |
| 794 | } |
| 795 | def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { |
| 796 | let IsLoad = 1; |
| 797 | let IsSignExtLoad = 1; |
| 798 | } |
| 799 | def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { |
| 800 | let IsLoad = 1; |
| 801 | let IsZeroExtLoad = 1; |
| 802 | } |
| 803 | |
| 804 | def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 805 | let IsLoad = 1; |
| 806 | let MemoryVT = i1; |
| 807 | } |
| 808 | def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 809 | let IsLoad = 1; |
| 810 | let MemoryVT = i8; |
| 811 | } |
| 812 | def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 813 | let IsLoad = 1; |
| 814 | let MemoryVT = i16; |
| 815 | } |
| 816 | def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 817 | let IsLoad = 1; |
| 818 | let MemoryVT = i32; |
| 819 | } |
| 820 | def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 821 | let IsLoad = 1; |
| 822 | let MemoryVT = f32; |
| 823 | } |
| 824 | def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 825 | let IsLoad = 1; |
| 826 | let MemoryVT = f64; |
| 827 | } |
| 828 | |
| 829 | def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 830 | let IsLoad = 1; |
| 831 | let MemoryVT = i1; |
| 832 | } |
| 833 | def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 834 | let IsLoad = 1; |
| 835 | let MemoryVT = i8; |
| 836 | } |
| 837 | def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 838 | let IsLoad = 1; |
| 839 | let MemoryVT = i16; |
| 840 | } |
| 841 | def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 842 | let IsLoad = 1; |
| 843 | let MemoryVT = i32; |
| 844 | } |
| 845 | |
| 846 | def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 847 | let IsLoad = 1; |
| 848 | let MemoryVT = i1; |
| 849 | } |
| 850 | def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 851 | let IsLoad = 1; |
| 852 | let MemoryVT = i8; |
| 853 | } |
| 854 | def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 855 | let IsLoad = 1; |
| 856 | let MemoryVT = i16; |
| 857 | } |
| 858 | def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 859 | let IsLoad = 1; |
| 860 | let MemoryVT = i32; |
| 861 | } |
| 862 | |
| 863 | def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 864 | let IsLoad = 1; |
| 865 | let ScalarMemoryVT = i1; |
| 866 | } |
| 867 | def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 868 | let IsLoad = 1; |
| 869 | let ScalarMemoryVT = i8; |
| 870 | } |
| 871 | def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 872 | let IsLoad = 1; |
| 873 | let ScalarMemoryVT = i16; |
| 874 | } |
| 875 | def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 876 | let IsLoad = 1; |
| 877 | let ScalarMemoryVT = i32; |
| 878 | } |
| 879 | def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 880 | let IsLoad = 1; |
| 881 | let ScalarMemoryVT = f32; |
| 882 | } |
| 883 | def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { |
| 884 | let IsLoad = 1; |
| 885 | let ScalarMemoryVT = f64; |
| 886 | } |
| 887 | |
| 888 | def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 889 | let IsLoad = 1; |
| 890 | let ScalarMemoryVT = i1; |
| 891 | } |
| 892 | def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 893 | let IsLoad = 1; |
| 894 | let ScalarMemoryVT = i8; |
| 895 | } |
| 896 | def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 897 | let IsLoad = 1; |
| 898 | let ScalarMemoryVT = i16; |
| 899 | } |
| 900 | def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { |
| 901 | let IsLoad = 1; |
| 902 | let ScalarMemoryVT = i32; |
| 903 | } |
| 904 | |
| 905 | def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 906 | let IsLoad = 1; |
| 907 | let ScalarMemoryVT = i1; |
| 908 | } |
| 909 | def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 910 | let IsLoad = 1; |
| 911 | let ScalarMemoryVT = i8; |
| 912 | } |
| 913 | def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 914 | let IsLoad = 1; |
| 915 | let ScalarMemoryVT = i16; |
| 916 | } |
| 917 | def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { |
| 918 | let IsLoad = 1; |
| 919 | let ScalarMemoryVT = i32; |
| 920 | } |
| 921 | |
| 922 | // store fragments. |
| 923 | def unindexedstore : PatFrag<(ops node:$val, node:$ptr), |
| 924 | (st node:$val, node:$ptr)> { |
| 925 | let IsStore = 1; |
| 926 | let IsUnindexed = 1; |
| 927 | } |
| 928 | def store : PatFrag<(ops node:$val, node:$ptr), |
| 929 | (unindexedstore node:$val, node:$ptr)> { |
| 930 | let IsStore = 1; |
| 931 | let IsTruncStore = 0; |
| 932 | } |
| 933 | |
| 934 | // truncstore fragments. |
| 935 | def truncstore : PatFrag<(ops node:$val, node:$ptr), |
| 936 | (unindexedstore node:$val, node:$ptr)> { |
| 937 | let IsStore = 1; |
| 938 | let IsTruncStore = 1; |
| 939 | } |
| 940 | def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), |
| 941 | (truncstore node:$val, node:$ptr)> { |
| 942 | let IsStore = 1; |
| 943 | let MemoryVT = i8; |
| 944 | } |
| 945 | def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), |
| 946 | (truncstore node:$val, node:$ptr)> { |
| 947 | let IsStore = 1; |
| 948 | let MemoryVT = i16; |
| 949 | } |
| 950 | def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), |
| 951 | (truncstore node:$val, node:$ptr)> { |
| 952 | let IsStore = 1; |
| 953 | let MemoryVT = i32; |
| 954 | } |
| 955 | def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), |
| 956 | (truncstore node:$val, node:$ptr)> { |
| 957 | let IsStore = 1; |
| 958 | let MemoryVT = f32; |
| 959 | } |
| 960 | def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), |
| 961 | (truncstore node:$val, node:$ptr)> { |
| 962 | let IsStore = 1; |
| 963 | let MemoryVT = f64; |
| 964 | } |
| 965 | |
| 966 | def truncstorevi8 : PatFrag<(ops node:$val, node:$ptr), |
| 967 | (truncstore node:$val, node:$ptr)> { |
| 968 | let IsStore = 1; |
| 969 | let ScalarMemoryVT = i8; |
| 970 | } |
| 971 | |
| 972 | def truncstorevi16 : PatFrag<(ops node:$val, node:$ptr), |
| 973 | (truncstore node:$val, node:$ptr)> { |
| 974 | let IsStore = 1; |
| 975 | let ScalarMemoryVT = i16; |
| 976 | } |
| 977 | |
| 978 | def truncstorevi32 : PatFrag<(ops node:$val, node:$ptr), |
| 979 | (truncstore node:$val, node:$ptr)> { |
| 980 | let IsStore = 1; |
| 981 | let ScalarMemoryVT = i32; |
| 982 | } |
| 983 | |
| 984 | // indexed store fragments. |
| 985 | def istore : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 986 | (ist node:$val, node:$base, node:$offset)> { |
| 987 | let IsStore = 1; |
| 988 | let IsTruncStore = 0; |
| 989 | } |
| 990 | |
| 991 | def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 992 | (istore node:$val, node:$base, node:$offset), [{ |
| 993 | ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); |
| 994 | return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; |
| 995 | }]>; |
| 996 | |
| 997 | def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 998 | (ist node:$val, node:$base, node:$offset)> { |
| 999 | let IsStore = 1; |
| 1000 | let IsTruncStore = 1; |
| 1001 | } |
| 1002 | def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1003 | (itruncstore node:$val, node:$base, node:$offset), [{ |
| 1004 | ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); |
| 1005 | return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; |
| 1006 | }]>; |
| 1007 | def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1008 | (pre_truncst node:$val, node:$base, node:$offset)> { |
| 1009 | let IsStore = 1; |
| 1010 | let MemoryVT = i1; |
| 1011 | } |
| 1012 | def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1013 | (pre_truncst node:$val, node:$base, node:$offset)> { |
| 1014 | let IsStore = 1; |
| 1015 | let MemoryVT = i8; |
| 1016 | } |
| 1017 | def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1018 | (pre_truncst node:$val, node:$base, node:$offset)> { |
| 1019 | let IsStore = 1; |
| 1020 | let MemoryVT = i16; |
| 1021 | } |
| 1022 | def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1023 | (pre_truncst node:$val, node:$base, node:$offset)> { |
| 1024 | let IsStore = 1; |
| 1025 | let MemoryVT = i32; |
| 1026 | } |
| 1027 | def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1028 | (pre_truncst node:$val, node:$base, node:$offset)> { |
| 1029 | let IsStore = 1; |
| 1030 | let MemoryVT = f32; |
| 1031 | } |
| 1032 | |
| 1033 | def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), |
| 1034 | (istore node:$val, node:$ptr, node:$offset), [{ |
| 1035 | ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); |
| 1036 | return AM == ISD::POST_INC || AM == ISD::POST_DEC; |
| 1037 | }]>; |
| 1038 | |
| 1039 | def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1040 | (itruncstore node:$val, node:$base, node:$offset), [{ |
| 1041 | ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); |
| 1042 | return AM == ISD::POST_INC || AM == ISD::POST_DEC; |
| 1043 | }]>; |
| 1044 | def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1045 | (post_truncst node:$val, node:$base, node:$offset)> { |
| 1046 | let IsStore = 1; |
| 1047 | let MemoryVT = i1; |
| 1048 | } |
| 1049 | def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1050 | (post_truncst node:$val, node:$base, node:$offset)> { |
| 1051 | let IsStore = 1; |
| 1052 | let MemoryVT = i8; |
| 1053 | } |
| 1054 | def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1055 | (post_truncst node:$val, node:$base, node:$offset)> { |
| 1056 | let IsStore = 1; |
| 1057 | let MemoryVT = i16; |
| 1058 | } |
| 1059 | def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1060 | (post_truncst node:$val, node:$base, node:$offset)> { |
| 1061 | let IsStore = 1; |
| 1062 | let MemoryVT = i32; |
| 1063 | } |
| 1064 | def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), |
| 1065 | (post_truncst node:$val, node:$base, node:$offset)> { |
| 1066 | let IsStore = 1; |
| 1067 | let MemoryVT = f32; |
| 1068 | } |
| 1069 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame^] | 1070 | def nonvolatile_load : PatFrag<(ops node:$ptr), |
| 1071 | (load node:$ptr), [{ |
| 1072 | return !cast<LoadSDNode>(N)->isVolatile(); |
| 1073 | }]>; |
| 1074 | def nonvolatile_store : PatFrag<(ops node:$val, node:$ptr), |
| 1075 | (store node:$val, node:$ptr), [{ |
| 1076 | return !cast<StoreSDNode>(N)->isVolatile(); |
| 1077 | }]>; |
| 1078 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1079 | // nontemporal store fragments. |
| 1080 | def nontemporalstore : PatFrag<(ops node:$val, node:$ptr), |
| 1081 | (store node:$val, node:$ptr), [{ |
| 1082 | return cast<StoreSDNode>(N)->isNonTemporal(); |
| 1083 | }]>; |
| 1084 | |
| 1085 | def alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), |
| 1086 | (nontemporalstore node:$val, node:$ptr), [{ |
| 1087 | StoreSDNode *St = cast<StoreSDNode>(N); |
| 1088 | return St->getAlignment() >= St->getMemoryVT().getStoreSize(); |
| 1089 | }]>; |
| 1090 | |
| 1091 | def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), |
| 1092 | (nontemporalstore node:$val, node:$ptr), [{ |
| 1093 | StoreSDNode *St = cast<StoreSDNode>(N); |
| 1094 | return St->getAlignment() < St->getMemoryVT().getStoreSize(); |
| 1095 | }]>; |
| 1096 | |
| 1097 | // nontemporal load fragments. |
| 1098 | def nontemporalload : PatFrag<(ops node:$ptr), |
| 1099 | (load node:$ptr), [{ |
| 1100 | return cast<LoadSDNode>(N)->isNonTemporal(); |
| 1101 | }]>; |
| 1102 | |
| 1103 | def alignednontemporalload : PatFrag<(ops node:$ptr), |
| 1104 | (nontemporalload node:$ptr), [{ |
| 1105 | LoadSDNode *Ld = cast<LoadSDNode>(N); |
| 1106 | return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); |
| 1107 | }]>; |
| 1108 | |
| 1109 | // setcc convenience fragments. |
| 1110 | def setoeq : PatFrag<(ops node:$lhs, node:$rhs), |
| 1111 | (setcc node:$lhs, node:$rhs, SETOEQ)>; |
| 1112 | def setogt : PatFrag<(ops node:$lhs, node:$rhs), |
| 1113 | (setcc node:$lhs, node:$rhs, SETOGT)>; |
| 1114 | def setoge : PatFrag<(ops node:$lhs, node:$rhs), |
| 1115 | (setcc node:$lhs, node:$rhs, SETOGE)>; |
| 1116 | def setolt : PatFrag<(ops node:$lhs, node:$rhs), |
| 1117 | (setcc node:$lhs, node:$rhs, SETOLT)>; |
| 1118 | def setole : PatFrag<(ops node:$lhs, node:$rhs), |
| 1119 | (setcc node:$lhs, node:$rhs, SETOLE)>; |
| 1120 | def setone : PatFrag<(ops node:$lhs, node:$rhs), |
| 1121 | (setcc node:$lhs, node:$rhs, SETONE)>; |
| 1122 | def seto : PatFrag<(ops node:$lhs, node:$rhs), |
| 1123 | (setcc node:$lhs, node:$rhs, SETO)>; |
| 1124 | def setuo : PatFrag<(ops node:$lhs, node:$rhs), |
| 1125 | (setcc node:$lhs, node:$rhs, SETUO)>; |
| 1126 | def setueq : PatFrag<(ops node:$lhs, node:$rhs), |
| 1127 | (setcc node:$lhs, node:$rhs, SETUEQ)>; |
| 1128 | def setugt : PatFrag<(ops node:$lhs, node:$rhs), |
| 1129 | (setcc node:$lhs, node:$rhs, SETUGT)>; |
| 1130 | def setuge : PatFrag<(ops node:$lhs, node:$rhs), |
| 1131 | (setcc node:$lhs, node:$rhs, SETUGE)>; |
| 1132 | def setult : PatFrag<(ops node:$lhs, node:$rhs), |
| 1133 | (setcc node:$lhs, node:$rhs, SETULT)>; |
| 1134 | def setule : PatFrag<(ops node:$lhs, node:$rhs), |
| 1135 | (setcc node:$lhs, node:$rhs, SETULE)>; |
| 1136 | def setune : PatFrag<(ops node:$lhs, node:$rhs), |
| 1137 | (setcc node:$lhs, node:$rhs, SETUNE)>; |
| 1138 | def seteq : PatFrag<(ops node:$lhs, node:$rhs), |
| 1139 | (setcc node:$lhs, node:$rhs, SETEQ)>; |
| 1140 | def setgt : PatFrag<(ops node:$lhs, node:$rhs), |
| 1141 | (setcc node:$lhs, node:$rhs, SETGT)>; |
| 1142 | def setge : PatFrag<(ops node:$lhs, node:$rhs), |
| 1143 | (setcc node:$lhs, node:$rhs, SETGE)>; |
| 1144 | def setlt : PatFrag<(ops node:$lhs, node:$rhs), |
| 1145 | (setcc node:$lhs, node:$rhs, SETLT)>; |
| 1146 | def setle : PatFrag<(ops node:$lhs, node:$rhs), |
| 1147 | (setcc node:$lhs, node:$rhs, SETLE)>; |
| 1148 | def setne : PatFrag<(ops node:$lhs, node:$rhs), |
| 1149 | (setcc node:$lhs, node:$rhs, SETNE)>; |
| 1150 | |
| 1151 | multiclass binary_atomic_op_ord<SDNode atomic_op> { |
| 1152 | def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val), |
| 1153 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> { |
| 1154 | let IsAtomic = 1; |
| 1155 | let IsAtomicOrderingMonotonic = 1; |
| 1156 | } |
| 1157 | def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val), |
| 1158 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> { |
| 1159 | let IsAtomic = 1; |
| 1160 | let IsAtomicOrderingAcquire = 1; |
| 1161 | } |
| 1162 | def #NAME#_release : PatFrag<(ops node:$ptr, node:$val), |
| 1163 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> { |
| 1164 | let IsAtomic = 1; |
| 1165 | let IsAtomicOrderingRelease = 1; |
| 1166 | } |
| 1167 | def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val), |
| 1168 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> { |
| 1169 | let IsAtomic = 1; |
| 1170 | let IsAtomicOrderingAcquireRelease = 1; |
| 1171 | } |
| 1172 | def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val), |
| 1173 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> { |
| 1174 | let IsAtomic = 1; |
| 1175 | let IsAtomicOrderingSequentiallyConsistent = 1; |
| 1176 | } |
| 1177 | } |
| 1178 | |
| 1179 | multiclass ternary_atomic_op_ord<SDNode atomic_op> { |
| 1180 | def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1181 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> { |
| 1182 | let IsAtomic = 1; |
| 1183 | let IsAtomicOrderingMonotonic = 1; |
| 1184 | } |
| 1185 | def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1186 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> { |
| 1187 | let IsAtomic = 1; |
| 1188 | let IsAtomicOrderingAcquire = 1; |
| 1189 | } |
| 1190 | def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1191 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> { |
| 1192 | let IsAtomic = 1; |
| 1193 | let IsAtomicOrderingRelease = 1; |
| 1194 | } |
| 1195 | def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1196 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> { |
| 1197 | let IsAtomic = 1; |
| 1198 | let IsAtomicOrderingAcquireRelease = 1; |
| 1199 | } |
| 1200 | def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1201 | (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> { |
| 1202 | let IsAtomic = 1; |
| 1203 | let IsAtomicOrderingSequentiallyConsistent = 1; |
| 1204 | } |
| 1205 | } |
| 1206 | |
| 1207 | multiclass binary_atomic_op<SDNode atomic_op> { |
| 1208 | def _8 : PatFrag<(ops node:$ptr, node:$val), |
| 1209 | (atomic_op node:$ptr, node:$val)> { |
| 1210 | let IsAtomic = 1; |
| 1211 | let MemoryVT = i8; |
| 1212 | } |
| 1213 | def _16 : PatFrag<(ops node:$ptr, node:$val), |
| 1214 | (atomic_op node:$ptr, node:$val)> { |
| 1215 | let IsAtomic = 1; |
| 1216 | let MemoryVT = i16; |
| 1217 | } |
| 1218 | def _32 : PatFrag<(ops node:$ptr, node:$val), |
| 1219 | (atomic_op node:$ptr, node:$val)> { |
| 1220 | let IsAtomic = 1; |
| 1221 | let MemoryVT = i32; |
| 1222 | } |
| 1223 | def _64 : PatFrag<(ops node:$ptr, node:$val), |
| 1224 | (atomic_op node:$ptr, node:$val)> { |
| 1225 | let IsAtomic = 1; |
| 1226 | let MemoryVT = i64; |
| 1227 | } |
| 1228 | |
| 1229 | defm NAME#_8 : binary_atomic_op_ord<atomic_op>; |
| 1230 | defm NAME#_16 : binary_atomic_op_ord<atomic_op>; |
| 1231 | defm NAME#_32 : binary_atomic_op_ord<atomic_op>; |
| 1232 | defm NAME#_64 : binary_atomic_op_ord<atomic_op>; |
| 1233 | } |
| 1234 | |
| 1235 | multiclass ternary_atomic_op<SDNode atomic_op> { |
| 1236 | def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1237 | (atomic_op node:$ptr, node:$cmp, node:$val)> { |
| 1238 | let IsAtomic = 1; |
| 1239 | let MemoryVT = i8; |
| 1240 | } |
| 1241 | def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1242 | (atomic_op node:$ptr, node:$cmp, node:$val)> { |
| 1243 | let IsAtomic = 1; |
| 1244 | let MemoryVT = i16; |
| 1245 | } |
| 1246 | def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1247 | (atomic_op node:$ptr, node:$cmp, node:$val)> { |
| 1248 | let IsAtomic = 1; |
| 1249 | let MemoryVT = i32; |
| 1250 | } |
| 1251 | def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val), |
| 1252 | (atomic_op node:$ptr, node:$cmp, node:$val)> { |
| 1253 | let IsAtomic = 1; |
| 1254 | let MemoryVT = i64; |
| 1255 | } |
| 1256 | |
| 1257 | defm NAME#_8 : ternary_atomic_op_ord<atomic_op>; |
| 1258 | defm NAME#_16 : ternary_atomic_op_ord<atomic_op>; |
| 1259 | defm NAME#_32 : ternary_atomic_op_ord<atomic_op>; |
| 1260 | defm NAME#_64 : ternary_atomic_op_ord<atomic_op>; |
| 1261 | } |
| 1262 | |
| 1263 | defm atomic_load_add : binary_atomic_op<atomic_load_add>; |
| 1264 | defm atomic_swap : binary_atomic_op<atomic_swap>; |
| 1265 | defm atomic_load_sub : binary_atomic_op<atomic_load_sub>; |
| 1266 | defm atomic_load_and : binary_atomic_op<atomic_load_and>; |
| 1267 | defm atomic_load_clr : binary_atomic_op<atomic_load_clr>; |
| 1268 | defm atomic_load_or : binary_atomic_op<atomic_load_or>; |
| 1269 | defm atomic_load_xor : binary_atomic_op<atomic_load_xor>; |
| 1270 | defm atomic_load_nand : binary_atomic_op<atomic_load_nand>; |
| 1271 | defm atomic_load_min : binary_atomic_op<atomic_load_min>; |
| 1272 | defm atomic_load_max : binary_atomic_op<atomic_load_max>; |
| 1273 | defm atomic_load_umin : binary_atomic_op<atomic_load_umin>; |
| 1274 | defm atomic_load_umax : binary_atomic_op<atomic_load_umax>; |
| 1275 | defm atomic_store : binary_atomic_op<atomic_store>; |
| 1276 | defm atomic_cmp_swap : ternary_atomic_op<atomic_cmp_swap>; |
| 1277 | |
| 1278 | def atomic_load_8 : |
| 1279 | PatFrag<(ops node:$ptr), |
| 1280 | (atomic_load node:$ptr)> { |
| 1281 | let IsAtomic = 1; |
| 1282 | let MemoryVT = i8; |
| 1283 | } |
| 1284 | def atomic_load_16 : |
| 1285 | PatFrag<(ops node:$ptr), |
| 1286 | (atomic_load node:$ptr)> { |
| 1287 | let IsAtomic = 1; |
| 1288 | let MemoryVT = i16; |
| 1289 | } |
| 1290 | def atomic_load_32 : |
| 1291 | PatFrag<(ops node:$ptr), |
| 1292 | (atomic_load node:$ptr)> { |
| 1293 | let IsAtomic = 1; |
| 1294 | let MemoryVT = i32; |
| 1295 | } |
| 1296 | def atomic_load_64 : |
| 1297 | PatFrag<(ops node:$ptr), |
| 1298 | (atomic_load node:$ptr)> { |
| 1299 | let IsAtomic = 1; |
| 1300 | let MemoryVT = i64; |
| 1301 | } |
| 1302 | |
| 1303 | //===----------------------------------------------------------------------===// |
| 1304 | // Selection DAG Pattern Support. |
| 1305 | // |
| 1306 | // Patterns are what are actually matched against by the target-flavored |
| 1307 | // instruction selection DAG. Instructions defined by the target implicitly |
| 1308 | // define patterns in most cases, but patterns can also be explicitly added when |
| 1309 | // an operation is defined by a sequence of instructions (e.g. loading a large |
| 1310 | // immediate value on RISC targets that do not support immediates as large as |
| 1311 | // their GPRs). |
| 1312 | // |
| 1313 | |
| 1314 | class Pattern<dag patternToMatch, list<dag> resultInstrs> { |
| 1315 | dag PatternToMatch = patternToMatch; |
| 1316 | list<dag> ResultInstrs = resultInstrs; |
| 1317 | list<Predicate> Predicates = []; // See class Instruction in Target.td. |
| 1318 | int AddedComplexity = 0; // See class Instruction in Target.td. |
| 1319 | } |
| 1320 | |
| 1321 | // Pat - A simple (but common) form of a pattern, which produces a simple result |
| 1322 | // not needing a full list. |
| 1323 | class Pat<dag pattern, dag result> : Pattern<pattern, [result]>; |
| 1324 | |
| 1325 | //===----------------------------------------------------------------------===// |
| 1326 | // Complex pattern definitions. |
| 1327 | // |
| 1328 | |
| 1329 | // Complex patterns, e.g. X86 addressing mode, requires pattern matching code |
| 1330 | // in C++. NumOperands is the number of operands returned by the select function; |
| 1331 | // SelectFunc is the name of the function used to pattern match the max. pattern; |
| 1332 | // RootNodes are the list of possible root nodes of the sub-dags to match. |
| 1333 | // e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; |
| 1334 | // |
| 1335 | class ComplexPattern<ValueType ty, int numops, string fn, |
| 1336 | list<SDNode> roots = [], list<SDNodeProperty> props = [], |
| 1337 | int complexity = -1> { |
| 1338 | ValueType Ty = ty; |
| 1339 | int NumOperands = numops; |
| 1340 | string SelectFunc = fn; |
| 1341 | list<SDNode> RootNodes = roots; |
| 1342 | list<SDNodeProperty> Properties = props; |
| 1343 | int Complexity = complexity; |
| 1344 | } |