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