10b57cec5SDimitry Andric//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file defines the target-independent interfaces used by SelectionDAG
100b57cec5SDimitry Andric// instruction selection generators.
110b57cec5SDimitry Andric//
120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric// Selection DAG Type Constraint definitions.
160b57cec5SDimitry Andric//
170b57cec5SDimitry Andric// Note that the semantics of these constraints are hard coded into tblgen.  To
180b57cec5SDimitry Andric// modify or add constraints, you have to hack tblgen.
190b57cec5SDimitry Andric//
200b57cec5SDimitry Andric
210b57cec5SDimitry Andricclass SDTypeConstraint<int opnum> {
220b57cec5SDimitry Andric  int OperandNum = opnum;
230b57cec5SDimitry Andric}
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric// SDTCisVT - The specified operand has exactly this VT.
260b57cec5SDimitry Andricclass SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
270b57cec5SDimitry Andric  ValueType VT = vt;
280b57cec5SDimitry Andric}
290b57cec5SDimitry Andric
300b57cec5SDimitry Andricclass SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>;
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric// SDTCisInt - The specified operand has integer type.
330b57cec5SDimitry Andricclass SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric// SDTCisFP - The specified operand has floating-point type.
360b57cec5SDimitry Andricclass SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric// SDTCisVec - The specified operand has a vector type.
390b57cec5SDimitry Andricclass SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>;
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric// SDTCisSameAs - The two specified operands have identical types.
420b57cec5SDimitry Andricclass SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
430b57cec5SDimitry Andric  int OtherOperandNum = OtherOp;
440b57cec5SDimitry Andric}
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is
470b57cec5SDimitry Andric// smaller than the 'Other' operand.
480b57cec5SDimitry Andricclass SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
490b57cec5SDimitry Andric  int OtherOperandNum = OtherOp;
500b57cec5SDimitry Andric}
510b57cec5SDimitry Andric
520b57cec5SDimitry Andricclass SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{
530b57cec5SDimitry Andric  int BigOperandNum = BigOp;
540b57cec5SDimitry Andric}
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
570b57cec5SDimitry Andric/// type as the element type of OtherOp, which is a vector type.
580b57cec5SDimitry Andricclass SDTCisEltOfVec<int ThisOp, int OtherOp>
590b57cec5SDimitry Andric  : SDTypeConstraint<ThisOp> {
600b57cec5SDimitry Andric  int OtherOpNum = OtherOp;
610b57cec5SDimitry Andric}
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type
640b57cec5SDimitry Andric/// with length less that of OtherOp, which is a vector type.
650b57cec5SDimitry Andricclass SDTCisSubVecOfVec<int ThisOp, int OtherOp>
660b57cec5SDimitry Andric  : SDTypeConstraint<ThisOp> {
670b57cec5SDimitry Andric  int OtherOpNum = OtherOp;
680b57cec5SDimitry Andric}
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric// SDTCVecEltisVT - The specified operand is vector type with element type
710b57cec5SDimitry Andric// of VT.
720b57cec5SDimitry Andricclass SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
730b57cec5SDimitry Andric  ValueType VT = vt;
740b57cec5SDimitry Andric}
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric// SDTCisSameNumEltsAs - The two specified operands have identical number
770b57cec5SDimitry Andric// of elements.
780b57cec5SDimitry Andricclass SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
790b57cec5SDimitry Andric  int OtherOperandNum = OtherOp;
800b57cec5SDimitry Andric}
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric// SDTCisSameSizeAs - The two specified operands have identical size.
830b57cec5SDimitry Andricclass SDTCisSameSizeAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
840b57cec5SDimitry Andric  int OtherOperandNum = OtherOp;
850b57cec5SDimitry Andric}
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
880b57cec5SDimitry Andric// Selection DAG Type Profile definitions.
890b57cec5SDimitry Andric//
900b57cec5SDimitry Andric// These use the constraints defined above to describe the type requirements of
910b57cec5SDimitry Andric// the various nodes.  These are not hard coded into tblgen, allowing targets to
920b57cec5SDimitry Andric// add their own if needed.
930b57cec5SDimitry Andric//
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric// SDTypeProfile - This profile describes the type requirements of a Selection
960b57cec5SDimitry Andric// DAG node.
970b57cec5SDimitry Andricclass SDTypeProfile<int numresults, int numoperands,
980b57cec5SDimitry Andric                    list<SDTypeConstraint> constraints> {
990b57cec5SDimitry Andric  int NumResults = numresults;
1000b57cec5SDimitry Andric  int NumOperands = numoperands;
1010b57cec5SDimitry Andric  list<SDTypeConstraint> Constraints = constraints;
1020b57cec5SDimitry Andric}
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric// Builtin profiles.
1050b57cec5SDimitry Andricdef SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>;         // for 'imm'.
1060b57cec5SDimitry Andricdef SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>;          // for 'fpimm'.
1070b57cec5SDimitry Andricdef SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;       // for '&g'.
1080b57cec5SDimitry Andricdef SDTOther  : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'.
1090b57cec5SDimitry Andricdef SDTUNDEF  : SDTypeProfile<1, 0, []>;                     // for 'undef'.
1100b57cec5SDimitry Andricdef SDTUnaryOp  : SDTypeProfile<1, 1, []>;                   // for bitconvert.
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andricdef SDTIntBinOp : SDTypeProfile<1, 2, [     // add, and, or, xor, udiv, etc.
1130b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>
1140b57cec5SDimitry Andric]>;
1150b57cec5SDimitry Andricdef SDTIntShiftOp : SDTypeProfile<1, 2, [   // shl, sra, srl
1160b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>
1170b57cec5SDimitry Andric]>;
1180b57cec5SDimitry Andricdef SDTIntShiftDOp: SDTypeProfile<1, 3, [   // fshl, fshr
1190b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3>
1200b57cec5SDimitry Andric]>;
1210b57cec5SDimitry Andricdef SDTIntSatNoShOp : SDTypeProfile<1, 2, [   // ssat with no shift
1220b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisInt<2>
1230b57cec5SDimitry Andric]>;
1240b57cec5SDimitry Andricdef SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem
1250b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0>
1260b57cec5SDimitry Andric]>;
127480093f4SDimitry Andricdef SDTIntScaledBinOp : SDTypeProfile<1, 3, [  // smulfix, sdivfix, etc
1280b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3>
1290b57cec5SDimitry Andric]>;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andricdef SDTFPBinOp : SDTypeProfile<1, 2, [      // fadd, fmul, etc.
1320b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
1330b57cec5SDimitry Andric]>;
1340b57cec5SDimitry Andricdef SDTFPSignOp : SDTypeProfile<1, 2, [     // fcopysign.
1350b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2>
1360b57cec5SDimitry Andric]>;
1370b57cec5SDimitry Andricdef SDTFPTernaryOp : SDTypeProfile<1, 3, [  // fmadd, fnmsub, etc.
1380b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0>
1390b57cec5SDimitry Andric]>;
1408bcb0991SDimitry Andricdef SDTIntUnaryOp : SDTypeProfile<1, 1, [ // bitreverse
1410b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisInt<0>
1420b57cec5SDimitry Andric]>;
1438bcb0991SDimitry Andricdef SDTIntBitCountUnaryOp : SDTypeProfile<1, 1, [   // ctlz, cttz
1448bcb0991SDimitry Andric  SDTCisInt<0>, SDTCisInt<1>
1458bcb0991SDimitry Andric]>;
1460b57cec5SDimitry Andricdef SDTIntExtendOp : SDTypeProfile<1, 1, [  // sext, zext, anyext
1470b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
1480b57cec5SDimitry Andric]>;
1490b57cec5SDimitry Andricdef SDTIntTruncOp  : SDTypeProfile<1, 1, [  // trunc
1500b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
1510b57cec5SDimitry Andric]>;
1520b57cec5SDimitry Andricdef SDTFPUnaryOp  : SDTypeProfile<1, 1, [   // fneg, fsqrt, etc
1530b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisFP<0>
1540b57cec5SDimitry Andric]>;
155fe6060f1SDimitry Andricdef SDTFPRoundOp  : SDTypeProfile<1, 1, [   // fpround
1560b57cec5SDimitry Andric  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
1570b57cec5SDimitry Andric]>;
158fe6060f1SDimitry Andricdef SDTFPExtendOp  : SDTypeProfile<1, 1, [  // fpextend
1590b57cec5SDimitry Andric  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
1600b57cec5SDimitry Andric]>;
1610b57cec5SDimitry Andricdef SDTIntToFPOp : SDTypeProfile<1, 1, [    // [su]int_to_fp
1620b57cec5SDimitry Andric  SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>
1630b57cec5SDimitry Andric]>;
1640b57cec5SDimitry Andricdef SDTFPToIntOp : SDTypeProfile<1, 1, [    // fp_to_[su]int
1650b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>
1660b57cec5SDimitry Andric]>;
167e8d8bef9SDimitry Andricdef SDTFPToIntSatOp : SDTypeProfile<1, 2, [    // fp_to_[su]int_sat
168fe6060f1SDimitry Andric  SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, OtherVT>
169e8d8bef9SDimitry Andric]>;
1700b57cec5SDimitry Andricdef SDTExtInreg : SDTypeProfile<1, 2, [     // sext_inreg
1710b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
1720b57cec5SDimitry Andric  SDTCisVTSmallerThanOp<2, 1>
1730b57cec5SDimitry Andric]>;
1740b57cec5SDimitry Andricdef SDTExtInvec : SDTypeProfile<1, 1, [     // sext_invec
1750b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>,
1760b57cec5SDimitry Andric  SDTCisOpSmallerThanOp<1, 0>
1770b57cec5SDimitry Andric]>;
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andricdef SDTSetCC : SDTypeProfile<1, 3, [        // setcc
1800b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
1810b57cec5SDimitry Andric]>;
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andricdef SDTSelect : SDTypeProfile<1, 3, [       // select
1840b57cec5SDimitry Andric  SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
1850b57cec5SDimitry Andric]>;
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andricdef SDTVSelect : SDTypeProfile<1, 3, [       // vselect
1880b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1>
1890b57cec5SDimitry Andric]>;
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andricdef SDTSelectCC : SDTypeProfile<1, 5, [     // select_cc
1920b57cec5SDimitry Andric  SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>,
1930b57cec5SDimitry Andric  SDTCisVT<5, OtherVT>
1940b57cec5SDimitry Andric]>;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andricdef SDTBr : SDTypeProfile<0, 1, [           // br
1970b57cec5SDimitry Andric  SDTCisVT<0, OtherVT>
1980b57cec5SDimitry Andric]>;
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andricdef SDTBrCC : SDTypeProfile<0, 4, [       // brcc
2010b57cec5SDimitry Andric  SDTCisVT<0, OtherVT>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
2020b57cec5SDimitry Andric]>;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andricdef SDTBrcond : SDTypeProfile<0, 2, [       // brcond
2050b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisVT<1, OtherVT>
2060b57cec5SDimitry Andric]>;
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andricdef SDTBrind : SDTypeProfile<0, 1, [        // brind
2090b57cec5SDimitry Andric  SDTCisPtrTy<0>
2100b57cec5SDimitry Andric]>;
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andricdef SDTCatchret : SDTypeProfile<0, 2, [     // catchret
2130b57cec5SDimitry Andric  SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>
2140b57cec5SDimitry Andric]>;
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andricdef SDTNone : SDTypeProfile<0, 0, []>;      // ret, trap
2170b57cec5SDimitry Andric
218e8d8bef9SDimitry Andricdef SDTUBSANTrap : SDTypeProfile<0, 1, []>;      // ubsantrap
219e8d8bef9SDimitry Andric
2200b57cec5SDimitry Andricdef SDTLoad : SDTypeProfile<1, 1, [         // load
2210b57cec5SDimitry Andric  SDTCisPtrTy<1>
2220b57cec5SDimitry Andric]>;
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andricdef SDTStore : SDTypeProfile<0, 2, [        // store
2250b57cec5SDimitry Andric  SDTCisPtrTy<1>
2260b57cec5SDimitry Andric]>;
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andricdef SDTIStore : SDTypeProfile<1, 3, [       // indexed store
2290b57cec5SDimitry Andric  SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3>
2300b57cec5SDimitry Andric]>;
2310b57cec5SDimitry Andric
232480093f4SDimitry Andricdef SDTMaskedStore: SDTypeProfile<0, 4, [       // masked store
233480093f4SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameNumEltsAs<0, 3>
2340b57cec5SDimitry Andric]>;
2350b57cec5SDimitry Andric
236480093f4SDimitry Andricdef SDTMaskedLoad: SDTypeProfile<1, 4, [       // masked load
237480093f4SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameAs<0, 4>,
238480093f4SDimitry Andric  SDTCisSameNumEltsAs<0, 3>
2390b57cec5SDimitry Andric]>;
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andricdef SDTVecShuffle : SDTypeProfile<1, 2, [
2420b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
2430b57cec5SDimitry Andric]>;
244fe6060f1SDimitry Andricdef SDTVecSlice : SDTypeProfile<1, 3, [     // vector splice
245fe6060f1SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisInt<3>
246fe6060f1SDimitry Andric]>;
2470b57cec5SDimitry Andricdef SDTVecExtract : SDTypeProfile<1, 2, [   // vector extract
2480b57cec5SDimitry Andric  SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2>
2490b57cec5SDimitry Andric]>;
2500b57cec5SDimitry Andricdef SDTVecInsert : SDTypeProfile<1, 3, [    // vector insert
2510b57cec5SDimitry Andric  SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
2520b57cec5SDimitry Andric]>;
2538bcb0991SDimitry Andricdef SDTVecReduce : SDTypeProfile<1, 1, [    // vector reduction
2548bcb0991SDimitry Andric  SDTCisInt<0>, SDTCisVec<1>
2558bcb0991SDimitry Andric]>;
256e8d8bef9SDimitry Andricdef SDTFPVecReduce : SDTypeProfile<1, 1, [  // FP vector reduction
257e8d8bef9SDimitry Andric  SDTCisFP<0>, SDTCisVec<1>
258e8d8bef9SDimitry Andric]>;
259e8d8bef9SDimitry Andric
260fe6060f1SDimitry Andricdef SDTVecReverse : SDTypeProfile<1, 1, [  // vector reverse
261fe6060f1SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0,1>
262fe6060f1SDimitry Andric]>;
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andricdef SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
2650b57cec5SDimitry Andric  SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
2660b57cec5SDimitry Andric]>;
2670b57cec5SDimitry Andricdef SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
2680b57cec5SDimitry Andric  SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
2690b57cec5SDimitry Andric]>;
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andricdef SDTPrefetch : SDTypeProfile<0, 4, [     // prefetch
2720b57cec5SDimitry Andric  SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1>
2730b57cec5SDimitry Andric]>;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andricdef SDTMemBarrier : SDTypeProfile<0, 5, [   // memory barrier
2760b57cec5SDimitry Andric  SDTCisSameAs<0,1>,  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisSameAs<0,4>,
2770b57cec5SDimitry Andric  SDTCisInt<0>
2780b57cec5SDimitry Andric]>;
2790b57cec5SDimitry Andricdef SDTAtomicFence : SDTypeProfile<0, 2, [
2800b57cec5SDimitry Andric  SDTCisSameAs<0,1>, SDTCisPtrTy<0>
2810b57cec5SDimitry Andric]>;
2820b57cec5SDimitry Andricdef SDTAtomic3 : SDTypeProfile<1, 3, [
2830b57cec5SDimitry Andric  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1>
2840b57cec5SDimitry Andric]>;
2850b57cec5SDimitry Andricdef SDTAtomic2 : SDTypeProfile<1, 2, [
2860b57cec5SDimitry Andric  SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
2870b57cec5SDimitry Andric]>;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andricdef SDTFPAtomic2 : SDTypeProfile<1, 2, [
2900b57cec5SDimitry Andric  SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1>
2910b57cec5SDimitry Andric]>;
2920b57cec5SDimitry Andric
2930b57cec5SDimitry Andricdef SDTAtomicStore : SDTypeProfile<0, 2, [
2940b57cec5SDimitry Andric  SDTCisPtrTy<0>, SDTCisInt<1>
2950b57cec5SDimitry Andric]>;
2960b57cec5SDimitry Andricdef SDTAtomicLoad : SDTypeProfile<1, 1, [
2970b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisPtrTy<1>
2980b57cec5SDimitry Andric]>;
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andricdef SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
3010b57cec5SDimitry Andric  SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
3020b57cec5SDimitry Andric]>;
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andricclass SDCallSeqStart<list<SDTypeConstraint> constraints> :
3050b57cec5SDimitry Andric        SDTypeProfile<0, 2, constraints>;
3060b57cec5SDimitry Andricclass SDCallSeqEnd<list<SDTypeConstraint> constraints> :
3070b57cec5SDimitry Andric        SDTypeProfile<0, 2, constraints>;
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3100b57cec5SDimitry Andric// Selection DAG Node definitions.
3110b57cec5SDimitry Andric//
3120b57cec5SDimitry Andricclass SDNode<string opcode, SDTypeProfile typeprof,
3130b57cec5SDimitry Andric             list<SDNodeProperty> props = [], string sdclass = "SDNode">
3140b57cec5SDimitry Andric             : SDPatternOperator {
3150b57cec5SDimitry Andric  string Opcode  = opcode;
3160b57cec5SDimitry Andric  string SDClass = sdclass;
3170b57cec5SDimitry Andric  let Properties = props;
3180b57cec5SDimitry Andric  SDTypeProfile TypeProfile = typeprof;
3190b57cec5SDimitry Andric}
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric// Special TableGen-recognized dag nodes
3220b57cec5SDimitry Andricdef set;
3230b57cec5SDimitry Andricdef implicit;
3240b57cec5SDimitry Andricdef node;
3250b57cec5SDimitry Andricdef srcvalue;
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andricdef imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
3280b57cec5SDimitry Andricdef timm       : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">;
3290b57cec5SDimitry Andricdef fpimm      : SDNode<"ISD::ConstantFP", SDTFPLeaf  , [], "ConstantFPSDNode">;
3300b57cec5SDimitry Andricdef vt         : SDNode<"ISD::VALUETYPE" , SDTOther   , [], "VTSDNode">;
3310b57cec5SDimitry Andricdef bb         : SDNode<"ISD::BasicBlock", SDTOther   , [], "BasicBlockSDNode">;
3320b57cec5SDimitry Andricdef cond       : SDNode<"ISD::CONDCODE"  , SDTOther   , [], "CondCodeSDNode">;
3330b57cec5SDimitry Andricdef undef      : SDNode<"ISD::UNDEF"     , SDTUNDEF   , []>;
3345ffd83dbSDimitry Andricdef vscale     : SDNode<"ISD::VSCALE"    , SDTIntUnaryOp, []>;
3350b57cec5SDimitry Andricdef globaladdr : SDNode<"ISD::GlobalAddress",         SDTPtrLeaf, [],
3360b57cec5SDimitry Andric                        "GlobalAddressSDNode">;
3370b57cec5SDimitry Andricdef tglobaladdr : SDNode<"ISD::TargetGlobalAddress",  SDTPtrLeaf, [],
3380b57cec5SDimitry Andric                         "GlobalAddressSDNode">;
3390b57cec5SDimitry Andricdef globaltlsaddr : SDNode<"ISD::GlobalTLSAddress",         SDTPtrLeaf, [],
3400b57cec5SDimitry Andric                          "GlobalAddressSDNode">;
3410b57cec5SDimitry Andricdef tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress",  SDTPtrLeaf, [],
3420b57cec5SDimitry Andric                           "GlobalAddressSDNode">;
3430b57cec5SDimitry Andricdef constpool   : SDNode<"ISD::ConstantPool",         SDTPtrLeaf, [],
3440b57cec5SDimitry Andric                         "ConstantPoolSDNode">;
3450b57cec5SDimitry Andricdef tconstpool  : SDNode<"ISD::TargetConstantPool",   SDTPtrLeaf, [],
3460b57cec5SDimitry Andric                         "ConstantPoolSDNode">;
3470b57cec5SDimitry Andricdef jumptable   : SDNode<"ISD::JumpTable",            SDTPtrLeaf, [],
3480b57cec5SDimitry Andric                         "JumpTableSDNode">;
3490b57cec5SDimitry Andricdef tjumptable  : SDNode<"ISD::TargetJumpTable",      SDTPtrLeaf, [],
3500b57cec5SDimitry Andric                         "JumpTableSDNode">;
3510b57cec5SDimitry Andricdef frameindex  : SDNode<"ISD::FrameIndex",           SDTPtrLeaf, [],
3520b57cec5SDimitry Andric                         "FrameIndexSDNode">;
3530b57cec5SDimitry Andricdef tframeindex : SDNode<"ISD::TargetFrameIndex",     SDTPtrLeaf, [],
3540b57cec5SDimitry Andric                         "FrameIndexSDNode">;
3550b57cec5SDimitry Andricdef externalsym : SDNode<"ISD::ExternalSymbol",       SDTPtrLeaf, [],
3560b57cec5SDimitry Andric                         "ExternalSymbolSDNode">;
3570b57cec5SDimitry Andricdef texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [],
3580b57cec5SDimitry Andric                         "ExternalSymbolSDNode">;
3590b57cec5SDimitry Andricdef mcsym: SDNode<"ISD::MCSymbol", SDTPtrLeaf, [], "MCSymbolSDNode">;
3600b57cec5SDimitry Andricdef blockaddress : SDNode<"ISD::BlockAddress",        SDTPtrLeaf, [],
3610b57cec5SDimitry Andric                         "BlockAddressSDNode">;
3620b57cec5SDimitry Andricdef tblockaddress: SDNode<"ISD::TargetBlockAddress",  SDTPtrLeaf, [],
3630b57cec5SDimitry Andric                         "BlockAddressSDNode">;
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andricdef add        : SDNode<"ISD::ADD"       , SDTIntBinOp   ,
3660b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
3670b57cec5SDimitry Andricdef sub        : SDNode<"ISD::SUB"       , SDTIntBinOp>;
3680b57cec5SDimitry Andricdef mul        : SDNode<"ISD::MUL"       , SDTIntBinOp,
3690b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
3700b57cec5SDimitry Andricdef mulhs      : SDNode<"ISD::MULHS"     , SDTIntBinOp, [SDNPCommutative]>;
3710b57cec5SDimitry Andricdef mulhu      : SDNode<"ISD::MULHU"     , SDTIntBinOp, [SDNPCommutative]>;
372fe6060f1SDimitry Andricdef abds       : SDNode<"ISD::ABDS"      , SDTIntBinOp, [SDNPCommutative]>;
373fe6060f1SDimitry Andricdef abdu       : SDNode<"ISD::ABDU"      , SDTIntBinOp, [SDNPCommutative]>;
3740b57cec5SDimitry Andricdef smullohi   : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
3750b57cec5SDimitry Andricdef umullohi   : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
3760b57cec5SDimitry Andricdef sdiv       : SDNode<"ISD::SDIV"      , SDTIntBinOp>;
3770b57cec5SDimitry Andricdef udiv       : SDNode<"ISD::UDIV"      , SDTIntBinOp>;
3780b57cec5SDimitry Andricdef srem       : SDNode<"ISD::SREM"      , SDTIntBinOp>;
3790b57cec5SDimitry Andricdef urem       : SDNode<"ISD::UREM"      , SDTIntBinOp>;
3800b57cec5SDimitry Andricdef sdivrem    : SDNode<"ISD::SDIVREM"   , SDTIntBinHiLoOp>;
3810b57cec5SDimitry Andricdef udivrem    : SDNode<"ISD::UDIVREM"   , SDTIntBinHiLoOp>;
3820b57cec5SDimitry Andricdef srl        : SDNode<"ISD::SRL"       , SDTIntShiftOp>;
3830b57cec5SDimitry Andricdef sra        : SDNode<"ISD::SRA"       , SDTIntShiftOp>;
3840b57cec5SDimitry Andricdef shl        : SDNode<"ISD::SHL"       , SDTIntShiftOp>;
3850b57cec5SDimitry Andricdef rotl       : SDNode<"ISD::ROTL"      , SDTIntShiftOp>;
3860b57cec5SDimitry Andricdef rotr       : SDNode<"ISD::ROTR"      , SDTIntShiftOp>;
3870b57cec5SDimitry Andricdef fshl       : SDNode<"ISD::FSHL"      , SDTIntShiftDOp>;
3880b57cec5SDimitry Andricdef fshr       : SDNode<"ISD::FSHR"      , SDTIntShiftDOp>;
3890b57cec5SDimitry Andricdef and        : SDNode<"ISD::AND"       , SDTIntBinOp,
3900b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
3910b57cec5SDimitry Andricdef or         : SDNode<"ISD::OR"        , SDTIntBinOp,
3920b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
3930b57cec5SDimitry Andricdef xor        : SDNode<"ISD::XOR"       , SDTIntBinOp,
3940b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
3950b57cec5SDimitry Andricdef addc       : SDNode<"ISD::ADDC"      , SDTIntBinOp,
3960b57cec5SDimitry Andric                        [SDNPCommutative, SDNPOutGlue]>;
3970b57cec5SDimitry Andricdef adde       : SDNode<"ISD::ADDE"      , SDTIntBinOp,
3980b57cec5SDimitry Andric                        [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>;
3990b57cec5SDimitry Andricdef subc       : SDNode<"ISD::SUBC"      , SDTIntBinOp,
4000b57cec5SDimitry Andric                        [SDNPOutGlue]>;
4010b57cec5SDimitry Andricdef sube       : SDNode<"ISD::SUBE"      , SDTIntBinOp,
4020b57cec5SDimitry Andric                        [SDNPOutGlue, SDNPInGlue]>;
4030b57cec5SDimitry Andricdef smin       : SDNode<"ISD::SMIN"      , SDTIntBinOp,
4040b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4050b57cec5SDimitry Andricdef smax       : SDNode<"ISD::SMAX"      , SDTIntBinOp,
4060b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4070b57cec5SDimitry Andricdef umin       : SDNode<"ISD::UMIN"      , SDTIntBinOp,
4080b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4090b57cec5SDimitry Andricdef umax       : SDNode<"ISD::UMAX"      , SDTIntBinOp,
4100b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andricdef saddsat    : SDNode<"ISD::SADDSAT"   , SDTIntBinOp, [SDNPCommutative]>;
4130b57cec5SDimitry Andricdef uaddsat    : SDNode<"ISD::UADDSAT"   , SDTIntBinOp, [SDNPCommutative]>;
4140b57cec5SDimitry Andricdef ssubsat    : SDNode<"ISD::SSUBSAT"   , SDTIntBinOp>;
4150b57cec5SDimitry Andricdef usubsat    : SDNode<"ISD::USUBSAT"   , SDTIntBinOp>;
416e8d8bef9SDimitry Andricdef sshlsat    : SDNode<"ISD::SSHLSAT"   , SDTIntBinOp>;
417e8d8bef9SDimitry Andricdef ushlsat    : SDNode<"ISD::USHLSAT"   , SDTIntBinOp>;
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andricdef smulfix    : SDNode<"ISD::SMULFIX"   , SDTIntScaledBinOp, [SDNPCommutative]>;
4200b57cec5SDimitry Andricdef smulfixsat : SDNode<"ISD::SMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>;
4210b57cec5SDimitry Andricdef umulfix    : SDNode<"ISD::UMULFIX"   , SDTIntScaledBinOp, [SDNPCommutative]>;
4228bcb0991SDimitry Andricdef umulfixsat : SDNode<"ISD::UMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>;
423480093f4SDimitry Andricdef sdivfix    : SDNode<"ISD::SDIVFIX"   , SDTIntScaledBinOp>;
4245ffd83dbSDimitry Andricdef sdivfixsat : SDNode<"ISD::SDIVFIXSAT", SDTIntScaledBinOp>;
425480093f4SDimitry Andricdef udivfix    : SDNode<"ISD::UDIVFIX"   , SDTIntScaledBinOp>;
4265ffd83dbSDimitry Andricdef udivfixsat : SDNode<"ISD::UDIVFIXSAT", SDTIntScaledBinOp>;
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andricdef sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
4290b57cec5SDimitry Andricdef sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>;
4300b57cec5SDimitry Andricdef zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>;
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andricdef abs        : SDNode<"ISD::ABS"        , SDTIntUnaryOp>;
4330b57cec5SDimitry Andricdef bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>;
4340b57cec5SDimitry Andricdef bswap      : SDNode<"ISD::BSWAP"      , SDTIntUnaryOp>;
4358bcb0991SDimitry Andricdef ctlz       : SDNode<"ISD::CTLZ"       , SDTIntBitCountUnaryOp>;
4368bcb0991SDimitry Andricdef cttz       : SDNode<"ISD::CTTZ"       , SDTIntBitCountUnaryOp>;
4378bcb0991SDimitry Andricdef ctpop      : SDNode<"ISD::CTPOP"      , SDTIntBitCountUnaryOp>;
4388bcb0991SDimitry Andricdef ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>;
4398bcb0991SDimitry Andricdef cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>;
4400b57cec5SDimitry Andricdef sext       : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
4410b57cec5SDimitry Andricdef zext       : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
4420b57cec5SDimitry Andricdef anyext     : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
4430b57cec5SDimitry Andricdef trunc      : SDNode<"ISD::TRUNCATE"   , SDTIntTruncOp>;
4440b57cec5SDimitry Andricdef bitconvert : SDNode<"ISD::BITCAST"    , SDTUnaryOp>;
4450b57cec5SDimitry Andricdef addrspacecast : SDNode<"ISD::ADDRSPACECAST", SDTUnaryOp>;
4460b57cec5SDimitry Andricdef extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
4470b57cec5SDimitry Andricdef insertelt  : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
4480b57cec5SDimitry Andric
4498bcb0991SDimitry Andricdef vecreduce_add  : SDNode<"ISD::VECREDUCE_ADD", SDTVecReduce>;
4508bcb0991SDimitry Andricdef vecreduce_smax  : SDNode<"ISD::VECREDUCE_SMAX", SDTVecReduce>;
4518bcb0991SDimitry Andricdef vecreduce_umax  : SDNode<"ISD::VECREDUCE_UMAX", SDTVecReduce>;
4528bcb0991SDimitry Andricdef vecreduce_smin  : SDNode<"ISD::VECREDUCE_SMIN", SDTVecReduce>;
4538bcb0991SDimitry Andricdef vecreduce_umin  : SDNode<"ISD::VECREDUCE_UMIN", SDTVecReduce>;
454e8d8bef9SDimitry Andricdef vecreduce_fadd  : SDNode<"ISD::VECREDUCE_FADD", SDTFPVecReduce>;
4558bcb0991SDimitry Andric
4560b57cec5SDimitry Andricdef fadd       : SDNode<"ISD::FADD"       , SDTFPBinOp, [SDNPCommutative]>;
4570b57cec5SDimitry Andricdef fsub       : SDNode<"ISD::FSUB"       , SDTFPBinOp>;
4580b57cec5SDimitry Andricdef fmul       : SDNode<"ISD::FMUL"       , SDTFPBinOp, [SDNPCommutative]>;
4590b57cec5SDimitry Andricdef fdiv       : SDNode<"ISD::FDIV"       , SDTFPBinOp>;
4600b57cec5SDimitry Andricdef frem       : SDNode<"ISD::FREM"       , SDTFPBinOp>;
461e8d8bef9SDimitry Andricdef fma        : SDNode<"ISD::FMA"        , SDTFPTernaryOp, [SDNPCommutative]>;
462e8d8bef9SDimitry Andricdef fmad       : SDNode<"ISD::FMAD"       , SDTFPTernaryOp, [SDNPCommutative]>;
4630b57cec5SDimitry Andricdef fabs       : SDNode<"ISD::FABS"       , SDTFPUnaryOp>;
4640b57cec5SDimitry Andricdef fminnum    : SDNode<"ISD::FMINNUM"    , SDTFPBinOp,
4650b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4660b57cec5SDimitry Andricdef fmaxnum    : SDNode<"ISD::FMAXNUM"    , SDTFPBinOp,
4670b57cec5SDimitry Andric                                  [SDNPCommutative, SDNPAssociative]>;
4680b57cec5SDimitry Andricdef fminnum_ieee : SDNode<"ISD::FMINNUM_IEEE", SDTFPBinOp,
4690b57cec5SDimitry Andric                          [SDNPCommutative]>;
4700b57cec5SDimitry Andricdef fmaxnum_ieee  : SDNode<"ISD::FMAXNUM_IEEE", SDTFPBinOp,
4710b57cec5SDimitry Andric                           [SDNPCommutative]>;
4720b57cec5SDimitry Andricdef fminimum   : SDNode<"ISD::FMINIMUM"   , SDTFPBinOp,
4730b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
4740b57cec5SDimitry Andricdef fmaximum   : SDNode<"ISD::FMAXIMUM"   , SDTFPBinOp,
4750b57cec5SDimitry Andric                        [SDNPCommutative, SDNPAssociative]>;
4760b57cec5SDimitry Andricdef fgetsign   : SDNode<"ISD::FGETSIGN"   , SDTFPToIntOp>;
4770b57cec5SDimitry Andricdef fcanonicalize : SDNode<"ISD::FCANONICALIZE", SDTFPUnaryOp>;
4780b57cec5SDimitry Andricdef fneg       : SDNode<"ISD::FNEG"       , SDTFPUnaryOp>;
4790b57cec5SDimitry Andricdef fsqrt      : SDNode<"ISD::FSQRT"      , SDTFPUnaryOp>;
4800b57cec5SDimitry Andricdef fsin       : SDNode<"ISD::FSIN"       , SDTFPUnaryOp>;
4810b57cec5SDimitry Andricdef fcos       : SDNode<"ISD::FCOS"       , SDTFPUnaryOp>;
4820b57cec5SDimitry Andricdef fexp2      : SDNode<"ISD::FEXP2"      , SDTFPUnaryOp>;
4830b57cec5SDimitry Andricdef fpow       : SDNode<"ISD::FPOW"       , SDTFPBinOp>;
4840b57cec5SDimitry Andricdef flog2      : SDNode<"ISD::FLOG2"      , SDTFPUnaryOp>;
4850b57cec5SDimitry Andricdef frint      : SDNode<"ISD::FRINT"      , SDTFPUnaryOp>;
4860b57cec5SDimitry Andricdef ftrunc     : SDNode<"ISD::FTRUNC"     , SDTFPUnaryOp>;
4870b57cec5SDimitry Andricdef fceil      : SDNode<"ISD::FCEIL"      , SDTFPUnaryOp>;
4880b57cec5SDimitry Andricdef ffloor     : SDNode<"ISD::FFLOOR"     , SDTFPUnaryOp>;
4890b57cec5SDimitry Andricdef fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
4900b57cec5SDimitry Andricdef fround     : SDNode<"ISD::FROUND"     , SDTFPUnaryOp>;
491fe6060f1SDimitry Andricdef froundeven : SDNode<"ISD::FROUNDEVEN" , SDTFPUnaryOp>;
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andricdef lround     : SDNode<"ISD::LROUND"     , SDTFPToIntOp>;
4940b57cec5SDimitry Andricdef llround    : SDNode<"ISD::LLROUND"    , SDTFPToIntOp>;
4950b57cec5SDimitry Andricdef lrint      : SDNode<"ISD::LRINT"      , SDTFPToIntOp>;
4960b57cec5SDimitry Andricdef llrint     : SDNode<"ISD::LLRINT"     , SDTFPToIntOp>;
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andricdef fpround    : SDNode<"ISD::FP_ROUND"   , SDTFPRoundOp>;
4990b57cec5SDimitry Andricdef fpextend   : SDNode<"ISD::FP_EXTEND"  , SDTFPExtendOp>;
5000b57cec5SDimitry Andricdef fcopysign  : SDNode<"ISD::FCOPYSIGN"  , SDTFPSignOp>;
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andricdef sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
5030b57cec5SDimitry Andricdef uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
5040b57cec5SDimitry Andricdef fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
5050b57cec5SDimitry Andricdef fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
506e8d8bef9SDimitry Andricdef fp_to_sint_sat : SDNode<"ISD::FP_TO_SINT_SAT" , SDTFPToIntSatOp>;
507e8d8bef9SDimitry Andricdef fp_to_uint_sat : SDNode<"ISD::FP_TO_UINT_SAT" , SDTFPToIntSatOp>;
5080b57cec5SDimitry Andricdef f16_to_fp  : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>;
5090b57cec5SDimitry Andricdef fp_to_f16  : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>;
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andricdef strict_fadd       : SDNode<"ISD::STRICT_FADD",
5120b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>;
5130b57cec5SDimitry Andricdef strict_fsub       : SDNode<"ISD::STRICT_FSUB",
5140b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain]>;
5150b57cec5SDimitry Andricdef strict_fmul       : SDNode<"ISD::STRICT_FMUL",
5160b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>;
5170b57cec5SDimitry Andricdef strict_fdiv       : SDNode<"ISD::STRICT_FDIV",
5180b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain]>;
5190b57cec5SDimitry Andricdef strict_frem       : SDNode<"ISD::STRICT_FREM",
5200b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain]>;
5210b57cec5SDimitry Andricdef strict_fma        : SDNode<"ISD::STRICT_FMA",
522e8d8bef9SDimitry Andric                               SDTFPTernaryOp, [SDNPHasChain, SDNPCommutative]>;
5230b57cec5SDimitry Andricdef strict_fsqrt      : SDNode<"ISD::STRICT_FSQRT",
5240b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5250b57cec5SDimitry Andricdef strict_fsin       : SDNode<"ISD::STRICT_FSIN",
5260b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5270b57cec5SDimitry Andricdef strict_fcos       : SDNode<"ISD::STRICT_FCOS",
5280b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5290b57cec5SDimitry Andricdef strict_fexp2      : SDNode<"ISD::STRICT_FEXP2",
5300b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5310b57cec5SDimitry Andricdef strict_fpow       : SDNode<"ISD::STRICT_FPOW",
5320b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain]>;
5330b57cec5SDimitry Andricdef strict_flog2      : SDNode<"ISD::STRICT_FLOG2",
5340b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5350b57cec5SDimitry Andricdef strict_frint      : SDNode<"ISD::STRICT_FRINT",
5360b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5378bcb0991SDimitry Andricdef strict_lrint      : SDNode<"ISD::STRICT_LRINT",
5388bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
5398bcb0991SDimitry Andricdef strict_llrint     : SDNode<"ISD::STRICT_LLRINT",
5408bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
5410b57cec5SDimitry Andricdef strict_fnearbyint : SDNode<"ISD::STRICT_FNEARBYINT",
5420b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5430b57cec5SDimitry Andricdef strict_fceil      : SDNode<"ISD::STRICT_FCEIL",
5440b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5450b57cec5SDimitry Andricdef strict_ffloor     : SDNode<"ISD::STRICT_FFLOOR",
5460b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5478bcb0991SDimitry Andricdef strict_lround     : SDNode<"ISD::STRICT_LROUND",
5488bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
5498bcb0991SDimitry Andricdef strict_llround    : SDNode<"ISD::STRICT_LLROUND",
5508bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
5510b57cec5SDimitry Andricdef strict_fround     : SDNode<"ISD::STRICT_FROUND",
5520b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
553fe6060f1SDimitry Andricdef strict_froundeven : SDNode<"ISD::STRICT_FROUNDEVEN",
554fe6060f1SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5550b57cec5SDimitry Andricdef strict_ftrunc     : SDNode<"ISD::STRICT_FTRUNC",
5560b57cec5SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
5570b57cec5SDimitry Andricdef strict_fminnum    : SDNode<"ISD::STRICT_FMINNUM",
5580b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain,
5590b57cec5SDimitry Andric                                            SDNPCommutative, SDNPAssociative]>;
5600b57cec5SDimitry Andricdef strict_fmaxnum    : SDNode<"ISD::STRICT_FMAXNUM",
5610b57cec5SDimitry Andric                               SDTFPBinOp, [SDNPHasChain,
5620b57cec5SDimitry Andric                                            SDNPCommutative, SDNPAssociative]>;
563480093f4SDimitry Andricdef strict_fminimum   : SDNode<"ISD::STRICT_FMINIMUM",
564480093f4SDimitry Andric                               SDTFPBinOp, [SDNPHasChain,
565480093f4SDimitry Andric                                            SDNPCommutative, SDNPAssociative]>;
566480093f4SDimitry Andricdef strict_fmaximum   : SDNode<"ISD::STRICT_FMAXIMUM",
567480093f4SDimitry Andric                               SDTFPBinOp, [SDNPHasChain,
568480093f4SDimitry Andric                                            SDNPCommutative, SDNPAssociative]>;
5690b57cec5SDimitry Andricdef strict_fpround    : SDNode<"ISD::STRICT_FP_ROUND",
5700b57cec5SDimitry Andric                               SDTFPRoundOp, [SDNPHasChain]>;
5710b57cec5SDimitry Andricdef strict_fpextend   : SDNode<"ISD::STRICT_FP_EXTEND",
5720b57cec5SDimitry Andric                               SDTFPExtendOp, [SDNPHasChain]>;
5738bcb0991SDimitry Andricdef strict_fp_to_sint : SDNode<"ISD::STRICT_FP_TO_SINT",
5748bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
5758bcb0991SDimitry Andricdef strict_fp_to_uint : SDNode<"ISD::STRICT_FP_TO_UINT",
5768bcb0991SDimitry Andric                               SDTFPToIntOp, [SDNPHasChain]>;
577480093f4SDimitry Andricdef strict_sint_to_fp : SDNode<"ISD::STRICT_SINT_TO_FP",
578480093f4SDimitry Andric                               SDTIntToFPOp, [SDNPHasChain]>;
579480093f4SDimitry Andricdef strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP",
580480093f4SDimitry Andric                               SDTIntToFPOp, [SDNPHasChain]>;
581e8d8bef9SDimitry Andricdef strict_fsetcc  : SDNode<"ISD::STRICT_FSETCC",  SDTSetCC, [SDNPHasChain]>;
582e8d8bef9SDimitry Andricdef strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>;
5830b57cec5SDimitry Andric
5840b57cec5SDimitry Andricdef setcc      : SDNode<"ISD::SETCC"      , SDTSetCC>;
5850b57cec5SDimitry Andricdef select     : SDNode<"ISD::SELECT"     , SDTSelect>;
5860b57cec5SDimitry Andricdef vselect    : SDNode<"ISD::VSELECT"    , SDTVSelect>;
5870b57cec5SDimitry Andricdef selectcc   : SDNode<"ISD::SELECT_CC"  , SDTSelectCC>;
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andricdef brcc       : SDNode<"ISD::BR_CC"      , SDTBrCC,   [SDNPHasChain]>;
5900b57cec5SDimitry Andricdef brcond     : SDNode<"ISD::BRCOND"     , SDTBrcond, [SDNPHasChain]>;
5910b57cec5SDimitry Andricdef brind      : SDNode<"ISD::BRIND"      , SDTBrind,  [SDNPHasChain]>;
5920b57cec5SDimitry Andricdef br         : SDNode<"ISD::BR"         , SDTBr,     [SDNPHasChain]>;
5930b57cec5SDimitry Andricdef catchret   : SDNode<"ISD::CATCHRET"   , SDTCatchret,
5940b57cec5SDimitry Andric                        [SDNPHasChain, SDNPSideEffect]>;
5950b57cec5SDimitry Andricdef cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone,   [SDNPHasChain]>;
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andricdef trap       : SDNode<"ISD::TRAP"       , SDTNone,
5980b57cec5SDimitry Andric                        [SDNPHasChain, SDNPSideEffect]>;
5990b57cec5SDimitry Andricdef debugtrap  : SDNode<"ISD::DEBUGTRAP"  , SDTNone,
6000b57cec5SDimitry Andric                        [SDNPHasChain, SDNPSideEffect]>;
601e8d8bef9SDimitry Andricdef ubsantrap  : SDNode<"ISD::UBSANTRAP"  , SDTUBSANTrap,
602e8d8bef9SDimitry Andric                        [SDNPHasChain, SDNPSideEffect]>;
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andricdef prefetch   : SDNode<"ISD::PREFETCH"   , SDTPrefetch,
6050b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
6060b57cec5SDimitry Andric                         SDNPMemOperand]>;
6070b57cec5SDimitry Andric
6080b57cec5SDimitry Andricdef readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf,
6090b57cec5SDimitry Andric                     [SDNPHasChain, SDNPSideEffect]>;
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andricdef atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence,
6120b57cec5SDimitry Andric                          [SDNPHasChain, SDNPSideEffect]>;
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andricdef atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3,
6150b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6160b57cec5SDimitry Andricdef atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2,
6170b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6180b57cec5SDimitry Andricdef atomic_swap     : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2,
6190b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6200b57cec5SDimitry Andricdef atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2,
6210b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6220b57cec5SDimitry Andricdef atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2,
6230b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6240b57cec5SDimitry Andricdef atomic_load_clr : SDNode<"ISD::ATOMIC_LOAD_CLR" , SDTAtomic2,
6250b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6260b57cec5SDimitry Andricdef atomic_load_or  : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2,
6270b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6280b57cec5SDimitry Andricdef atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2,
6290b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6300b57cec5SDimitry Andricdef atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2,
6310b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6320b57cec5SDimitry Andricdef atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2,
6330b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6340b57cec5SDimitry Andricdef atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2,
6350b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6360b57cec5SDimitry Andricdef atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2,
6370b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6380b57cec5SDimitry Andricdef atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2,
6390b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6400b57cec5SDimitry Andricdef atomic_load_fadd : SDNode<"ISD::ATOMIC_LOAD_FADD" , SDTFPAtomic2,
6410b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6420b57cec5SDimitry Andricdef atomic_load_fsub : SDNode<"ISD::ATOMIC_LOAD_FSUB" , SDTFPAtomic2,
6430b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andricdef atomic_load      : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
6460b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
6470b57cec5SDimitry Andricdef atomic_store     : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore,
6480b57cec5SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
6490b57cec5SDimitry Andric
6500b57cec5SDimitry Andricdef masked_st    : SDNode<"ISD::MSTORE",  SDTMaskedStore,
6510b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
6520b57cec5SDimitry Andricdef masked_ld    : SDNode<"ISD::MLOAD",  SDTMaskedLoad,
6530b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
6540b57cec5SDimitry Andric
6550b57cec5SDimitry Andric// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
6560b57cec5SDimitry Andric// and truncst (see below).
6570b57cec5SDimitry Andricdef ld         : SDNode<"ISD::LOAD"       , SDTLoad,
6580b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
6590b57cec5SDimitry Andricdef st         : SDNode<"ISD::STORE"      , SDTStore,
6600b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
6610b57cec5SDimitry Andricdef ist        : SDNode<"ISD::STORE"      , SDTIStore,
6620b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
6630b57cec5SDimitry Andric
6640b57cec5SDimitry Andricdef vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
665fe6060f1SDimitry Andricdef vector_reverse : SDNode<"ISD::VECTOR_REVERSE", SDTVecReverse>;
666fe6060f1SDimitry Andricdef vector_splice : SDNode<"ISD::VECTOR_SPLICE", SDTVecSlice, []>;
6670b57cec5SDimitry Andricdef build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
668e8d8bef9SDimitry Andricdef splat_vector : SDNode<"ISD::SPLAT_VECTOR", SDTypeProfile<1, 1, []>, []>;
669fe6060f1SDimitry Andricdef step_vector : SDNode<"ISD::STEP_VECTOR", SDTypeProfile<1, 1,
670fe6060f1SDimitry Andric                       [SDTCisVec<0>, SDTCisInt<1>]>, []>;
6710b57cec5SDimitry Andricdef scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
6720b57cec5SDimitry Andric                              []>;
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric// vector_extract/vector_insert are deprecated. extractelt/insertelt
6750b57cec5SDimitry Andric// are preferred.
6760b57cec5SDimitry Andricdef vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
6770b57cec5SDimitry Andric    SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
6780b57cec5SDimitry Andricdef vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
6790b57cec5SDimitry Andric    SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
6800b57cec5SDimitry Andricdef concat_vectors : SDNode<"ISD::CONCAT_VECTORS",
6810b57cec5SDimitry Andric    SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>;
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andric// This operator does not do subvector type checking.  The ARM
6840b57cec5SDimitry Andric// backend, at least, needs it.
6850b57cec5SDimitry Andricdef vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
6860b57cec5SDimitry Andric    SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>,
6870b57cec5SDimitry Andric    []>;
6880b57cec5SDimitry Andric
6890b57cec5SDimitry Andric// This operator does subvector type checking.
6900b57cec5SDimitry Andricdef extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
6910b57cec5SDimitry Andricdef insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>;
6920b57cec5SDimitry Andric
6930b57cec5SDimitry Andric// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
6940b57cec5SDimitry Andric// these internally.  Don't reference these directly.
6950b57cec5SDimitry Andricdef intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
6960b57cec5SDimitry Andric                            SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
6970b57cec5SDimitry Andric                            [SDNPHasChain]>;
6980b57cec5SDimitry Andricdef intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
6990b57cec5SDimitry Andric                               SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
7000b57cec5SDimitry Andric                               [SDNPHasChain]>;
7010b57cec5SDimitry Andricdef intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
7020b57cec5SDimitry Andric                                SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
7030b57cec5SDimitry Andric
7045ffd83dbSDimitry Andricdef SDT_assert : SDTypeProfile<1, 1,
7050b57cec5SDimitry Andric  [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
7065ffd83dbSDimitry Andricdef assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
7075ffd83dbSDimitry Andricdef assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
7085ffd83dbSDimitry Andricdef assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7110b57cec5SDimitry Andric// Selection DAG Condition Codes
7120b57cec5SDimitry Andric
7138bcb0991SDimitry Andricclass CondCode<string fcmpName = "", string icmpName = ""> {
7148bcb0991SDimitry Andric  string ICmpPredicate = icmpName;
7158bcb0991SDimitry Andric  string FCmpPredicate = fcmpName;
7168bcb0991SDimitry Andric}
7170b57cec5SDimitry Andric
7188bcb0991SDimitry Andric// ISD::CondCode enums, and mapping to CmpInst::Predicate names
7198bcb0991SDimitry Andricdef SETOEQ : CondCode<"FCMP_OEQ">;
7208bcb0991SDimitry Andricdef SETOGT : CondCode<"FCMP_OGT">;
7218bcb0991SDimitry Andricdef SETOGE : CondCode<"FCMP_OGE">;
7228bcb0991SDimitry Andricdef SETOLT : CondCode<"FCMP_OLT">;
7238bcb0991SDimitry Andricdef SETOLE : CondCode<"FCMP_OLE">;
7248bcb0991SDimitry Andricdef SETONE : CondCode<"FCMP_ONE">;
7258bcb0991SDimitry Andricdef SETO   : CondCode<"FCMP_ORD">;
7268bcb0991SDimitry Andricdef SETUO  : CondCode<"FCMP_UNO">;
7278bcb0991SDimitry Andricdef SETUEQ : CondCode<"FCMP_UEQ">;
7288bcb0991SDimitry Andricdef SETUGT : CondCode<"FCMP_UGT", "ICMP_UGT">;
7298bcb0991SDimitry Andricdef SETUGE : CondCode<"FCMP_UGE", "ICMP_UGE">;
7308bcb0991SDimitry Andricdef SETULT : CondCode<"FCMP_ULT", "ICMP_ULT">;
7318bcb0991SDimitry Andricdef SETULE : CondCode<"FCMP_ULE", "ICMP_ULE">;
7328bcb0991SDimitry Andricdef SETUNE : CondCode<"FCMP_UNE">;
7338bcb0991SDimitry Andricdef SETEQ : CondCode<"", "ICMP_EQ">;
7348bcb0991SDimitry Andricdef SETGT : CondCode<"", "ICMP_SGT">;
7358bcb0991SDimitry Andricdef SETGE : CondCode<"", "ICMP_SGE">;
7368bcb0991SDimitry Andricdef SETLT : CondCode<"", "ICMP_SLT">;
7378bcb0991SDimitry Andricdef SETLE : CondCode<"", "ICMP_SLE">;
7388bcb0991SDimitry Andricdef SETNE : CondCode<"", "ICMP_NE">;
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7410b57cec5SDimitry Andric// Selection DAG Node Transformation Functions.
7420b57cec5SDimitry Andric//
7430b57cec5SDimitry Andric// This mechanism allows targets to manipulate nodes in the output DAG once a
7440b57cec5SDimitry Andric// match has been formed.  This is typically used to manipulate immediate
7450b57cec5SDimitry Andric// values.
7460b57cec5SDimitry Andric//
7470b57cec5SDimitry Andricclass SDNodeXForm<SDNode opc, code xformFunction> {
7480b57cec5SDimitry Andric  SDNode Opcode = opc;
7490b57cec5SDimitry Andric  code XFormFunction = xformFunction;
7500b57cec5SDimitry Andric}
7510b57cec5SDimitry Andric
7520b57cec5SDimitry Andricdef NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7550b57cec5SDimitry Andric// Selection DAG Pattern Fragments.
7560b57cec5SDimitry Andric//
7570b57cec5SDimitry Andric// Pattern fragments are reusable chunks of dags that match specific things.
7580b57cec5SDimitry Andric// They can take arguments and have C++ predicates that control whether they
7590b57cec5SDimitry Andric// match.  They are intended to make the patterns for common instructions more
7600b57cec5SDimitry Andric// compact and readable.
7610b57cec5SDimitry Andric//
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric/// PatFrags - Represents a set of pattern fragments.  Each single fragment
7640b57cec5SDimitry Andric/// can match something on the DAG, from a single node to multiple nested other
7650b57cec5SDimitry Andric/// fragments.   The whole set of fragments matches if any of the single
7665ffd83dbSDimitry Andric/// fragments match.  This allows e.g. matching and "add with overflow" and
7670b57cec5SDimitry Andric/// a regular "add" with the same fragment set.
7680b57cec5SDimitry Andric///
7690b57cec5SDimitry Andricclass PatFrags<dag ops, list<dag> frags, code pred = [{}],
7700b57cec5SDimitry Andric               SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
7710b57cec5SDimitry Andric  dag Operands = ops;
7720b57cec5SDimitry Andric  list<dag> Fragments = frags;
7730b57cec5SDimitry Andric  code PredicateCode = pred;
7740b57cec5SDimitry Andric  code GISelPredicateCode = [{}];
7750b57cec5SDimitry Andric  code ImmediateCode = [{}];
7760b57cec5SDimitry Andric  SDNodeXForm OperandTransform = xform;
7770b57cec5SDimitry Andric
7780b57cec5SDimitry Andric  // When this is set, the PredicateCode may refer to a constant Operands
7790b57cec5SDimitry Andric  // vector which contains the captured nodes of the DAG, in the order listed
7800b57cec5SDimitry Andric  // by the Operands field above.
7810b57cec5SDimitry Andric  //
7820b57cec5SDimitry Andric  // This is useful when Fragments involves associative / commutative
7830b57cec5SDimitry Andric  // operators: a single piece of code can easily refer to all operands even
7840b57cec5SDimitry Andric  // when re-associated / commuted variants of the fragment are matched.
785e8d8bef9SDimitry Andric  bit PredicateCodeUsesOperands = false;
7860b57cec5SDimitry Andric
7870b57cec5SDimitry Andric  // Define a few pre-packaged predicates. This helps GlobalISel import
7880b57cec5SDimitry Andric  // existing rules from SelectionDAG for many common cases.
7890b57cec5SDimitry Andric  // They will be tested prior to the code in pred and must not be used in
7900b57cec5SDimitry Andric  // ImmLeaf and its subclasses.
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric  // Is the desired pre-packaged predicate for a load?
7930b57cec5SDimitry Andric  bit IsLoad = ?;
7940b57cec5SDimitry Andric  // Is the desired pre-packaged predicate for a store?
7950b57cec5SDimitry Andric  bit IsStore = ?;
7960b57cec5SDimitry Andric  // Is the desired pre-packaged predicate for an atomic?
7970b57cec5SDimitry Andric  bit IsAtomic = ?;
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
8000b57cec5SDimitry Andric  // cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
8010b57cec5SDimitry Andric  bit IsUnindexed = ?;
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD
8040b57cec5SDimitry Andric  bit IsNonExtLoad = ?;
8050b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
8060b57cec5SDimitry Andric  bit IsAnyExtLoad = ?;
8070b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
8080b57cec5SDimitry Andric  bit IsSignExtLoad = ?;
8090b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
8100b57cec5SDimitry Andric  bit IsZeroExtLoad = ?;
8110b57cec5SDimitry Andric  // !cast<StoreSDNode>(N)->isTruncatingStore();
8120b57cec5SDimitry Andric  // cast<StoreSDNode>(N)->isTruncatingStore();
8130b57cec5SDimitry Andric  bit IsTruncStore = ?;
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andric  // cast<MemSDNode>(N)->getAddressSpace() ==
8160b57cec5SDimitry Andric  // If this empty, accept any address space.
8170b57cec5SDimitry Andric  list<int> AddressSpaces = ?;
8180b57cec5SDimitry Andric
8198bcb0991SDimitry Andric  // cast<MemSDNode>(N)->getAlignment() >=
8208bcb0991SDimitry Andric  // If this is empty, accept any alignment.
8218bcb0991SDimitry Andric  int MinAlignment = ?;
8228bcb0991SDimitry Andric
8230b57cec5SDimitry Andric  // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic
8240b57cec5SDimitry Andric  bit IsAtomicOrderingMonotonic = ?;
8250b57cec5SDimitry Andric  // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire
8260b57cec5SDimitry Andric  bit IsAtomicOrderingAcquire = ?;
8270b57cec5SDimitry Andric  // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release
8280b57cec5SDimitry Andric  bit IsAtomicOrderingRelease = ?;
8290b57cec5SDimitry Andric  // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease
8300b57cec5SDimitry Andric  bit IsAtomicOrderingAcquireRelease = ?;
8310b57cec5SDimitry Andric  // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent
8320b57cec5SDimitry Andric  bit IsAtomicOrderingSequentiallyConsistent = ?;
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andric  // isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())
8350b57cec5SDimitry Andric  // !isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())
8360b57cec5SDimitry Andric  bit IsAtomicOrderingAcquireOrStronger = ?;
8370b57cec5SDimitry Andric
8380b57cec5SDimitry Andric  // isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())
8390b57cec5SDimitry Andric  // !isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())
8400b57cec5SDimitry Andric  bit IsAtomicOrderingReleaseOrStronger = ?;
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>;
8430b57cec5SDimitry Andric  // cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>;
8440b57cec5SDimitry Andric  ValueType MemoryVT = ?;
8450b57cec5SDimitry Andric  // cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>;
8460b57cec5SDimitry Andric  // cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>;
8470b57cec5SDimitry Andric  ValueType ScalarMemoryVT = ?;
8480b57cec5SDimitry Andric}
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric// PatFrag - A version of PatFrags matching only a single fragment.
8510b57cec5SDimitry Andricclass PatFrag<dag ops, dag frag, code pred = [{}],
8520b57cec5SDimitry Andric              SDNodeXForm xform = NOOP_SDNodeXForm>
8530b57cec5SDimitry Andric  : PatFrags<ops, [frag], pred, xform>;
8540b57cec5SDimitry Andric
8550b57cec5SDimitry Andric// OutPatFrag is a pattern fragment that is used as part of an output pattern
8560b57cec5SDimitry Andric// (not an input pattern). These do not have predicates or transforms, but are
8570b57cec5SDimitry Andric// used to avoid repeated subexpressions in output patterns.
8580b57cec5SDimitry Andricclass OutPatFrag<dag ops, dag frag>
8590b57cec5SDimitry Andric : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>;
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andric// PatLeaf's are pattern fragments that have no operands.  This is just a helper
8620b57cec5SDimitry Andric// to define immediates and other common things concisely.
8630b57cec5SDimitry Andricclass PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
8640b57cec5SDimitry Andric : PatFrag<(ops), frag, pred, xform>;
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric// ImmLeaf is a pattern fragment with a constraint on the immediate.  The
8680b57cec5SDimitry Andric// constraint is a function that is run on the immediate (always with the value
8690b57cec5SDimitry Andric// sign extended out to an int64_t) as Imm.  For example:
8700b57cec5SDimitry Andric//
8710b57cec5SDimitry Andric//  def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
8720b57cec5SDimitry Andric//
8730b57cec5SDimitry Andric// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
8740b57cec5SDimitry Andric// is preferred over using PatLeaf because it allows the code generator to
8750b57cec5SDimitry Andric// reason more about the constraint.
8760b57cec5SDimitry Andric//
8770b57cec5SDimitry Andric// If FastIsel should ignore all instructions that have an operand of this type,
8780b57cec5SDimitry Andric// the FastIselShouldIgnore flag can be set.  This is an optimization to reduce
8790b57cec5SDimitry Andric// the code size of the generated fast instruction selector.
8800b57cec5SDimitry Andricclass ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
8810b57cec5SDimitry Andric              SDNode ImmNode = imm>
8820b57cec5SDimitry Andric  : PatFrag<(ops), (vt ImmNode), [{}], xform> {
8830b57cec5SDimitry Andric  let ImmediateCode = pred;
884e8d8bef9SDimitry Andric  bit FastIselShouldIgnore = false;
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andric  // Is the data type of the immediate an APInt?
887e8d8bef9SDimitry Andric  bit IsAPInt = false;
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric  // Is the data type of the immediate an APFloat?
890e8d8bef9SDimitry Andric  bit IsAPFloat = false;
8910b57cec5SDimitry Andric}
8920b57cec5SDimitry Andric
8938bcb0991SDimitry Andric// Convenience wrapper for ImmLeaf to use timm/TargetConstant instead
8948bcb0991SDimitry Andric// of imm/Constant.
8958bcb0991SDimitry Andricclass TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
8968bcb0991SDimitry Andric  SDNode ImmNode = timm> : ImmLeaf<vt, pred, xform, ImmNode>;
8978bcb0991SDimitry Andric
8980b57cec5SDimitry Andric// An ImmLeaf except that Imm is an APInt. This is useful when you need to
8990b57cec5SDimitry Andric// zero-extend the immediate instead of sign-extend it.
9000b57cec5SDimitry Andric//
9010b57cec5SDimitry Andric// Note that FastISel does not currently understand IntImmLeaf and will not
9020b57cec5SDimitry Andric// generate code for rules that make use of it. As such, it does not make sense
9030b57cec5SDimitry Andric// to replace ImmLeaf with IntImmLeaf. However, replacing PatLeaf with an
9040b57cec5SDimitry Andric// IntImmLeaf will allow GlobalISel to import the rule.
9050b57cec5SDimitry Andricclass IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
9060b57cec5SDimitry Andric    : ImmLeaf<vt, pred, xform> {
907e8d8bef9SDimitry Andric  let IsAPInt = true;
908e8d8bef9SDimitry Andric  let FastIselShouldIgnore = true;
9090b57cec5SDimitry Andric}
9100b57cec5SDimitry Andric
9110b57cec5SDimitry Andric// An ImmLeaf except that Imm is an APFloat.
9120b57cec5SDimitry Andric//
9130b57cec5SDimitry Andric// Note that FastISel does not currently understand FPImmLeaf and will not
9140b57cec5SDimitry Andric// generate code for rules that make use of it.
9150b57cec5SDimitry Andricclass FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
9160b57cec5SDimitry Andric  : ImmLeaf<vt, pred, xform, fpimm> {
917e8d8bef9SDimitry Andric  let IsAPFloat = true;
918e8d8bef9SDimitry Andric  let FastIselShouldIgnore = true;
9190b57cec5SDimitry Andric}
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric// Leaf fragments.
9220b57cec5SDimitry Andric
9230b57cec5SDimitry Andricdef vtInt      : PatLeaf<(vt),  [{ return N->getVT().isInteger(); }]>;
9240b57cec5SDimitry Andricdef vtFP       : PatLeaf<(vt),  [{ return N->getVT().isFloatingPoint(); }]>;
9250b57cec5SDimitry Andric
926e8d8bef9SDimitry Andric// Use ISD::isConstantSplatVectorAllOnes or ISD::isConstantSplatVectorAllZeros
927e8d8bef9SDimitry Andric// to look for the corresponding build_vector or splat_vector. Will look through
928e8d8bef9SDimitry Andric// bitcasts and check for either opcode, except when used as a pattern root.
929e8d8bef9SDimitry Andric// When used as a pattern root, only fixed-length build_vector and scalable
930e8d8bef9SDimitry Andric// splat_vector are supported.
931fe6060f1SDimitry Andricdef immAllOnesV  : SDPatternOperator; // ISD::isConstantSplatVectorAllOnes
932fe6060f1SDimitry Andricdef immAllZerosV : SDPatternOperator; // ISD::isConstantSplatVectorAllZeros
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric// Other helper fragments.
9350b57cec5SDimitry Andricdef not  : PatFrag<(ops node:$in), (xor node:$in, -1)>;
9360b57cec5SDimitry Andricdef vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
9370b57cec5SDimitry Andricdef ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
9380b57cec5SDimitry Andric
939e8d8bef9SDimitry Andricdef zanyext : PatFrags<(ops node:$op),
940e8d8bef9SDimitry Andric                       [(zext node:$op),
941e8d8bef9SDimitry Andric                        (anyext node:$op)]>;
942e8d8bef9SDimitry Andric
9430b57cec5SDimitry Andric// null_frag - The null pattern operator is used in multiclass instantiations
9440b57cec5SDimitry Andric// which accept an SDPatternOperator for use in matching patterns for internal
9450b57cec5SDimitry Andric// definitions. When expanding a pattern, if the null fragment is referenced
9460b57cec5SDimitry Andric// in the expansion, the pattern is discarded and it is as-if '[]' had been
9470b57cec5SDimitry Andric// specified. This allows multiclasses to have the isel patterns be optional.
9480b57cec5SDimitry Andricdef null_frag : SDPatternOperator;
9490b57cec5SDimitry Andric
9500b57cec5SDimitry Andric// load fragments.
9510b57cec5SDimitry Andricdef unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> {
952e8d8bef9SDimitry Andric  let IsLoad = true;
953e8d8bef9SDimitry Andric  let IsUnindexed = true;
9540b57cec5SDimitry Andric}
9550b57cec5SDimitry Andricdef load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
956e8d8bef9SDimitry Andric  let IsLoad = true;
957e8d8bef9SDimitry Andric  let IsNonExtLoad = true;
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric// extending load fragments.
9610b57cec5SDimitry Andricdef extload   : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
962e8d8bef9SDimitry Andric  let IsLoad = true;
963e8d8bef9SDimitry Andric  let IsAnyExtLoad = true;
9640b57cec5SDimitry Andric}
9650b57cec5SDimitry Andricdef sextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
966e8d8bef9SDimitry Andric  let IsLoad = true;
967e8d8bef9SDimitry Andric  let IsSignExtLoad = true;
9680b57cec5SDimitry Andric}
9690b57cec5SDimitry Andricdef zextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> {
970e8d8bef9SDimitry Andric  let IsLoad = true;
971e8d8bef9SDimitry Andric  let IsZeroExtLoad = true;
9720b57cec5SDimitry Andric}
9730b57cec5SDimitry Andric
9740b57cec5SDimitry Andricdef extloadi1  : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
975e8d8bef9SDimitry Andric  let IsLoad = true;
9760b57cec5SDimitry Andric  let MemoryVT = i1;
9770b57cec5SDimitry Andric}
9780b57cec5SDimitry Andricdef extloadi8  : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
979e8d8bef9SDimitry Andric  let IsLoad = true;
9800b57cec5SDimitry Andric  let MemoryVT = i8;
9810b57cec5SDimitry Andric}
9820b57cec5SDimitry Andricdef extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
983e8d8bef9SDimitry Andric  let IsLoad = true;
9840b57cec5SDimitry Andric  let MemoryVT = i16;
9850b57cec5SDimitry Andric}
9860b57cec5SDimitry Andricdef extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
987e8d8bef9SDimitry Andric  let IsLoad = true;
9880b57cec5SDimitry Andric  let MemoryVT = i32;
9890b57cec5SDimitry Andric}
9900946e70aSDimitry Andricdef extloadf16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
991e8d8bef9SDimitry Andric  let IsLoad = true;
9920946e70aSDimitry Andric  let MemoryVT = f16;
9930946e70aSDimitry Andric}
9940b57cec5SDimitry Andricdef extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
995e8d8bef9SDimitry Andric  let IsLoad = true;
9960b57cec5SDimitry Andric  let MemoryVT = f32;
9970b57cec5SDimitry Andric}
9980b57cec5SDimitry Andricdef extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
999e8d8bef9SDimitry Andric  let IsLoad = true;
10000b57cec5SDimitry Andric  let MemoryVT = f64;
10010b57cec5SDimitry Andric}
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andricdef sextloadi1  : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1004e8d8bef9SDimitry Andric  let IsLoad = true;
10050b57cec5SDimitry Andric  let MemoryVT = i1;
10060b57cec5SDimitry Andric}
10070b57cec5SDimitry Andricdef sextloadi8  : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1008e8d8bef9SDimitry Andric  let IsLoad = true;
10090b57cec5SDimitry Andric  let MemoryVT = i8;
10100b57cec5SDimitry Andric}
10110b57cec5SDimitry Andricdef sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1012e8d8bef9SDimitry Andric  let IsLoad = true;
10130b57cec5SDimitry Andric  let MemoryVT = i16;
10140b57cec5SDimitry Andric}
10150b57cec5SDimitry Andricdef sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1016e8d8bef9SDimitry Andric  let IsLoad = true;
10170b57cec5SDimitry Andric  let MemoryVT = i32;
10180b57cec5SDimitry Andric}
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andricdef zextloadi1  : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1021e8d8bef9SDimitry Andric  let IsLoad = true;
10220b57cec5SDimitry Andric  let MemoryVT = i1;
10230b57cec5SDimitry Andric}
10240b57cec5SDimitry Andricdef zextloadi8  : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1025e8d8bef9SDimitry Andric  let IsLoad = true;
10260b57cec5SDimitry Andric  let MemoryVT = i8;
10270b57cec5SDimitry Andric}
10280b57cec5SDimitry Andricdef zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1029e8d8bef9SDimitry Andric  let IsLoad = true;
10300b57cec5SDimitry Andric  let MemoryVT = i16;
10310b57cec5SDimitry Andric}
10320b57cec5SDimitry Andricdef zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1033e8d8bef9SDimitry Andric  let IsLoad = true;
10340b57cec5SDimitry Andric  let MemoryVT = i32;
10350b57cec5SDimitry Andric}
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andricdef extloadvi1  : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1038e8d8bef9SDimitry Andric  let IsLoad = true;
10390b57cec5SDimitry Andric  let ScalarMemoryVT = i1;
10400b57cec5SDimitry Andric}
10410b57cec5SDimitry Andricdef extloadvi8  : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1042e8d8bef9SDimitry Andric  let IsLoad = true;
10430b57cec5SDimitry Andric  let ScalarMemoryVT = i8;
10440b57cec5SDimitry Andric}
10450b57cec5SDimitry Andricdef extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1046e8d8bef9SDimitry Andric  let IsLoad = true;
10470b57cec5SDimitry Andric  let ScalarMemoryVT = i16;
10480b57cec5SDimitry Andric}
10490b57cec5SDimitry Andricdef extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1050e8d8bef9SDimitry Andric  let IsLoad = true;
10510b57cec5SDimitry Andric  let ScalarMemoryVT = i32;
10520b57cec5SDimitry Andric}
10530b57cec5SDimitry Andricdef extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1054e8d8bef9SDimitry Andric  let IsLoad = true;
10550b57cec5SDimitry Andric  let ScalarMemoryVT = f32;
10560b57cec5SDimitry Andric}
10570b57cec5SDimitry Andricdef extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> {
1058e8d8bef9SDimitry Andric  let IsLoad = true;
10590b57cec5SDimitry Andric  let ScalarMemoryVT = f64;
10600b57cec5SDimitry Andric}
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andricdef sextloadvi1  : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1063e8d8bef9SDimitry Andric  let IsLoad = true;
10640b57cec5SDimitry Andric  let ScalarMemoryVT = i1;
10650b57cec5SDimitry Andric}
10660b57cec5SDimitry Andricdef sextloadvi8  : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1067e8d8bef9SDimitry Andric  let IsLoad = true;
10680b57cec5SDimitry Andric  let ScalarMemoryVT = i8;
10690b57cec5SDimitry Andric}
10700b57cec5SDimitry Andricdef sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1071e8d8bef9SDimitry Andric  let IsLoad = true;
10720b57cec5SDimitry Andric  let ScalarMemoryVT = i16;
10730b57cec5SDimitry Andric}
10740b57cec5SDimitry Andricdef sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> {
1075e8d8bef9SDimitry Andric  let IsLoad = true;
10760b57cec5SDimitry Andric  let ScalarMemoryVT = i32;
10770b57cec5SDimitry Andric}
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andricdef zextloadvi1  : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1080e8d8bef9SDimitry Andric  let IsLoad = true;
10810b57cec5SDimitry Andric  let ScalarMemoryVT = i1;
10820b57cec5SDimitry Andric}
10830b57cec5SDimitry Andricdef zextloadvi8  : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1084e8d8bef9SDimitry Andric  let IsLoad = true;
10850b57cec5SDimitry Andric  let ScalarMemoryVT = i8;
10860b57cec5SDimitry Andric}
10870b57cec5SDimitry Andricdef zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1088e8d8bef9SDimitry Andric  let IsLoad = true;
10890b57cec5SDimitry Andric  let ScalarMemoryVT = i16;
10900b57cec5SDimitry Andric}
10910b57cec5SDimitry Andricdef zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> {
1092e8d8bef9SDimitry Andric  let IsLoad = true;
10930b57cec5SDimitry Andric  let ScalarMemoryVT = i32;
10940b57cec5SDimitry Andric}
10950b57cec5SDimitry Andric
10960b57cec5SDimitry Andric// store fragments.
10970b57cec5SDimitry Andricdef unindexedstore : PatFrag<(ops node:$val, node:$ptr),
10980b57cec5SDimitry Andric                             (st node:$val, node:$ptr)> {
1099e8d8bef9SDimitry Andric  let IsStore = true;
1100e8d8bef9SDimitry Andric  let IsUnindexed = true;
11010b57cec5SDimitry Andric}
11020b57cec5SDimitry Andricdef store : PatFrag<(ops node:$val, node:$ptr),
11030b57cec5SDimitry Andric                    (unindexedstore node:$val, node:$ptr)> {
1104e8d8bef9SDimitry Andric  let IsStore = true;
1105e8d8bef9SDimitry Andric  let IsTruncStore = false;
11060b57cec5SDimitry Andric}
11070b57cec5SDimitry Andric
11080b57cec5SDimitry Andric// truncstore fragments.
11090b57cec5SDimitry Andricdef truncstore : PatFrag<(ops node:$val, node:$ptr),
11100b57cec5SDimitry Andric                         (unindexedstore node:$val, node:$ptr)> {
1111e8d8bef9SDimitry Andric  let IsStore = true;
1112e8d8bef9SDimitry Andric  let IsTruncStore = true;
11130b57cec5SDimitry Andric}
11140b57cec5SDimitry Andricdef truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
11150b57cec5SDimitry Andric                           (truncstore node:$val, node:$ptr)> {
1116e8d8bef9SDimitry Andric  let IsStore = true;
11170b57cec5SDimitry Andric  let MemoryVT = i8;
1118fe6060f1SDimitry Andric  let IsTruncStore = true;
11190b57cec5SDimitry Andric}
11200b57cec5SDimitry Andricdef truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
11210b57cec5SDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1122e8d8bef9SDimitry Andric  let IsStore = true;
11230b57cec5SDimitry Andric  let MemoryVT = i16;
1124fe6060f1SDimitry Andric  let IsTruncStore = true;
11250b57cec5SDimitry Andric}
11260b57cec5SDimitry Andricdef truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
11270b57cec5SDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1128e8d8bef9SDimitry Andric  let IsStore = true;
11290b57cec5SDimitry Andric  let MemoryVT = i32;
1130fe6060f1SDimitry Andric  let IsTruncStore = true;
11310b57cec5SDimitry Andric}
11320946e70aSDimitry Andricdef truncstoref16 : PatFrag<(ops node:$val, node:$ptr),
11330946e70aSDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1134e8d8bef9SDimitry Andric  let IsStore = true;
11350946e70aSDimitry Andric  let MemoryVT = f16;
11360946e70aSDimitry Andric}
11370b57cec5SDimitry Andricdef truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
11380b57cec5SDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1139e8d8bef9SDimitry Andric  let IsStore = true;
11400b57cec5SDimitry Andric  let MemoryVT = f32;
11410b57cec5SDimitry Andric}
11420b57cec5SDimitry Andricdef truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
11430b57cec5SDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1144e8d8bef9SDimitry Andric  let IsStore = true;
11450b57cec5SDimitry Andric  let MemoryVT = f64;
11460b57cec5SDimitry Andric}
11470b57cec5SDimitry Andric
11480b57cec5SDimitry Andricdef truncstorevi8 : PatFrag<(ops node:$val, node:$ptr),
11490b57cec5SDimitry Andric                            (truncstore node:$val, node:$ptr)> {
1150e8d8bef9SDimitry Andric  let IsStore = true;
11510b57cec5SDimitry Andric  let ScalarMemoryVT = i8;
11520b57cec5SDimitry Andric}
11530b57cec5SDimitry Andric
11540b57cec5SDimitry Andricdef truncstorevi16 : PatFrag<(ops node:$val, node:$ptr),
11550b57cec5SDimitry Andric                             (truncstore node:$val, node:$ptr)> {
1156e8d8bef9SDimitry Andric  let IsStore = true;
11570b57cec5SDimitry Andric  let ScalarMemoryVT = i16;
11580b57cec5SDimitry Andric}
11590b57cec5SDimitry Andric
11600b57cec5SDimitry Andricdef truncstorevi32 : PatFrag<(ops node:$val, node:$ptr),
11610b57cec5SDimitry Andric                             (truncstore node:$val, node:$ptr)> {
1162e8d8bef9SDimitry Andric  let IsStore = true;
11630b57cec5SDimitry Andric  let ScalarMemoryVT = i32;
11640b57cec5SDimitry Andric}
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andric// indexed store fragments.
11670b57cec5SDimitry Andricdef istore : PatFrag<(ops node:$val, node:$base, node:$offset),
11680b57cec5SDimitry Andric                     (ist node:$val, node:$base, node:$offset)> {
1169e8d8bef9SDimitry Andric  let IsStore = true;
1170e8d8bef9SDimitry Andric  let IsTruncStore = false;
11710b57cec5SDimitry Andric}
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andricdef pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
11740b57cec5SDimitry Andric                        (istore node:$val, node:$base, node:$offset), [{
11750b57cec5SDimitry Andric  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
11760b57cec5SDimitry Andric  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
11770b57cec5SDimitry Andric}]>;
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andricdef itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
11800b57cec5SDimitry Andric                          (ist node:$val, node:$base, node:$offset)> {
1181e8d8bef9SDimitry Andric  let IsStore = true;
1182e8d8bef9SDimitry Andric  let IsTruncStore = true;
11830b57cec5SDimitry Andric}
11840b57cec5SDimitry Andricdef pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
11850b57cec5SDimitry Andric                          (itruncstore node:$val, node:$base, node:$offset), [{
11860b57cec5SDimitry Andric  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
11870b57cec5SDimitry Andric  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
11880b57cec5SDimitry Andric}]>;
11890b57cec5SDimitry Andricdef pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
11900b57cec5SDimitry Andric                            (pre_truncst node:$val, node:$base, node:$offset)> {
1191e8d8bef9SDimitry Andric  let IsStore = true;
11920b57cec5SDimitry Andric  let MemoryVT = i1;
11930b57cec5SDimitry Andric}
11940b57cec5SDimitry Andricdef pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
11950b57cec5SDimitry Andric                            (pre_truncst node:$val, node:$base, node:$offset)> {
1196e8d8bef9SDimitry Andric  let IsStore = true;
11970b57cec5SDimitry Andric  let MemoryVT = i8;
11980b57cec5SDimitry Andric}
11990b57cec5SDimitry Andricdef pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
12000b57cec5SDimitry Andric                             (pre_truncst node:$val, node:$base, node:$offset)> {
1201e8d8bef9SDimitry Andric  let IsStore = true;
12020b57cec5SDimitry Andric  let MemoryVT = i16;
12030b57cec5SDimitry Andric}
12040b57cec5SDimitry Andricdef pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
12050b57cec5SDimitry Andric                             (pre_truncst node:$val, node:$base, node:$offset)> {
1206e8d8bef9SDimitry Andric  let IsStore = true;
12070b57cec5SDimitry Andric  let MemoryVT = i32;
12080b57cec5SDimitry Andric}
12090b57cec5SDimitry Andricdef pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
12100b57cec5SDimitry Andric                             (pre_truncst node:$val, node:$base, node:$offset)> {
1211e8d8bef9SDimitry Andric  let IsStore = true;
12120b57cec5SDimitry Andric  let MemoryVT = f32;
12130b57cec5SDimitry Andric}
12148bcb0991SDimitry Andricdef pre_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset),
12158bcb0991SDimitry Andric                             (pre_truncst node:$val, node:$base, node:$offset)> {
1216e8d8bef9SDimitry Andric  let IsStore = true;
12178bcb0991SDimitry Andric  let ScalarMemoryVT = i8;
12188bcb0991SDimitry Andric}
12198bcb0991SDimitry Andricdef pre_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset),
12208bcb0991SDimitry Andric                              (pre_truncst node:$val, node:$base, node:$offset)> {
1221e8d8bef9SDimitry Andric  let IsStore = true;
12228bcb0991SDimitry Andric  let ScalarMemoryVT = i16;
12238bcb0991SDimitry Andric}
12240b57cec5SDimitry Andric
12250b57cec5SDimitry Andricdef post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
12260b57cec5SDimitry Andric                         (istore node:$val, node:$ptr, node:$offset), [{
12270b57cec5SDimitry Andric  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
12280b57cec5SDimitry Andric  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
12290b57cec5SDimitry Andric}]>;
12300b57cec5SDimitry Andric
12310b57cec5SDimitry Andricdef post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
12320b57cec5SDimitry Andric                           (itruncstore node:$val, node:$base, node:$offset), [{
12330b57cec5SDimitry Andric  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
12340b57cec5SDimitry Andric  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
12350b57cec5SDimitry Andric}]>;
12360b57cec5SDimitry Andricdef post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
12370b57cec5SDimitry Andric                             (post_truncst node:$val, node:$base, node:$offset)> {
1238e8d8bef9SDimitry Andric  let IsStore = true;
12390b57cec5SDimitry Andric  let MemoryVT = i1;
12400b57cec5SDimitry Andric}
12410b57cec5SDimitry Andricdef post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
12420b57cec5SDimitry Andric                             (post_truncst node:$val, node:$base, node:$offset)> {
1243e8d8bef9SDimitry Andric  let IsStore = true;
12440b57cec5SDimitry Andric  let MemoryVT = i8;
12450b57cec5SDimitry Andric}
12460b57cec5SDimitry Andricdef post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
12470b57cec5SDimitry Andric                              (post_truncst node:$val, node:$base, node:$offset)> {
1248e8d8bef9SDimitry Andric  let IsStore = true;
12490b57cec5SDimitry Andric  let MemoryVT = i16;
12500b57cec5SDimitry Andric}
12510b57cec5SDimitry Andricdef post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
12520b57cec5SDimitry Andric                              (post_truncst node:$val, node:$base, node:$offset)> {
1253e8d8bef9SDimitry Andric  let IsStore = true;
12540b57cec5SDimitry Andric  let MemoryVT = i32;
12550b57cec5SDimitry Andric}
12560b57cec5SDimitry Andricdef post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
12570b57cec5SDimitry Andric                              (post_truncst node:$val, node:$base, node:$offset)> {
1258e8d8bef9SDimitry Andric  let IsStore = true;
12590b57cec5SDimitry Andric  let MemoryVT = f32;
12600b57cec5SDimitry Andric}
12618bcb0991SDimitry Andricdef post_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset),
12628bcb0991SDimitry Andric                              (post_truncst node:$val, node:$base, node:$offset)> {
1263e8d8bef9SDimitry Andric  let IsStore = true;
12648bcb0991SDimitry Andric  let ScalarMemoryVT = i8;
12658bcb0991SDimitry Andric}
12668bcb0991SDimitry Andricdef post_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset),
12678bcb0991SDimitry Andric                               (post_truncst node:$val, node:$base, node:$offset)> {
1268e8d8bef9SDimitry Andric  let IsStore = true;
12698bcb0991SDimitry Andric  let ScalarMemoryVT = i16;
12708bcb0991SDimitry Andric}
12710b57cec5SDimitry Andric
12728bcb0991SDimitry Andric// TODO: Split these into volatile and unordered flavors to enable
12738bcb0991SDimitry Andric// selectively legal optimizations for each.  (See D66309)
12748bcb0991SDimitry Andricdef simple_load : PatFrag<(ops node:$ptr),
12750b57cec5SDimitry Andric                          (load node:$ptr), [{
12768bcb0991SDimitry Andric  return cast<LoadSDNode>(N)->isSimple();
12770b57cec5SDimitry Andric}]>;
12788bcb0991SDimitry Andricdef simple_store : PatFrag<(ops node:$val, node:$ptr),
12790b57cec5SDimitry Andric                           (store node:$val, node:$ptr), [{
12808bcb0991SDimitry Andric  return cast<StoreSDNode>(N)->isSimple();
12810b57cec5SDimitry Andric}]>;
12820b57cec5SDimitry Andric
12830b57cec5SDimitry Andric// nontemporal store fragments.
12840b57cec5SDimitry Andricdef nontemporalstore : PatFrag<(ops node:$val, node:$ptr),
12850b57cec5SDimitry Andric                               (store node:$val, node:$ptr), [{
12860b57cec5SDimitry Andric  return cast<StoreSDNode>(N)->isNonTemporal();
12870b57cec5SDimitry Andric}]>;
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andricdef alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
12900b57cec5SDimitry Andric                                      (nontemporalstore node:$val, node:$ptr), [{
12910b57cec5SDimitry Andric  StoreSDNode *St = cast<StoreSDNode>(N);
12920b57cec5SDimitry Andric  return St->getAlignment() >= St->getMemoryVT().getStoreSize();
12930b57cec5SDimitry Andric}]>;
12940b57cec5SDimitry Andric
12950b57cec5SDimitry Andricdef unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
12960b57cec5SDimitry Andric                                        (nontemporalstore node:$val, node:$ptr), [{
12970b57cec5SDimitry Andric  StoreSDNode *St = cast<StoreSDNode>(N);
12980b57cec5SDimitry Andric  return St->getAlignment() < St->getMemoryVT().getStoreSize();
12990b57cec5SDimitry Andric}]>;
13000b57cec5SDimitry Andric
13010b57cec5SDimitry Andric// nontemporal load fragments.
13020b57cec5SDimitry Andricdef nontemporalload : PatFrag<(ops node:$ptr),
13030b57cec5SDimitry Andric                               (load node:$ptr), [{
13040b57cec5SDimitry Andric  return cast<LoadSDNode>(N)->isNonTemporal();
13050b57cec5SDimitry Andric}]>;
13060b57cec5SDimitry Andric
13070b57cec5SDimitry Andricdef alignednontemporalload : PatFrag<(ops node:$ptr),
13080b57cec5SDimitry Andric                                      (nontemporalload node:$ptr), [{
13090b57cec5SDimitry Andric  LoadSDNode *Ld = cast<LoadSDNode>(N);
13100b57cec5SDimitry Andric  return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
13110b57cec5SDimitry Andric}]>;
13120b57cec5SDimitry Andric
13130b57cec5SDimitry Andric// setcc convenience fragments.
13140b57cec5SDimitry Andricdef setoeq : PatFrag<(ops node:$lhs, node:$rhs),
13150b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETOEQ)>;
13160b57cec5SDimitry Andricdef setogt : PatFrag<(ops node:$lhs, node:$rhs),
13170b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETOGT)>;
13180b57cec5SDimitry Andricdef setoge : PatFrag<(ops node:$lhs, node:$rhs),
13190b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETOGE)>;
13200b57cec5SDimitry Andricdef setolt : PatFrag<(ops node:$lhs, node:$rhs),
13210b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETOLT)>;
13220b57cec5SDimitry Andricdef setole : PatFrag<(ops node:$lhs, node:$rhs),
13230b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETOLE)>;
13240b57cec5SDimitry Andricdef setone : PatFrag<(ops node:$lhs, node:$rhs),
13250b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETONE)>;
13260b57cec5SDimitry Andricdef seto   : PatFrag<(ops node:$lhs, node:$rhs),
13270b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETO)>;
13280b57cec5SDimitry Andricdef setuo  : PatFrag<(ops node:$lhs, node:$rhs),
13290b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETUO)>;
13300b57cec5SDimitry Andricdef setueq : PatFrag<(ops node:$lhs, node:$rhs),
13310b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETUEQ)>;
13320b57cec5SDimitry Andricdef setugt : PatFrag<(ops node:$lhs, node:$rhs),
13330b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETUGT)>;
13340b57cec5SDimitry Andricdef setuge : PatFrag<(ops node:$lhs, node:$rhs),
13350b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETUGE)>;
13360b57cec5SDimitry Andricdef setult : PatFrag<(ops node:$lhs, node:$rhs),
13370b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETULT)>;
13380b57cec5SDimitry Andricdef setule : PatFrag<(ops node:$lhs, node:$rhs),
13390b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETULE)>;
13400b57cec5SDimitry Andricdef setune : PatFrag<(ops node:$lhs, node:$rhs),
13410b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETUNE)>;
13420b57cec5SDimitry Andricdef seteq  : PatFrag<(ops node:$lhs, node:$rhs),
13430b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETEQ)>;
13440b57cec5SDimitry Andricdef setgt  : PatFrag<(ops node:$lhs, node:$rhs),
13450b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETGT)>;
13460b57cec5SDimitry Andricdef setge  : PatFrag<(ops node:$lhs, node:$rhs),
13470b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETGE)>;
13480b57cec5SDimitry Andricdef setlt  : PatFrag<(ops node:$lhs, node:$rhs),
13490b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETLT)>;
13500b57cec5SDimitry Andricdef setle  : PatFrag<(ops node:$lhs, node:$rhs),
13510b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETLE)>;
13520b57cec5SDimitry Andricdef setne  : PatFrag<(ops node:$lhs, node:$rhs),
13530b57cec5SDimitry Andric                     (setcc node:$lhs, node:$rhs, SETNE)>;
13540b57cec5SDimitry Andric
13550b57cec5SDimitry Andric// We don't have strict FP extended loads as single DAG nodes, but we can
13560b57cec5SDimitry Andric// still provide convenience fragments to match those operations.
13570b57cec5SDimitry Andricdef strict_extloadf32 : PatFrag<(ops node:$ptr),
13580b57cec5SDimitry Andric                                (strict_fpextend (f32 (load node:$ptr)))>;
13590b57cec5SDimitry Andricdef strict_extloadf64 : PatFrag<(ops node:$ptr),
13600b57cec5SDimitry Andric                                (strict_fpextend (f64 (load node:$ptr)))>;
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andric// Convenience fragments to match both strict and non-strict fp operations
13630b57cec5SDimitry Andricdef any_fadd       : PatFrags<(ops node:$lhs, node:$rhs),
13640b57cec5SDimitry Andric                              [(strict_fadd node:$lhs, node:$rhs),
13650b57cec5SDimitry Andric                               (fadd node:$lhs, node:$rhs)]>;
13660b57cec5SDimitry Andricdef any_fsub       : PatFrags<(ops node:$lhs, node:$rhs),
13670b57cec5SDimitry Andric                              [(strict_fsub node:$lhs, node:$rhs),
13680b57cec5SDimitry Andric                               (fsub node:$lhs, node:$rhs)]>;
13690b57cec5SDimitry Andricdef any_fmul       : PatFrags<(ops node:$lhs, node:$rhs),
13700b57cec5SDimitry Andric                              [(strict_fmul node:$lhs, node:$rhs),
13710b57cec5SDimitry Andric                               (fmul node:$lhs, node:$rhs)]>;
13720b57cec5SDimitry Andricdef any_fdiv       : PatFrags<(ops node:$lhs, node:$rhs),
13730b57cec5SDimitry Andric                              [(strict_fdiv node:$lhs, node:$rhs),
13740b57cec5SDimitry Andric                               (fdiv node:$lhs, node:$rhs)]>;
13750b57cec5SDimitry Andricdef any_frem       : PatFrags<(ops node:$lhs, node:$rhs),
13760b57cec5SDimitry Andric                              [(strict_frem node:$lhs, node:$rhs),
13770b57cec5SDimitry Andric                               (frem node:$lhs, node:$rhs)]>;
13780b57cec5SDimitry Andricdef any_fma        : PatFrags<(ops node:$src1, node:$src2, node:$src3),
13790b57cec5SDimitry Andric                              [(strict_fma node:$src1, node:$src2, node:$src3),
13800b57cec5SDimitry Andric                               (fma node:$src1, node:$src2, node:$src3)]>;
13810b57cec5SDimitry Andricdef any_fsqrt      : PatFrags<(ops node:$src),
13820b57cec5SDimitry Andric                              [(strict_fsqrt node:$src),
13830b57cec5SDimitry Andric                               (fsqrt node:$src)]>;
13840b57cec5SDimitry Andricdef any_fsin       : PatFrags<(ops node:$src),
13850b57cec5SDimitry Andric                              [(strict_fsin node:$src),
13860b57cec5SDimitry Andric                               (fsin node:$src)]>;
13870b57cec5SDimitry Andricdef any_fcos       : PatFrags<(ops node:$src),
13880b57cec5SDimitry Andric                              [(strict_fcos node:$src),
13890b57cec5SDimitry Andric                               (fcos node:$src)]>;
13900b57cec5SDimitry Andricdef any_fexp2      : PatFrags<(ops node:$src),
13910b57cec5SDimitry Andric                              [(strict_fexp2 node:$src),
13920b57cec5SDimitry Andric                               (fexp2 node:$src)]>;
13930b57cec5SDimitry Andricdef any_fpow       : PatFrags<(ops node:$lhs, node:$rhs),
13940b57cec5SDimitry Andric                              [(strict_fpow node:$lhs, node:$rhs),
13950b57cec5SDimitry Andric                               (fpow node:$lhs, node:$rhs)]>;
13960b57cec5SDimitry Andricdef any_flog2      : PatFrags<(ops node:$src),
13970b57cec5SDimitry Andric                              [(strict_flog2 node:$src),
13980b57cec5SDimitry Andric                               (flog2 node:$src)]>;
13990b57cec5SDimitry Andricdef any_frint      : PatFrags<(ops node:$src),
14000b57cec5SDimitry Andric                              [(strict_frint node:$src),
14010b57cec5SDimitry Andric                               (frint node:$src)]>;
14028bcb0991SDimitry Andricdef any_lrint      : PatFrags<(ops node:$src),
14038bcb0991SDimitry Andric                              [(strict_lrint node:$src),
14048bcb0991SDimitry Andric                               (lrint node:$src)]>;
14058bcb0991SDimitry Andricdef any_llrint     : PatFrags<(ops node:$src),
14068bcb0991SDimitry Andric                              [(strict_llrint node:$src),
14078bcb0991SDimitry Andric                               (llrint node:$src)]>;
14080b57cec5SDimitry Andricdef any_fnearbyint : PatFrags<(ops node:$src),
14090b57cec5SDimitry Andric                              [(strict_fnearbyint node:$src),
14100b57cec5SDimitry Andric                               (fnearbyint node:$src)]>;
14110b57cec5SDimitry Andricdef any_fceil      : PatFrags<(ops node:$src),
14120b57cec5SDimitry Andric                              [(strict_fceil node:$src),
14130b57cec5SDimitry Andric                               (fceil node:$src)]>;
14140b57cec5SDimitry Andricdef any_ffloor     : PatFrags<(ops node:$src),
14150b57cec5SDimitry Andric                              [(strict_ffloor node:$src),
14160b57cec5SDimitry Andric                               (ffloor node:$src)]>;
14178bcb0991SDimitry Andricdef any_lround     : PatFrags<(ops node:$src),
14188bcb0991SDimitry Andric                              [(strict_lround node:$src),
14198bcb0991SDimitry Andric                               (lround node:$src)]>;
14208bcb0991SDimitry Andricdef any_llround    : PatFrags<(ops node:$src),
14218bcb0991SDimitry Andric                              [(strict_llround node:$src),
14228bcb0991SDimitry Andric                               (llround node:$src)]>;
14230b57cec5SDimitry Andricdef any_fround     : PatFrags<(ops node:$src),
14240b57cec5SDimitry Andric                              [(strict_fround node:$src),
14250b57cec5SDimitry Andric                               (fround node:$src)]>;
1426fe6060f1SDimitry Andricdef any_froundeven : PatFrags<(ops node:$src),
1427fe6060f1SDimitry Andric                              [(strict_froundeven node:$src),
1428fe6060f1SDimitry Andric                               (froundeven node:$src)]>;
14290b57cec5SDimitry Andricdef any_ftrunc     : PatFrags<(ops node:$src),
14300b57cec5SDimitry Andric                              [(strict_ftrunc node:$src),
14310b57cec5SDimitry Andric                               (ftrunc node:$src)]>;
14320b57cec5SDimitry Andricdef any_fmaxnum    : PatFrags<(ops node:$lhs, node:$rhs),
14330b57cec5SDimitry Andric                              [(strict_fmaxnum node:$lhs, node:$rhs),
14340b57cec5SDimitry Andric                               (fmaxnum node:$lhs, node:$rhs)]>;
14350b57cec5SDimitry Andricdef any_fminnum    : PatFrags<(ops node:$lhs, node:$rhs),
14360b57cec5SDimitry Andric                              [(strict_fminnum node:$lhs, node:$rhs),
14370b57cec5SDimitry Andric                               (fminnum node:$lhs, node:$rhs)]>;
1438480093f4SDimitry Andricdef any_fmaximum   : PatFrags<(ops node:$lhs, node:$rhs),
1439480093f4SDimitry Andric                              [(strict_fmaximum node:$lhs, node:$rhs),
1440480093f4SDimitry Andric                               (fmaximum node:$lhs, node:$rhs)]>;
1441480093f4SDimitry Andricdef any_fminimum   : PatFrags<(ops node:$lhs, node:$rhs),
1442480093f4SDimitry Andric                              [(strict_fminimum node:$lhs, node:$rhs),
1443480093f4SDimitry Andric                               (fminimum node:$lhs, node:$rhs)]>;
14440b57cec5SDimitry Andricdef any_fpround    : PatFrags<(ops node:$src),
14450b57cec5SDimitry Andric                              [(strict_fpround node:$src),
14460b57cec5SDimitry Andric                               (fpround node:$src)]>;
14470b57cec5SDimitry Andricdef any_fpextend   : PatFrags<(ops node:$src),
14480b57cec5SDimitry Andric                              [(strict_fpextend node:$src),
14490b57cec5SDimitry Andric                               (fpextend node:$src)]>;
14500b57cec5SDimitry Andricdef any_extloadf32 : PatFrags<(ops node:$ptr),
14510b57cec5SDimitry Andric                              [(strict_extloadf32 node:$ptr),
14520b57cec5SDimitry Andric                               (extloadf32 node:$ptr)]>;
14530b57cec5SDimitry Andricdef any_extloadf64 : PatFrags<(ops node:$ptr),
14540b57cec5SDimitry Andric                              [(strict_extloadf64 node:$ptr),
14550b57cec5SDimitry Andric                               (extloadf64 node:$ptr)]>;
14568bcb0991SDimitry Andricdef any_fp_to_sint : PatFrags<(ops node:$src),
14578bcb0991SDimitry Andric                              [(strict_fp_to_sint node:$src),
14588bcb0991SDimitry Andric                               (fp_to_sint node:$src)]>;
14598bcb0991SDimitry Andricdef any_fp_to_uint : PatFrags<(ops node:$src),
14608bcb0991SDimitry Andric                              [(strict_fp_to_uint node:$src),
14618bcb0991SDimitry Andric                               (fp_to_uint node:$src)]>;
1462480093f4SDimitry Andricdef any_sint_to_fp : PatFrags<(ops node:$src),
1463480093f4SDimitry Andric                              [(strict_sint_to_fp node:$src),
1464480093f4SDimitry Andric                               (sint_to_fp node:$src)]>;
1465480093f4SDimitry Andricdef any_uint_to_fp : PatFrags<(ops node:$src),
1466480093f4SDimitry Andric                              [(strict_uint_to_fp node:$src),
1467480093f4SDimitry Andric                               (uint_to_fp node:$src)]>;
1468e8d8bef9SDimitry Andricdef any_fsetcc : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
1469e8d8bef9SDimitry Andric                          [(strict_fsetcc node:$lhs, node:$rhs, node:$pred),
1470e8d8bef9SDimitry Andric                           (setcc node:$lhs, node:$rhs, node:$pred)]>;
1471e8d8bef9SDimitry Andricdef any_fsetccs : PatFrags<(ops node:$lhs, node:$rhs, node:$pred),
1472e8d8bef9SDimitry Andric                          [(strict_fsetccs node:$lhs, node:$rhs, node:$pred),
1473e8d8bef9SDimitry Andric                           (setcc node:$lhs, node:$rhs, node:$pred)]>;
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andricmulticlass binary_atomic_op_ord<SDNode atomic_op> {
14765ffd83dbSDimitry Andric  def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
14775ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
1478e8d8bef9SDimitry Andric    let IsAtomic = true;
1479e8d8bef9SDimitry Andric    let IsAtomicOrderingMonotonic = true;
14800b57cec5SDimitry Andric  }
14815ffd83dbSDimitry Andric  def NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
14825ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
1483e8d8bef9SDimitry Andric    let IsAtomic = true;
1484e8d8bef9SDimitry Andric    let IsAtomicOrderingAcquire = true;
14850b57cec5SDimitry Andric  }
14865ffd83dbSDimitry Andric  def NAME#_release : PatFrag<(ops node:$ptr, node:$val),
14875ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
1488e8d8bef9SDimitry Andric    let IsAtomic = true;
1489e8d8bef9SDimitry Andric    let IsAtomicOrderingRelease = true;
14900b57cec5SDimitry Andric  }
14915ffd83dbSDimitry Andric  def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
14925ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
1493e8d8bef9SDimitry Andric    let IsAtomic = true;
1494e8d8bef9SDimitry Andric    let IsAtomicOrderingAcquireRelease = true;
14950b57cec5SDimitry Andric  }
14965ffd83dbSDimitry Andric  def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
14975ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
1498e8d8bef9SDimitry Andric    let IsAtomic = true;
1499e8d8bef9SDimitry Andric    let IsAtomicOrderingSequentiallyConsistent = true;
15000b57cec5SDimitry Andric  }
15010b57cec5SDimitry Andric}
15020b57cec5SDimitry Andric
15030b57cec5SDimitry Andricmulticlass ternary_atomic_op_ord<SDNode atomic_op> {
15045ffd83dbSDimitry Andric  def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15055ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
1506e8d8bef9SDimitry Andric    let IsAtomic = true;
1507e8d8bef9SDimitry Andric    let IsAtomicOrderingMonotonic = true;
15080b57cec5SDimitry Andric  }
15095ffd83dbSDimitry Andric  def NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15105ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
1511e8d8bef9SDimitry Andric    let IsAtomic = true;
1512e8d8bef9SDimitry Andric    let IsAtomicOrderingAcquire = true;
15130b57cec5SDimitry Andric  }
15145ffd83dbSDimitry Andric  def NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15155ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
1516e8d8bef9SDimitry Andric    let IsAtomic = true;
1517e8d8bef9SDimitry Andric    let IsAtomicOrderingRelease = true;
15180b57cec5SDimitry Andric  }
15195ffd83dbSDimitry Andric  def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15205ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
1521e8d8bef9SDimitry Andric    let IsAtomic = true;
1522e8d8bef9SDimitry Andric    let IsAtomicOrderingAcquireRelease = true;
15230b57cec5SDimitry Andric  }
15245ffd83dbSDimitry Andric  def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15255ffd83dbSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
1526e8d8bef9SDimitry Andric    let IsAtomic = true;
1527e8d8bef9SDimitry Andric    let IsAtomicOrderingSequentiallyConsistent = true;
15280b57cec5SDimitry Andric  }
15290b57cec5SDimitry Andric}
15300b57cec5SDimitry Andric
15318bcb0991SDimitry Andricmulticlass binary_atomic_op<SDNode atomic_op, bit IsInt = 1> {
15320b57cec5SDimitry Andric  def _8 : PatFrag<(ops node:$ptr, node:$val),
15330b57cec5SDimitry Andric                   (atomic_op  node:$ptr, node:$val)> {
1534e8d8bef9SDimitry Andric    let IsAtomic = true;
15358bcb0991SDimitry Andric    let MemoryVT = !if(IsInt, i8, ?);
15360b57cec5SDimitry Andric  }
15370b57cec5SDimitry Andric  def _16 : PatFrag<(ops node:$ptr, node:$val),
15380b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$val)> {
1539e8d8bef9SDimitry Andric    let IsAtomic = true;
15408bcb0991SDimitry Andric    let MemoryVT = !if(IsInt, i16, f16);
15410b57cec5SDimitry Andric  }
15420b57cec5SDimitry Andric  def _32 : PatFrag<(ops node:$ptr, node:$val),
15430b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$val)> {
1544e8d8bef9SDimitry Andric    let IsAtomic = true;
15458bcb0991SDimitry Andric    let MemoryVT = !if(IsInt, i32, f32);
15460b57cec5SDimitry Andric  }
15470b57cec5SDimitry Andric  def _64 : PatFrag<(ops node:$ptr, node:$val),
15480b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$val)> {
1549e8d8bef9SDimitry Andric    let IsAtomic = true;
15508bcb0991SDimitry Andric    let MemoryVT = !if(IsInt, i64, f64);
15510b57cec5SDimitry Andric  }
15520b57cec5SDimitry Andric
15530b57cec5SDimitry Andric  defm NAME#_8  : binary_atomic_op_ord<atomic_op>;
15540b57cec5SDimitry Andric  defm NAME#_16 : binary_atomic_op_ord<atomic_op>;
15550b57cec5SDimitry Andric  defm NAME#_32 : binary_atomic_op_ord<atomic_op>;
15560b57cec5SDimitry Andric  defm NAME#_64 : binary_atomic_op_ord<atomic_op>;
15570b57cec5SDimitry Andric}
15580b57cec5SDimitry Andric
15590b57cec5SDimitry Andricmulticlass ternary_atomic_op<SDNode atomic_op> {
15600b57cec5SDimitry Andric  def _8 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15610b57cec5SDimitry Andric                   (atomic_op  node:$ptr, node:$cmp, node:$val)> {
1562e8d8bef9SDimitry Andric    let IsAtomic = true;
15630b57cec5SDimitry Andric    let MemoryVT = i8;
15640b57cec5SDimitry Andric  }
15650b57cec5SDimitry Andric  def _16 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15660b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$cmp, node:$val)> {
1567e8d8bef9SDimitry Andric    let IsAtomic = true;
15680b57cec5SDimitry Andric    let MemoryVT = i16;
15690b57cec5SDimitry Andric  }
15700b57cec5SDimitry Andric  def _32 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15710b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$cmp, node:$val)> {
1572e8d8bef9SDimitry Andric    let IsAtomic = true;
15730b57cec5SDimitry Andric    let MemoryVT = i32;
15740b57cec5SDimitry Andric  }
15750b57cec5SDimitry Andric  def _64 : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
15760b57cec5SDimitry Andric                    (atomic_op node:$ptr, node:$cmp, node:$val)> {
1577e8d8bef9SDimitry Andric    let IsAtomic = true;
15780b57cec5SDimitry Andric    let MemoryVT = i64;
15790b57cec5SDimitry Andric  }
15800b57cec5SDimitry Andric
15810b57cec5SDimitry Andric  defm NAME#_8  : ternary_atomic_op_ord<atomic_op>;
15820b57cec5SDimitry Andric  defm NAME#_16 : ternary_atomic_op_ord<atomic_op>;
15830b57cec5SDimitry Andric  defm NAME#_32 : ternary_atomic_op_ord<atomic_op>;
15840b57cec5SDimitry Andric  defm NAME#_64 : ternary_atomic_op_ord<atomic_op>;
15850b57cec5SDimitry Andric}
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andricdefm atomic_load_add  : binary_atomic_op<atomic_load_add>;
15880b57cec5SDimitry Andricdefm atomic_swap      : binary_atomic_op<atomic_swap>;
15890b57cec5SDimitry Andricdefm atomic_load_sub  : binary_atomic_op<atomic_load_sub>;
15900b57cec5SDimitry Andricdefm atomic_load_and  : binary_atomic_op<atomic_load_and>;
15910b57cec5SDimitry Andricdefm atomic_load_clr  : binary_atomic_op<atomic_load_clr>;
15920b57cec5SDimitry Andricdefm atomic_load_or   : binary_atomic_op<atomic_load_or>;
15930b57cec5SDimitry Andricdefm atomic_load_xor  : binary_atomic_op<atomic_load_xor>;
15940b57cec5SDimitry Andricdefm atomic_load_nand : binary_atomic_op<atomic_load_nand>;
15950b57cec5SDimitry Andricdefm atomic_load_min  : binary_atomic_op<atomic_load_min>;
15960b57cec5SDimitry Andricdefm atomic_load_max  : binary_atomic_op<atomic_load_max>;
15970b57cec5SDimitry Andricdefm atomic_load_umin : binary_atomic_op<atomic_load_umin>;
15980b57cec5SDimitry Andricdefm atomic_load_umax : binary_atomic_op<atomic_load_umax>;
15990b57cec5SDimitry Andricdefm atomic_store     : binary_atomic_op<atomic_store>;
16000b57cec5SDimitry Andricdefm atomic_cmp_swap  : ternary_atomic_op<atomic_cmp_swap>;
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andricdef atomic_load_8 :
16030b57cec5SDimitry Andric  PatFrag<(ops node:$ptr),
16040b57cec5SDimitry Andric          (atomic_load node:$ptr)> {
1605e8d8bef9SDimitry Andric  let IsAtomic = true;
16060b57cec5SDimitry Andric  let MemoryVT = i8;
16070b57cec5SDimitry Andric}
16080b57cec5SDimitry Andricdef atomic_load_16 :
16090b57cec5SDimitry Andric  PatFrag<(ops node:$ptr),
16100b57cec5SDimitry Andric          (atomic_load node:$ptr)> {
1611e8d8bef9SDimitry Andric  let IsAtomic = true;
16120b57cec5SDimitry Andric  let MemoryVT = i16;
16130b57cec5SDimitry Andric}
16140b57cec5SDimitry Andricdef atomic_load_32 :
16150b57cec5SDimitry Andric  PatFrag<(ops node:$ptr),
16160b57cec5SDimitry Andric          (atomic_load node:$ptr)> {
1617e8d8bef9SDimitry Andric  let IsAtomic = true;
16180b57cec5SDimitry Andric  let MemoryVT = i32;
16190b57cec5SDimitry Andric}
16200b57cec5SDimitry Andricdef atomic_load_64 :
16210b57cec5SDimitry Andric  PatFrag<(ops node:$ptr),
16220b57cec5SDimitry Andric          (atomic_load node:$ptr)> {
1623e8d8bef9SDimitry Andric  let IsAtomic = true;
16240b57cec5SDimitry Andric  let MemoryVT = i64;
16250b57cec5SDimitry Andric}
16260b57cec5SDimitry Andric
16270b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16280b57cec5SDimitry Andric// Selection DAG Pattern Support.
16290b57cec5SDimitry Andric//
16300b57cec5SDimitry Andric// Patterns are what are actually matched against by the target-flavored
16310b57cec5SDimitry Andric// instruction selection DAG.  Instructions defined by the target implicitly
16320b57cec5SDimitry Andric// define patterns in most cases, but patterns can also be explicitly added when
16330b57cec5SDimitry Andric// an operation is defined by a sequence of instructions (e.g. loading a large
16340b57cec5SDimitry Andric// immediate value on RISC targets that do not support immediates as large as
16350b57cec5SDimitry Andric// their GPRs).
16360b57cec5SDimitry Andric//
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andricclass Pattern<dag patternToMatch, list<dag> resultInstrs> {
16390b57cec5SDimitry Andric  dag             PatternToMatch  = patternToMatch;
16400b57cec5SDimitry Andric  list<dag>       ResultInstrs    = resultInstrs;
16410b57cec5SDimitry Andric  list<Predicate> Predicates      = [];  // See class Instruction in Target.td.
16420b57cec5SDimitry Andric  int             AddedComplexity = 0;   // See class Instruction in Target.td.
16430b57cec5SDimitry Andric}
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andric// Pat - A simple (but common) form of a pattern, which produces a simple result
16460b57cec5SDimitry Andric// not needing a full list.
16470b57cec5SDimitry Andricclass Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
16480b57cec5SDimitry Andric
16490b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16500b57cec5SDimitry Andric// Complex pattern definitions.
16510b57cec5SDimitry Andric//
16520b57cec5SDimitry Andric
16530b57cec5SDimitry Andric// Complex patterns, e.g. X86 addressing mode, requires pattern matching code
16540b57cec5SDimitry Andric// in C++. NumOperands is the number of operands returned by the select function;
16550b57cec5SDimitry Andric// SelectFunc is the name of the function used to pattern match the max. pattern;
16560b57cec5SDimitry Andric// RootNodes are the list of possible root nodes of the sub-dags to match.
16570b57cec5SDimitry Andric// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
16580b57cec5SDimitry Andric//
16590b57cec5SDimitry Andricclass ComplexPattern<ValueType ty, int numops, string fn,
16600b57cec5SDimitry Andric                     list<SDNode> roots = [], list<SDNodeProperty> props = [],
16610b57cec5SDimitry Andric                     int complexity = -1> {
16620b57cec5SDimitry Andric  ValueType Ty = ty;
16630b57cec5SDimitry Andric  int NumOperands = numops;
16640b57cec5SDimitry Andric  string SelectFunc = fn;
16650b57cec5SDimitry Andric  list<SDNode> RootNodes = roots;
16660b57cec5SDimitry Andric  list<SDNodeProperty> Properties = props;
16670b57cec5SDimitry Andric  int Complexity = complexity;
16680b57cec5SDimitry Andric}
1669