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