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