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