69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
167 unsigned OpIdx,
bool IsByte,
185 initializeAddrModeMap();
188 bool isPPC64 = Subtarget.isPPC64();
190 const MVT RegVT = Subtarget.getScalarIntVT();
198 if (!Subtarget.hasEFPU2())
215 if (!Subtarget.hasP10Vector()) {
244 if (Subtarget.isISA3_0()) {
277 if (!Subtarget.hasSPE()) {
284 if (Subtarget.useCRBits()) {
287 if (isPPC64 || Subtarget.hasFPCVT()) {
353 if (Subtarget.isISA3_0()) {
388 if (!Subtarget.hasSPE()) {
393 if (Subtarget.hasVSX()) {
398 if (Subtarget.hasFSQRT()) {
403 if (Subtarget.hasFPRND()) {
444 if (Subtarget.hasSPE()) {
454 if (Subtarget.hasSPE())
458 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
461 if (!Subtarget.hasFSQRT() &&
462 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
465 if (Subtarget.hasFCPSGN()) {
473 if (Subtarget.hasFPRND()) {
487 if (Subtarget.isISA3_1()) {
493 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
498 if (Subtarget.isISA3_0()) {
518 if (!Subtarget.useCRBits()) {
531 if (!Subtarget.useCRBits())
534 if (Subtarget.hasFPU()) {
545 if (!Subtarget.useCRBits())
550 if (Subtarget.hasSPE()) {
582 if (Subtarget.hasDirectMove() && isPPC64) {
644 if (Subtarget.is64BitELFABI()) {
655 }
else if (Subtarget.is32BitELFABI()) {
663 if (Subtarget.is32BitELFABI())
679 if (Subtarget.isISA3_0() && isPPC64) {
707 if (Subtarget.hasSPE()) {
729 if (Subtarget.has64BitSupport()) {
744 if (Subtarget.hasLFIWAX() || isPPC64) {
750 if (Subtarget.hasSPE()) {
760 if (Subtarget.hasFPCVT()) {
761 if (Subtarget.has64BitSupport()) {
782 if (Subtarget.use64BitRegs()) {
800 if (Subtarget.has64BitSupport()) {
807 if (Subtarget.hasVSX()) {
820 if (Subtarget.hasAltivec()) {
821 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
838 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
851 if (Subtarget.hasVSX()) {
860 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
870 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
944 if (!Subtarget.hasP8Vector()) {
986 if (Subtarget.hasAltivec())
987 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
990 if (Subtarget.hasP8Altivec())
1001 if (Subtarget.hasVSX()) {
1007 if (Subtarget.hasP8Altivec())
1012 if (Subtarget.isISA3_1()) {
1058 if (Subtarget.hasVSX()) {
1061 if (Subtarget.hasP8Vector()) {
1065 if (Subtarget.hasDirectMove() && isPPC64) {
1114 if (Subtarget.hasP8Vector())
1123 if (Subtarget.hasP8Altivec()) {
1150 if (Subtarget.isISA3_1())
1253 if (Subtarget.hasP8Altivec()) {
1258 if (Subtarget.hasP9Vector()) {
1263 if (Subtarget.useCRBits()) {
1323 }
else if (Subtarget.hasVSX()) {
1348 for (
MVT VT : {MVT::f32, MVT::f64}) {
1367 if (Subtarget.hasP9Altivec()) {
1368 if (Subtarget.isISA3_1()) {
1391 if (Subtarget.hasP10Vector()) {
1406 if (Subtarget.pairedVectorMemops()) {
1411 if (Subtarget.hasMMA()) {
1412 if (Subtarget.isISAFuture()) {
1428 if (Subtarget.has64BitSupport())
1431 if (Subtarget.isISA3_1())
1449 if (Subtarget.hasAltivec()) {
1467 if (Subtarget.hasFPCVT())
1470 if (Subtarget.useCRBits())
1479 if (Subtarget.useCRBits()) {
1483 if (Subtarget.hasP8Vector())
1488 if (Subtarget.useCRBits()) {
1504 auto CPUDirective = Subtarget.getCPUDirective();
1505 switch (CPUDirective) {
1528 if (Subtarget.enableMachineScheduler())
1602void PPCTargetLowering::initializeAddrModeMap() {
1653 if (MaxAlign == MaxMaxAlign)
1656 if (MaxMaxAlign >= 32 &&
1657 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1658 MaxAlign =
Align(32);
1659 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1661 MaxAlign =
Align(16);
1665 if (EltAlign > MaxAlign)
1666 MaxAlign = EltAlign;
1668 for (
auto *EltTy : STy->elements()) {
1671 if (EltAlign > MaxAlign)
1672 MaxAlign = EltAlign;
1673 if (MaxAlign == MaxMaxAlign)
1686 if (Subtarget.hasAltivec())
1692 return Subtarget.useSoftFloat();
1696 return Subtarget.hasSPE();
1704 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1705 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1709 if (VTy->getScalarType()->isIntegerTy()) {
1711 if (ElemSizeInBits == 32) {
1712 Index = Subtarget.isLittleEndian() ? 2 : 1;
1715 if (ElemSizeInBits == 64) {
1716 Index = Subtarget.isLittleEndian() ? 1 : 0;
1727 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1744 return CFP->getValueAPF().isZero();
1749 return CFP->getValueAPF().isZero();
1757 return Op < 0 ||
Op == Val;
1769 if (ShuffleKind == 0) {
1772 for (
unsigned i = 0; i != 16; ++i)
1775 }
else if (ShuffleKind == 2) {
1778 for (
unsigned i = 0; i != 16; ++i)
1781 }
else if (ShuffleKind == 1) {
1782 unsigned j = IsLE ? 0 : 1;
1783 for (
unsigned i = 0; i != 8; ++i)
1800 if (ShuffleKind == 0) {
1803 for (
unsigned i = 0; i != 16; i += 2)
1807 }
else if (ShuffleKind == 2) {
1810 for (
unsigned i = 0; i != 16; i += 2)
1814 }
else if (ShuffleKind == 1) {
1815 unsigned j = IsLE ? 0 : 2;
1816 for (
unsigned i = 0; i != 8; i += 2)
1837 if (!Subtarget.hasP8Vector())
1841 if (ShuffleKind == 0) {
1844 for (
unsigned i = 0; i != 16; i += 4)
1850 }
else if (ShuffleKind == 2) {
1853 for (
unsigned i = 0; i != 16; i += 4)
1859 }
else if (ShuffleKind == 1) {
1860 unsigned j = IsLE ? 0 : 4;
1861 for (
unsigned i = 0; i != 8; i += 4)
1878 unsigned LHSStart,
unsigned RHSStart) {
1879 if (
N->getValueType(0) != MVT::v16i8)
1881 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1882 "Unsupported merge size!");
1884 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1885 for (
unsigned j = 0; j != UnitSize; ++j) {
1887 LHSStart+j+i*UnitSize) ||
1889 RHSStart+j+i*UnitSize))
1904 if (ShuffleKind == 1)
1906 else if (ShuffleKind == 2)
1911 if (ShuffleKind == 1)
1913 else if (ShuffleKind == 0)
1929 if (ShuffleKind == 1)
1931 else if (ShuffleKind == 2)
1936 if (ShuffleKind == 1)
1938 else if (ShuffleKind == 0)
1988 unsigned RHSStartValue) {
1989 if (
N->getValueType(0) != MVT::v16i8)
1992 for (
unsigned i = 0; i < 2; ++i)
1993 for (
unsigned j = 0; j < 4; ++j)
1995 i*RHSStartValue+j+IndexOffset) ||
1997 i*RHSStartValue+j+IndexOffset+8))
2019 unsigned indexOffset = CheckEven ? 4 : 0;
2020 if (ShuffleKind == 1)
2022 else if (ShuffleKind == 2)
2028 unsigned indexOffset = CheckEven ? 0 : 4;
2029 if (ShuffleKind == 1)
2031 else if (ShuffleKind == 0)
2047 if (
N->getValueType(0) != MVT::v16i8)
2054 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2057 if (i == 16)
return -1;
2062 if (ShiftAmt < i)
return -1;
2067 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2069 for (++i; i != 16; ++i)
2072 }
else if (ShuffleKind == 1) {
2074 for (++i; i != 16; ++i)
2081 ShiftAmt = 16 - ShiftAmt;
2090 EVT VT =
N->getValueType(0);
2091 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2092 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2095 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2099 if (
N->getMaskElt(0) % EltSize != 0)
2104 unsigned ElementBase =
N->getMaskElt(0);
2107 if (ElementBase >= 16)
2112 for (
unsigned i = 1; i != EltSize; ++i)
2113 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2116 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2118 if (
N->getMaskElt(i) < 0) {
2119 for (
unsigned j = 1; j != EltSize; ++j)
2120 if (
N->getMaskElt(i + j) >= 0)
2123 for (
unsigned j = 0; j != EltSize; ++j)
2124 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2141 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2142 "Unexpected element width.");
2143 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2145 unsigned NumOfElem = 16 / Width;
2146 unsigned MaskVal[16];
2147 for (
unsigned i = 0; i < NumOfElem; ++i) {
2148 MaskVal[0] =
N->getMaskElt(i * Width);
2149 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2151 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2155 for (
unsigned int j = 1; j < Width; ++j) {
2156 MaskVal[j] =
N->getMaskElt(i * Width + j);
2157 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2167 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2172 unsigned M0 =
N->getMaskElt(0) / 4;
2173 unsigned M1 =
N->getMaskElt(4) / 4;
2174 unsigned M2 =
N->getMaskElt(8) / 4;
2175 unsigned M3 =
N->getMaskElt(12) / 4;
2176 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2177 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2182 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2183 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2184 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2185 InsertAtByte = IsLE ? 12 : 0;
2190 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2191 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2192 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2193 InsertAtByte = IsLE ? 8 : 4;
2198 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2199 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2200 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2201 InsertAtByte = IsLE ? 4 : 8;
2206 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2207 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2208 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2209 InsertAtByte = IsLE ? 0 : 12;
2216 if (
N->getOperand(1).isUndef()) {
2219 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2220 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2221 InsertAtByte = IsLE ? 12 : 0;
2224 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2225 InsertAtByte = IsLE ? 8 : 4;
2228 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2229 InsertAtByte = IsLE ? 4 : 8;
2232 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2233 InsertAtByte = IsLE ? 0 : 12;
2242 bool &Swap,
bool IsLE) {
2243 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2249 unsigned M0 =
N->getMaskElt(0) / 4;
2250 unsigned M1 =
N->getMaskElt(4) / 4;
2251 unsigned M2 =
N->getMaskElt(8) / 4;
2252 unsigned M3 =
N->getMaskElt(12) / 4;
2256 if (
N->getOperand(1).isUndef()) {
2257 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2258 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2261 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2267 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2271 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2276 ShiftElts = (8 -
M0) % 8;
2277 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2282 ShiftElts = (4 -
M0) % 4;
2287 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2292 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2304 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2309 for (
int i = 0; i < 16; i += Width)
2310 if (
N->getMaskElt(i) != i + Width - 1)
2341 bool &Swap,
bool IsLE) {
2342 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2348 unsigned M0 =
N->getMaskElt(0) / 8;
2349 unsigned M1 =
N->getMaskElt(8) / 8;
2350 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2354 if (
N->getOperand(1).isUndef()) {
2355 if ((
M0 |
M1) < 2) {
2356 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2364 if (
M0 > 1 &&
M1 < 2) {
2374 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2379 }
else if (
M0 > 1 &&
M1 < 2) {
2387 DM = (
M0 << 1) + (
M1 & 1);
2402 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2407 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2423 unsigned EltSize = 16/
N->getNumOperands();
2424 if (EltSize < ByteSize) {
2425 unsigned Multiple = ByteSize/EltSize;
2427 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2430 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2431 if (
N->getOperand(i).isUndef())
continue;
2435 if (!UniquedVals[i&(Multiple-1)].
getNode())
2436 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2437 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2447 bool LeadingZero =
true;
2448 bool LeadingOnes =
true;
2449 for (
unsigned i = 0; i != Multiple-1; ++i) {
2450 if (!UniquedVals[i].
getNode())
continue;
2457 if (!UniquedVals[Multiple-1].
getNode())
2464 if (!UniquedVals[Multiple-1].
getNode())
2475 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2476 if (
N->getOperand(i).isUndef())
continue;
2478 OpVal =
N->getOperand(i);
2479 else if (OpVal !=
N->getOperand(i))
2485 unsigned ValSizeInBytes = EltSize;
2488 Value = CN->getZExtValue();
2490 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2497 if (ValSizeInBytes < ByteSize)
return SDValue();
2508 if (MaskVal == 0)
return SDValue();
2528 Imm = (int16_t)
N->getAsZExtVal();
2529 if (
N->getValueType(0) == MVT::i32)
2530 return Imm == (int32_t)
N->getAsZExtVal();
2532 return Imm == (int64_t)
N->getAsZExtVal();
2550 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2558 for (
SDNode *U :
N->users()) {
2560 if (Memop->getMemoryVT() == MVT::f64) {
2561 Base =
N.getOperand(0);
2562 Index =
N.getOperand(1);
2605 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2607 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2610 Base =
N.getOperand(0);
2611 Index =
N.getOperand(1);
2613 }
else if (
N.getOpcode() ==
ISD::OR) {
2615 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2627 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2628 Base =
N.getOperand(0);
2629 Index =
N.getOperand(1);
2699 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2705 Base =
N.getOperand(0);
2708 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2710 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2711 "Cannot handle constant offsets yet!");
2712 Disp =
N.getOperand(1).getOperand(0);
2717 Base =
N.getOperand(0);
2720 }
else if (
N.getOpcode() ==
ISD::OR) {
2723 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2737 Base =
N.getOperand(0);
2750 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm))) {
2753 CN->getValueType(0));
2758 if ((CN->getValueType(0) == MVT::i32 ||
2759 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2760 (!EncodingAlignment ||
2761 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2762 int Addr = (int)CN->getZExtValue();
2769 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2790 if (
N.getValueType() != MVT::i64)
2803 Base =
N.getOperand(0);
2819 Base =
N.getOperand(0);
2852 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2853 Base =
N.getOperand(0);
2854 Index =
N.getOperand(1);
2876 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2897 EVT MemVT = LD->getMemoryVT();
2904 if (!ST.hasP8Vector())
2909 if (!ST.hasP9Vector())
2921 if (
Use.getResNo() == 0 &&
2923 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2943 Ptr = LD->getBasePtr();
2944 VT = LD->getMemoryVT();
2945 Alignment = LD->getAlign();
2947 Ptr = ST->getBasePtr();
2948 VT = ST->getMemoryVT();
2949 Alignment = ST->getAlign();
2988 if (VT != MVT::i64) {
2993 if (Alignment <
Align(4))
3003 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3020 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3062 EVT VT = Subtarget.getScalarIntVT();
3064 : Subtarget.isAIXABI()
3069 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3076 EVT PtrVT =
Op.getValueType();
3082 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3083 if (Subtarget.isUsingPCRelativeCalls()) {
3088 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3092 return getTOCEntry(DAG, SDLoc(CP), GA);
3095 unsigned MOHiFlag, MOLoFlag;
3099 if (IsPIC && Subtarget.isSVR4ABI()) {
3102 return getTOCEntry(DAG, SDLoc(CP), GA);
3125 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3132 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3149 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3162 EVT PtrVT =
Op.getValueType();
3180 return getTOCEntry(DAG,
SDLoc(JT), GA);
3183 unsigned MOHiFlag, MOLoFlag;
3187 if (IsPIC && Subtarget.isSVR4ABI()) {
3190 return getTOCEntry(DAG, SDLoc(GA), GA);
3200 EVT PtrVT =
Op.getValueType();
3205 if (Subtarget.isUsingPCRelativeCalls()) {
3216 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3219 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3228 unsigned MOHiFlag, MOLoFlag;
3238 if (Subtarget.isAIXABI())
3239 return LowerGlobalTLSAddressAIX(
Op, DAG);
3241 return LowerGlobalTLSAddressLinux(
Op, DAG);
3263 if (
I.getOpcode() == Instruction::Call)
3265 if (
Function *CF = CI->getCalledFunction())
3266 if (CF->isDeclaration() &&
3267 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3275 unsigned TLSGVCnt = TLSGV.
size();
3285 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3298 const GlobalValue *GV = GA->
getGlobal();
3300 bool Is64Bit = Subtarget.isPPC64();
3304 if (Subtarget.hasAIXShLibTLSModelOpt())
3314 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3315 bool HasAIXSmallTLSGlobalAttr =
false;
3318 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3322 if (GVar->hasAttribute(
"aix-small-tls"))
3323 HasAIXSmallTLSGlobalAttr =
true;
3342 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3343 IsTLSLocalExecModel) {
3348 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3358 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3363 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3365 "currently only supported on AIX (64-bit mode).");
3367 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3371 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3375 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3377 "currently only supported on AIX (64-bit mode).");
3385 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3388 GlobalVariable *TLSGV =
3392 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3395 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3397 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3406 if (HasAIXSmallLocalDynamicTLS) {
3411 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3415 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3428 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3429 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3430 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3445 const GlobalValue *GV = GA->
getGlobal();
3447 bool is64bit = Subtarget.isPPC64();
3455 if (Subtarget.isUsingPCRelativeCalls()) {
3460 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3461 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3472 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3476 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3483 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3485 MachinePointerInfo());
3492 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3494 if (!TM.isPositionIndependent())
3495 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3501 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3507 if (Subtarget.isUsingPCRelativeCalls()) {
3510 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3518 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3526 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3531 if (Subtarget.isUsingPCRelativeCalls()) {
3535 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3536 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3544 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3553 PtrVT, GOTPtr, TGA, TGA);
3555 PtrVT, TLSAddr, TGA);
3556 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3564 EVT PtrVT =
Op.getValueType();
3567 const GlobalValue *GV = GSDN->
getGlobal();
3571 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3572 if (Subtarget.isUsingPCRelativeCalls()) {
3579 MachinePointerInfo());
3584 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3589 return getTOCEntry(DAG,
DL, GA);
3592 unsigned MOHiFlag, MOLoFlag;
3596 if (IsPIC && Subtarget.isSVR4ABI()) {
3600 return getTOCEntry(DAG,
DL, GA);
3612 bool IsStrict =
Op->isStrictFPOpcode();
3613 const SDNodeFlags
Flags =
Op.getNode()->getFlags();
3619 EVT LHSVT =
LHS.getValueType();
3623 if (LHSVT == MVT::f128 ||
3624 (Subtarget.hasSPE() && (LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
3625 (!
Flags.hasNoNaNs() || !
Flags.hasNoInfs()))) {
3626 assert(!Subtarget.hasP9Vector() &&
3627 "SETCC for f128 is already legal under Power9!");
3636 }
else if (LHSVT == MVT::f32 || LHSVT == MVT::f64) {
3640 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3642 if (
Op.getValueType() == MVT::v2i64) {
3645 if (
LHS.getValueType() == MVT::v2i64) {
3653 int ShuffV[] = {1, 0, 3, 2};
3658 dl, MVT::v4i32, Shuff, SetCC32));
3675 if (
C->isAllOnes() ||
C->isZero())
3685 EVT VT =
Op.getValueType();
3693 const SDNodeFlags
Flags =
Op->getFlags();
3699 EVT LHSVT =
LHS.getValueType();
3702 assert(Subtarget.hasSPE() &&
"LowerBR_CC used only for targets with SPE");
3704 if ((LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
Flags.hasNoNaNs() &&
3722 SDNode *
Node =
Op.getNode();
3723 EVT VT =
Node->getValueType(0);
3730 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3734 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3737 if (VT == MVT::i64) {
3756 FprPtr, MachinePointerInfo(SV), MVT::i8);
3767 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3768 InChain = OverflowArea.
getValue(1);
3771 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3801 MachinePointerInfo(SV), MVT::i8);
3814 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3815 MachinePointerInfo(), MVT::i32);
3817 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3821 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3827 Align(8),
false,
true,
nullptr, std::nullopt,
3828 MachinePointerInfo(), MachinePointerInfo());
3833 return Op.getOperand(0);
3838 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3842 "Expecting Inline ASM node.");
3852 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3857 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3858 unsigned NumVals =
Flags.getNumOperandRegisters();
3861 switch (
Flags.getKind()) {
3872 for (; NumVals; --NumVals, ++i) {
3874 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3897 if (Subtarget.isAIXABI()) {
3902 MaybeAlign PointerAlign(PointerSize);
3903 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3906 : MachineMemOperand::MONone;
3913 const Value *TrampolineAddr =
3923 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3924 PointerAlign, MMOFlags);
3926 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3927 MachinePointerInfo(TrampolineAddr, 0));
3931 SDValue TOCFromDescriptorPtr =
3933 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3934 MachinePointerInfo(Func, TOCPointerOffset),
3935 PointerAlign, MMOFlags);
3936 SDValue TrampolineTOCPointer =
3940 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3941 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3947 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3948 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3955 bool isPPC64 = (PtrVT == MVT::i64);
3962 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3968 TargetLowering::CallLoweringInfo CLI(DAG);
3969 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3973 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3974 return CallResult.second;
3979 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3984 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3989 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3990 MachinePointerInfo(SV));
4024 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4027 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4038 MachinePointerInfo(SV), MVT::i8);
4046 MachinePointerInfo(SV, nextOffset), MVT::i8);
4047 nextOffset += StackOffset;
4048 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4051 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4052 MachinePointerInfo(SV, nextOffset));
4053 nextOffset += FrameOffset;
4054 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4057 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4058 MachinePointerInfo(SV, nextOffset));
4063static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4064 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4065 PPC::F11, PPC::F12, PPC::F13};
4070 unsigned PtrByteSize) {
4072 if (Flags.isByVal())
4073 ArgSize = Flags.getByValSize();
4077 if (!Flags.isInConsecutiveRegs())
4078 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4087 unsigned PtrByteSize) {
4088 Align Alignment(PtrByteSize);
4091 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4092 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4093 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4094 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4095 Alignment =
Align(16);
4098 if (Flags.isByVal()) {
4099 auto BVAlign = Flags.getNonZeroByValAlign();
4100 if (BVAlign > PtrByteSize) {
4101 if (BVAlign.value() % PtrByteSize != 0)
4103 "ByVal alignment is not a multiple of the pointer size");
4105 Alignment = BVAlign;
4110 if (Flags.isInConsecutiveRegs()) {
4114 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4128 unsigned PtrByteSize,
unsigned LinkageSize,
4129 unsigned ParamAreaSize,
unsigned &ArgOffset,
4130 unsigned &AvailableFPRs,
4131 unsigned &AvailableVRs) {
4132 bool UseMemory =
false;
4137 ArgOffset =
alignTo(ArgOffset, Alignment);
4140 if (ArgOffset >= LinkageSize + ParamAreaSize)
4145 if (Flags.isInConsecutiveRegsLast())
4146 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4149 if (ArgOffset > LinkageSize + ParamAreaSize)
4154 if (!Flags.isByVal()) {
4155 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4156 if (AvailableFPRs > 0) {
4160 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4161 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4162 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4163 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4164 if (AvailableVRs > 0) {
4176 unsigned NumBytes) {
4180SDValue PPCTargetLowering::LowerFormalArguments(
4184 if (Subtarget.isAIXABI())
4185 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4187 if (Subtarget.is64BitELFABI())
4188 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4190 assert(Subtarget.is32BitELFABI());
4191 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4195SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4231 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4237 const Align PtrAlign(4);
4245 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4246 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4249 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4250 CCValAssign &VA = ArgLocs[i];
4262 RC = &PPC::GPRCRegClass;
4265 if (Subtarget.hasP8Vector())
4266 RC = &PPC::VSSRCRegClass;
4267 else if (Subtarget.hasSPE())
4268 RC = &PPC::GPRCRegClass;
4270 RC = &PPC::F4RCRegClass;
4273 if (Subtarget.hasVSX())
4274 RC = &PPC::VSFRCRegClass;
4275 else if (Subtarget.hasSPE())
4277 RC = &PPC::GPRCRegClass;
4279 RC = &PPC::F8RCRegClass;
4284 RC = &PPC::VRRCRegClass;
4287 RC = &PPC::VRRCRegClass;
4291 RC = &PPC::VRRCRegClass;
4298 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4299 assert(i + 1 < e &&
"No second half of double precision argument");
4304 if (!Subtarget.isLittleEndian())
4306 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4311 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4312 if (ValVT == MVT::i1)
4327 ArgOffset += ArgSize - ObjSize;
4345 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4350 unsigned MinReservedArea = CCByValInfo.getStackSize();
4351 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4367 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4368 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4370 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4373 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4376 unsigned NumFPArgRegs = std::size(FPArgRegs);
4385 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4386 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4389 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4402 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4417 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4421 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4434 if (!MemOps.
empty())
4445 const SDLoc &dl)
const {
4449 else if (
Flags.isZExt())
4456SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4462 bool isELFv2ABI = Subtarget.isELFv2ABI();
4463 bool isLittleEndian = Subtarget.isLittleEndian();
4466 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4469 "fastcc not supported on varargs functions");
4475 unsigned PtrByteSize = 8;
4476 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4479 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4480 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4483 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4484 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4487 const unsigned Num_GPR_Regs = std::size(GPR);
4489 const unsigned Num_VR_Regs = std::size(VR);
4497 bool HasParameterArea = !isELFv2ABI || isVarArg;
4498 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4499 unsigned NumBytes = LinkageSize;
4500 unsigned AvailableFPRs = Num_FPR_Regs;
4501 unsigned AvailableVRs = Num_VR_Regs;
4502 for (
const ISD::InputArg &In : Ins) {
4503 if (
In.Flags.isNest())
4507 LinkageSize, ParamAreaSize, NumBytes,
4508 AvailableFPRs, AvailableVRs))
4509 HasParameterArea =
true;
4516 unsigned ArgOffset = LinkageSize;
4517 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4520 unsigned CurArgIdx = 0;
4521 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4523 bool needsLoad =
false;
4524 EVT ObjectVT = Ins[ArgNo].VT;
4525 EVT OrigVT = Ins[ArgNo].ArgVT;
4527 unsigned ArgSize = ObjSize;
4528 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4529 if (Ins[ArgNo].isOrigArg()) {
4530 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4531 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4536 unsigned CurArgOffset;
4538 auto ComputeArgOffset = [&]() {
4542 ArgOffset =
alignTo(ArgOffset, Alignment);
4543 CurArgOffset = ArgOffset;
4550 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4551 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4556 if (
Flags.isByVal()) {
4557 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4563 ObjSize =
Flags.getByValSize();
4564 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4586 if (HasParameterArea ||
4587 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4594 if (ObjSize < PtrByteSize) {
4598 if (!isLittleEndian) {
4604 if (GPR_idx != Num_GPR_Regs) {
4611 MachinePointerInfo(&*FuncArg), ObjType);
4616 ArgOffset += PtrByteSize;
4625 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4626 if (GPR_idx == Num_GPR_Regs)
4637 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4641 MachinePointerInfo(&*FuncArg, j), ObjType);
4645 ArgOffset += ArgSize;
4654 if (
Flags.isNest()) {
4659 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4660 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4668 if (GPR_idx != Num_GPR_Regs) {
4673 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4676 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4682 ArgSize = PtrByteSize;
4693 if (FPR_idx != Num_FPR_Regs) {
4696 if (ObjectVT == MVT::f32)
4698 Subtarget.hasP8Vector()
4699 ? &PPC::VSSRCRegClass
4700 : &PPC::F4RCRegClass);
4703 ? &PPC::VSFRCRegClass
4704 : &PPC::F8RCRegClass);
4719 if (ObjectVT == MVT::f32) {
4720 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4738 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4739 ArgOffset += ArgSize;
4740 if (
Flags.isInConsecutiveRegsLast())
4741 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4755 if (VR_idx != Num_VR_Regs) {
4772 if (ObjSize < ArgSize && !isLittleEndian)
4773 CurArgOffset += ArgSize - ObjSize;
4776 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4783 unsigned MinReservedArea;
4784 if (HasParameterArea)
4785 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4787 MinReservedArea = LinkageSize;
4804 int Depth = ArgOffset;
4813 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4814 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4826 if (!MemOps.
empty())
4835 unsigned ParamSize) {
4837 if (!isTailCall)
return 0;
4841 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4843 if (SPDiff < FI->getTailCallSPDelta())
4859 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4918 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4921 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4933 const unsigned PtrByteSize = 8;
4937 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4938 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4941 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4942 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4945 const unsigned NumGPRs = std::size(GPR);
4946 const unsigned NumFPRs = 13;
4947 const unsigned NumVRs = std::size(VR);
4948 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4950 unsigned NumBytes = LinkageSize;
4951 unsigned AvailableFPRs = NumFPRs;
4952 unsigned AvailableVRs = NumVRs;
4955 if (Param.Flags.isNest())
continue;
4958 LinkageSize, ParamAreaSize, NumBytes,
4959 AvailableFPRs, AvailableVRs))
4970 auto CalleeArgEnd = CB.
arg_end();
4973 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4974 const Value* CalleeArg = *CalleeArgIter;
4975 const Value* CallerArg = &(*CallerArgIter);
4976 if (CalleeArg == CallerArg)
5002 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5012bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5017 bool isCalleeExternalSymbol)
const {
5020 if (
DisableSCO && !TailCallOpt)
return false;
5023 if (isVarArg)
return false;
5030 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5066 if (!Subtarget.isUsingPCRelativeCalls() &&
5071 if (!Subtarget.isUsingPCRelativeCalls() &&
5099bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5112 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5133 if (!
C)
return nullptr;
5135 int Addr =
C->getZExtValue();
5136 if ((Addr & 3) != 0 ||
5142 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5149struct TailCallArgumentInfo {
5154 TailCallArgumentInfo() =
default;
5164 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5165 SDValue Arg = TailCallArgs[i].Arg;
5166 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5167 int FI = TailCallArgs[i].FrameIdx;
5170 Chain, dl, Arg, FIN,
5179 int SPDiff,
const SDLoc &dl) {
5185 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5186 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5188 NewRetAddrLoc,
true);
5191 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5201 int SPDiff,
unsigned ArgOffset,
5203 int Offset = ArgOffset + SPDiff;
5206 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5208 TailCallArgumentInfo Info;
5210 Info.FrameIdxOp = FIN;
5218SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5223 LROpOut = getReturnAddrFrameIndex(DAG);
5224 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5225 MachinePointerInfo());
5241 Align Alignment = Flags.getNonZeroByValAlign();
5243 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5251 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5275 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5285 if (!MemOpChains2.
empty())
5309SDValue PPCTargetLowering::LowerCallResult(
5317 CCRetInfo.AnalyzeCallResult(
5323 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5324 CCValAssign &VA = RVLocs[i];
5329 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5339 if (!Subtarget.isLittleEndian())
5341 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5407 bool IsStrictFPCall =
false) {
5409 return PPCISD::TC_RETURN;
5411 unsigned RetOpc = 0;
5422 if (Subtarget.usePointerGlueHelper())
5423 RetOpc = PPCISD::BL_LOAD_TOC;
5429 RetOpc = PPCISD::CALL_NOTOC;
5444 RetOpc = PPCISD::CALL;
5445 if (IsStrictFPCall) {
5449 case PPCISD::BCTRL_LOAD_TOC:
5450 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5453 RetOpc = PPCISD::BCTRL_RM;
5455 case PPCISD::BL_LOAD_TOC:
5456 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5458 case PPCISD::CALL_NOTOC:
5459 RetOpc = PPCISD::CALL_NOTOC_RM;
5462 RetOpc = PPCISD::CALL_RM;
5464 case PPCISD::CALL_NOP:
5465 RetOpc = PPCISD::CALL_NOP_RM;
5479 auto isLocalCallee = [&]() {
5495 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5511 return getAIXFuncEntryPointSymbolSDNode(GV);
5518 const char *SymName = S->getSymbol();
5525 return getAIXFuncEntryPointSymbolSDNode(
F);
5531 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5539 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5546 assert(Callee.getNode() &&
"What no callee?");
5552 "Expected a CALLSEQ_STARTSDNode.");
5569 SDValue MTCTROps[] = {Chain, Callee, Glue};
5570 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5571 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5611 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5630 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5631 Alignment, MMOFlags);
5638 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5645 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5657 "Nest parameter is not supported on AIX.");
5672 const SDLoc &dl,
bool hasNest,
5682 Chain = MoveToPhysicalReg.
getValue(0);
5683 Glue = MoveToPhysicalReg.
getValue(1);
5690 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5693 const bool IsPPC64 = Subtarget.isPPC64();
5698 Ops.push_back(Chain);
5702 Ops.push_back(Callee);
5703 else if (Subtarget.usePointerGlueHelper()) {
5704 Ops.push_back(Callee);
5727 Ops.push_back(AddTOC);
5738 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5747 for (
const auto &[
Reg,
N] : RegsToPass)
5765 assert(Mask &&
"Missing call preserved mask for calling convention");
5770 Ops.push_back(Glue);
5773SDValue PPCTargetLowering::FinishCall(
5780 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5781 Subtarget.isAIXABI())
5788 if (!CFlags.IsIndirect)
5790 else if (Subtarget.usesFunctionDescriptors()) {
5791 if (Subtarget.usePointerGlueHelper()) {
5793 CFlags.HasNest, Subtarget);
5799 dl, CFlags.HasNest, Subtarget);
5811 if (CFlags.IsTailCall) {
5819 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5820 "Expecting a global address, external symbol, absolute value, "
5821 "register or an indirect tail call when PC Relative calls are "
5824 assert(CallOpc == PPCISD::TC_RETURN &&
5825 "Unexpected call opcode for a tail call.");
5832 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5833 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5845 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5848 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5868 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5869 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5873bool PPCTargetLowering::isEligibleForTCO(
5878 bool isCalleeExternalSymbol)
const {
5882 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5883 return IsEligibleForTailCallOptimization_64SVR4(
5884 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5885 isCalleeExternalSymbol);
5887 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5915 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5930 "Callee should be an llvm::Function object.");
5933 <<
"\nTCO callee: ");
5940 "site marked musttail");
5947 Callee = LowerGlobalAddress(Callee, DAG);
5950 CallConv, isTailCall, isVarArg, isPatchPoint,
5953 Subtarget.is64BitELFABI() &&
5957 if (Subtarget.isAIXABI())
5958 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5961 assert(Subtarget.isSVR4ABI());
5962 if (Subtarget.isPPC64())
5963 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5965 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5969SDValue PPCTargetLowering::LowerCall_32SVR4(
5980 const bool IsVarArg = CFlags.IsVarArg;
5981 const bool IsTailCall = CFlags.IsTailCall;
5987 const Align PtrAlign(4);
5998 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6006 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6009 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6016 unsigned NumArgs = Outs.
size();
6018 for (
unsigned i = 0; i != NumArgs; ++i) {
6019 MVT ArgVT = Outs[i].VT;
6020 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6025 Outs[i].OrigTy, CCInfo);
6028 ArgFlags, Outs[i].OrigTy, CCInfo);
6033 errs() <<
"Call operand #" << i <<
" has unhandled type "
6046 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6049 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6056 unsigned NumBytes = CCByValInfo.getStackSize();
6070 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6081 bool seenFloatArg =
false;
6086 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6088 ++i, ++RealArgIdx) {
6089 CCValAssign &VA = ArgLocs[i];
6090 SDValue Arg = OutVals[RealArgIdx];
6091 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6093 if (
Flags.isByVal()) {
6098 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6099 CCValAssign &ByValVA = ByValArgLocs[
j++];
6121 Chain = CallSeqStart = NewCallSeqStart;
6140 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6141 bool IsLE = Subtarget.isLittleEndian();
6142 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6145 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6147 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6162 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6171 if (!MemOpChains.
empty())
6177 for (
const auto &[
Reg,
N] : RegsToPass) {
6185 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6188 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6198 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6199 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6204SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6216 return NewCallSeqStart;
6219SDValue PPCTargetLowering::LowerCall_64SVR4(
6226 bool isELFv2ABI = Subtarget.isELFv2ABI();
6227 bool isLittleEndian = Subtarget.isLittleEndian();
6229 bool IsSibCall =
false;
6233 unsigned PtrByteSize = 8;
6246 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6248 assert(!(IsFastCall && CFlags.IsVarArg) &&
6249 "fastcc not supported on varargs functions");
6255 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6256 unsigned NumBytes = LinkageSize;
6257 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6260 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6261 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6264 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6265 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6268 const unsigned NumGPRs = std::size(GPR);
6270 const unsigned NumVRs = std::size(VR);
6276 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6277 if (!HasParameterArea) {
6278 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6279 unsigned AvailableFPRs = NumFPRs;
6280 unsigned AvailableVRs = NumVRs;
6281 unsigned NumBytesTmp = NumBytes;
6282 for (
unsigned i = 0; i !=
NumOps; ++i) {
6283 if (Outs[i].
Flags.isNest())
continue;
6285 PtrByteSize, LinkageSize, ParamAreaSize,
6286 NumBytesTmp, AvailableFPRs, AvailableVRs))
6287 HasParameterArea =
true;
6293 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6298 HasParameterArea =
false;
6301 for (
unsigned i = 0; i !=
NumOps; ++i) {
6302 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6303 EVT ArgVT = Outs[i].VT;
6304 EVT OrigVT = Outs[i].ArgVT;
6310 if (
Flags.isByVal()) {
6311 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6312 if (NumGPRsUsed > NumGPRs)
6313 HasParameterArea =
true;
6320 if (++NumGPRsUsed <= NumGPRs)
6330 if (++NumVRsUsed <= NumVRs)
6334 if (++NumVRsUsed <= NumVRs)
6339 if (++NumFPRsUsed <= NumFPRs)
6343 HasParameterArea =
true;
6350 NumBytes =
alignTo(NumBytes, Alignement);
6353 if (
Flags.isInConsecutiveRegsLast())
6354 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6357 unsigned NumBytesActuallyUsed = NumBytes;
6367 if (HasParameterArea)
6368 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6370 NumBytes = LinkageSize;
6385 if (CFlags.IsTailCall)
6397 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6408 unsigned ArgOffset = LinkageSize;
6414 for (
unsigned i = 0; i !=
NumOps; ++i) {
6416 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6417 EVT ArgVT = Outs[i].VT;
6418 EVT OrigVT = Outs[i].ArgVT;
6427 auto ComputePtrOff = [&]() {
6431 ArgOffset =
alignTo(ArgOffset, Alignment);
6442 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6443 GPR_idx = std::min(GPR_idx, NumGPRs);
6450 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6456 if (
Flags.isByVal()) {
6474 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6475 if (GPR_idx != NumGPRs) {
6477 MachinePointerInfo(), VT);
6481 ArgOffset += PtrByteSize;
6486 if (GPR_idx == NumGPRs &&
Size < 8) {
6488 if (!isLittleEndian) {
6493 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6496 ArgOffset += PtrByteSize;
6505 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6506 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6511 if (
Size < 8 && GPR_idx != NumGPRs) {
6521 if (!isLittleEndian) {
6525 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6531 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6536 ArgOffset += PtrByteSize;
6542 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6545 if (GPR_idx != NumGPRs) {
6546 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6549 MachinePointerInfo(), ObjType);
6553 ArgOffset += PtrByteSize;
6555 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6567 if (
Flags.isNest()) {
6569 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6576 if (GPR_idx != NumGPRs) {
6577 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6582 assert(HasParameterArea &&
6583 "Parameter area must exist to pass an argument in memory.");
6585 true, CFlags.IsTailCall,
false, MemOpChains,
6586 TailCallArguments, dl);
6588 ArgOffset += PtrByteSize;
6591 ArgOffset += PtrByteSize;
6604 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6605 bool NeededLoad =
false;
6608 if (FPR_idx != NumFPRs)
6609 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6612 if (!NeedGPROrStack)
6614 else if (GPR_idx != NumGPRs && !IsFastCall) {
6628 }
else if (!
Flags.isInConsecutiveRegs()) {
6634 }
else if (ArgOffset % PtrByteSize != 0) {
6638 if (!isLittleEndian)
6643 }
else if (
Flags.isInConsecutiveRegsLast()) {
6646 if (!isLittleEndian)
6656 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6664 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6669 assert(HasParameterArea &&
6670 "Parameter area must exist to pass an argument in memory.");
6672 true, CFlags.IsTailCall,
false, MemOpChains,
6673 TailCallArguments, dl);
6680 if (!IsFastCall || NeededLoad) {
6682 Flags.isInConsecutiveRegs()) ? 4 : 8;
6683 if (
Flags.isInConsecutiveRegsLast())
6684 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6704 if (CFlags.IsVarArg) {
6705 assert(HasParameterArea &&
6706 "Parameter area must exist if we have a varargs call.");
6710 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6712 if (VR_idx != NumVRs) {
6714 DAG.
getLoad(MVT::v4f32, dl,
Store, PtrOff, MachinePointerInfo());
6719 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6720 if (GPR_idx == NumGPRs)
6725 DAG.
getLoad(PtrVT, dl,
Store, Ix, MachinePointerInfo());
6733 if (VR_idx != NumVRs) {
6734 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6739 assert(HasParameterArea &&
6740 "Parameter area must exist to pass an argument in memory.");
6742 true, CFlags.IsTailCall,
true, MemOpChains,
6743 TailCallArguments, dl);
6754 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6755 "mismatch in size of parameter area");
6756 (void)NumBytesActuallyUsed;
6758 if (!MemOpChains.
empty())
6764 if (CFlags.IsIndirect) {
6768 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6773 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6783 if (isELFv2ABI && !CFlags.IsPatchPoint)
6784 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6790 for (
const auto &[
Reg,
N] : RegsToPass) {
6795 if (CFlags.IsTailCall && !IsSibCall)
6799 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6800 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6807 "Required alignment greater than stack alignment.");
6827 return RequiredAlign <= 8;
6832 return RequiredAlign <= 4;
6840 State.getMachineFunction().getSubtarget());
6841 const bool IsPPC64 = Subtarget.isPPC64();
6842 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6843 const Align PtrAlign(PtrSize);
6844 const Align StackAlign(16);
6847 if (ValVT == MVT::f128)
6851 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6852 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6854 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6855 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6858 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6859 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6860 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6865 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6874 if (ByValAlign > StackAlign)
6876 "16 are not supported.");
6879 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6883 if (ByValSize == 0) {
6885 State.getStackSize(), RegVT, LocInfo));
6890 unsigned NextReg = State.getFirstUnallocated(GPRs);
6891 while (NextReg != GPRs.
size() &&
6896 State.AllocateStack(PtrSize, PtrAlign);
6897 assert(
Reg &&
"Alocating register unexpectedly failed.");
6899 NextReg = State.getFirstUnallocated(GPRs);
6902 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6903 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6923 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6927 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6946 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6952 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6954 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6955 if (State.isVarArg()) {
6987 const unsigned VecSize = 16;
6988 const Align VecAlign(VecSize);
6990 if (!State.isVarArg()) {
6993 if (
MCRegister VReg = State.AllocateReg(VR)) {
7000 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7005 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7008 while (NextRegIndex != GPRs.
size() &&
7012 State.AllocateStack(PtrSize, PtrAlign);
7013 assert(
Reg &&
"Allocating register unexpectedly failed.");
7015 NextRegIndex = State.getFirstUnallocated(GPRs);
7023 if (
MCRegister VReg = State.AllocateReg(VR)) {
7026 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7027 State.AllocateReg(GPRs);
7028 State.AllocateStack(VecSize, VecAlign);
7032 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7038 if (NextRegIndex == GPRs.
size()) {
7039 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7047 if (GPRs[NextRegIndex] == PPC::R9) {
7048 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7052 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7053 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7054 assert(FirstReg && SecondReg &&
7055 "Allocating R9 or R10 unexpectedly failed.");
7066 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7069 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7071 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7086 assert((IsPPC64 || SVT != MVT::i64) &&
7087 "i64 should have been split for 32-bit codegen.");
7095 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7097 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7099 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7107 return &PPC::VRRCRegClass;
7120 else if (Flags.isZExt())
7132 "Reg must be a valid argument register!");
7133 return LASize + 4 * (
Reg - PPC::R3);
7138 "Reg must be a valid argument register!");
7139 return LASize + 8 * (
Reg - PPC::X3);
7185SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7192 "Unexpected calling convention!");
7200 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7202 const bool IsPPC64 = Subtarget.isPPC64();
7203 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7209 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7210 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7214 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7215 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7216 uint64_t SaveStackPos = CCInfo.getStackSize();
7218 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7222 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7223 CCValAssign &VA = ArgLocs[
I++];
7228 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7229 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7241 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7243 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7249 MachinePointerInfo(),
Align(PtrByteSize));
7255 unsigned StoreSize =
7257 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7260 auto HandleMemLoc = [&]() {
7263 assert((ValSize <= LocSize) &&
7264 "Object size is larger than size of MemLoc");
7267 if (LocSize > ValSize)
7268 CurArgOffset += LocSize - ValSize;
7270 const bool IsImmutable =
7276 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7310 assert(isVarArg &&
"Only use custom memloc for vararg.");
7313 const unsigned OriginalValNo = VA.
getValNo();
7314 (void)OriginalValNo;
7316 auto HandleCustomVecRegLoc = [&]() {
7317 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7318 "Missing custom RegLoc.");
7321 "Unexpected Val type for custom RegLoc.");
7323 "ValNo mismatch between custom MemLoc and RegLoc.");
7327 Subtarget.hasVSX()));
7334 HandleCustomVecRegLoc();
7335 HandleCustomVecRegLoc();
7339 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7341 "Only 2 custom RegLocs expected for 64-bit codegen.");
7342 HandleCustomVecRegLoc();
7343 HandleCustomVecRegLoc();
7387 const unsigned Size =
7399 if (
Flags.isByVal()) {
7403 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7405 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7414 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7416 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7429 CopyFrom.
getValue(1), dl, CopyFrom,
7439 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7442 "RegLocs should be for ByVal argument.");
7444 const CCValAssign RL = ArgLocs[
I++];
7449 if (
Offset != StackSize) {
7451 "Expected MemLoc for remaining bytes.");
7452 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7466 Subtarget.hasVSX()));
7483 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7485 unsigned CallerReservedArea = std::max<unsigned>(
7486 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7492 CallerReservedArea =
7497 int VAListIndex = 0;
7501 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7502 unsigned FixedStackSize =
7503 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7519 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7520 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7522 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7523 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7524 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7530 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7532 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7535 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7536 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7539 MachinePointerInfo MPI =
7549 if (!MemOps.
empty())
7555SDValue PPCTargetLowering::LowerCall_AIX(
7568 "Unexpected calling convention!");
7570 if (CFlags.IsPatchPoint)
7573 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7577 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7584 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7585 const bool IsPPC64 = Subtarget.isPPC64();
7587 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7588 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7589 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7597 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7598 const unsigned NumBytes = std::max<unsigned>(
7599 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7615 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7616 const unsigned ValNo = ArgLocs[
I].getValNo();
7618 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7620 if (
Flags.isByVal()) {
7621 const unsigned ByValSize =
Flags.getByValSize();
7629 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7635 MachinePointerInfo(), VT);
7638 unsigned LoadOffset = 0;
7641 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7644 LoadOffset += PtrByteSize;
7645 const CCValAssign &ByValVA = ArgLocs[
I++];
7647 "Unexpected location for pass-by-value argument.");
7651 if (LoadOffset == ByValSize)
7655 assert(ArgLocs[
I].getValNo() == ValNo &&
7656 "Expected additional location for by-value argument.");
7658 if (ArgLocs[
I].isMemLoc()) {
7659 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7660 const CCValAssign &ByValVA = ArgLocs[
I++];
7661 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7664 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7670 CallSeqStart, MemcpyFlags, DAG, dl);
7679 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7680 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7681 "Unexpected register residue for by-value argument.");
7683 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7687 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7697 "Unexpected load emitted during handling of pass-by-value "
7705 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7710 const CCValAssign &ByValVA = ArgLocs[
I++];
7715 CCValAssign &VA = ArgLocs[
I++];
7740 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7746 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7748 const unsigned OriginalValNo = VA.
getValNo();
7750 unsigned LoadOffset = 0;
7751 auto HandleCustomVecRegLoc = [&]() {
7752 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7753 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7754 "Expected custom RegLoc.");
7755 CCValAssign RegVA = ArgLocs[
I++];
7757 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7763 LoadOffset += PtrByteSize;
7769 HandleCustomVecRegLoc();
7770 HandleCustomVecRegLoc();
7772 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7773 ArgLocs[
I].getValNo() == OriginalValNo) {
7775 "Only 2 custom RegLocs expected for 64-bit codegen.");
7776 HandleCustomVecRegLoc();
7777 HandleCustomVecRegLoc();
7788 DAG.
getStore(Chain, dl, Arg, PtrOff,
7790 Subtarget.getFrameLowering()->getStackAlign()));
7797 "Unexpected register handling for calling convention.");
7803 "Custom register handling only expected for VarArg.");
7808 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7812 else if (Arg.getValueType().getFixedSizeInBits() <
7820 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7821 "Unexpected custom register for argument!");
7822 CCValAssign &GPR1 = VA;
7831 CCValAssign &PeekArg = ArgLocs[
I];
7834 CCValAssign &GPR2 = ArgLocs[
I++];
7842 if (!MemOpChains.
empty())
7847 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7848 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7849 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7850 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7851 const MVT PtrVT = Subtarget.getScalarIntVT();
7852 const unsigned TOCSaveOffset =
7853 Subtarget.getFrameLowering()->getTOCSaveOffset();
7868 for (
auto Reg : RegsToPass) {
7873 const int SPDiff = 0;
7874 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7875 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7883 const Type *RetTy)
const {
7885 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7886 return CCInfo.CheckReturn(
7901 CCInfo.AnalyzeReturn(Outs,
7910 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7911 CCValAssign &VA = RVLocs[i];
7914 SDValue Arg = OutVals[RealResIdx];
7929 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7930 bool isLittleEndian = Subtarget.isLittleEndian();
7933 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7937 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7952 RetOps.push_back(Glue);
7954 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7958PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7963 EVT IntVT =
Op.getValueType();
7967 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7971 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7983 bool isPPC64 = Subtarget.isPPC64();
7984 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7993 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7999 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8004 bool isPPC64 = Subtarget.isPPC64();
8009 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8015 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8025PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8027 bool isPPC64 = Subtarget.isPPC64();
8032 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8038 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8061 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8063 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8065 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8066 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8073 bool isPPC64 = Subtarget.isPPC64();
8083 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8085 Op.getOperand(0),
Op.getOperand(1));
8091 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8092 Op.getOperand(0),
Op.getOperand(1));
8096 if (
Op.getValueType().isVector())
8097 return LowerVectorLoad(
Op, DAG);
8099 assert(
Op.getValueType() == MVT::i1 &&
8100 "Custom lowering only for i1 loads");
8109 MachineMemOperand *MMO =
LD->getMemOperand();
8113 BasePtr, MVT::i8, MMO);
8121 if (
Op.getOperand(1).getValueType().isVector())
8122 return LowerVectorStore(
Op, DAG);
8124 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8125 "Custom lowering only for i1 stores");
8135 MachineMemOperand *MMO =
ST->getMemOperand();
8144 assert(
Op.getValueType() == MVT::i1 &&
8145 "Custom lowering only for i1 results");
8173 EVT TrgVT =
Op.getValueType();
8197 if (SrcSize == 256) {
8208 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8214 SmallVector<int, 16> ShuffV;
8215 if (Subtarget.isLittleEndian())
8216 for (
unsigned i = 0; i < TrgNumElts; ++i)
8219 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8223 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8236 EVT ResVT =
Op.getValueType();
8237 EVT CmpVT =
Op.getOperand(0).getValueType();
8239 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8245 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8258 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8262 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8279 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8292 if (
LHS.getValueType() == MVT::f32)
8294 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8297 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8305 if (
LHS.getValueType() == MVT::f32)
8307 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8314 if (
LHS.getValueType() == MVT::f32)
8316 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8328 if (
Cmp.getValueType() == MVT::f32)
8330 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8333 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8338 if (
Cmp.getValueType() == MVT::f32)
8340 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8344 if (
Cmp.getValueType() == MVT::f32)
8346 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8350 if (
Cmp.getValueType() == MVT::f32)
8352 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8356 if (
Cmp.getValueType() == MVT::f32)
8358 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8367 case PPCISD::FCTIDZ:
8368 return PPCISD::STRICT_FCTIDZ;
8369 case PPCISD::FCTIWZ:
8370 return PPCISD::STRICT_FCTIWZ;
8371 case PPCISD::FCTIDUZ:
8372 return PPCISD::STRICT_FCTIDUZ;
8373 case PPCISD::FCTIWUZ:
8374 return PPCISD::STRICT_FCTIWUZ;
8376 return PPCISD::STRICT_FCFID;
8377 case PPCISD::FCFIDU:
8378 return PPCISD::STRICT_FCFIDU;
8379 case PPCISD::FCFIDS:
8380 return PPCISD::STRICT_FCFIDS;
8381 case PPCISD::FCFIDUS:
8382 return PPCISD::STRICT_FCFIDUS;
8389 bool IsStrict =
Op->isStrictFPOpcode();
8398 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8400 MVT DestTy =
Op.getSimpleValueType();
8401 assert(Src.getValueType().isFloatingPoint() &&
8402 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8403 DestTy == MVT::i64) &&
8404 "Invalid FP_TO_INT types");
8405 if (Src.getValueType() == MVT::f32) {
8409 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8414 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8420 Opc = IsSigned ? PPCISD::FCTIWZ
8421 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8424 assert((IsSigned || Subtarget.hasFPCVT()) &&
8425 "i64 FP_TO_UINT is supported only with FPCVT");
8426 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8428 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8440void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8442 const SDLoc &dl)
const {
8446 bool IsStrict =
Op->isStrictFPOpcode();
8449 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8450 (IsSigned || Subtarget.hasFPCVT());
8453 MachinePointerInfo MPI =
8462 MachineMemOperand *MMO =
8468 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8472 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8473 !Subtarget.isLittleEndian()) {
8490 const SDLoc &dl)
const {
8493 if (
Op->isStrictFPOpcode())
8500 const SDLoc &dl)
const {
8501 bool IsStrict =
Op->isStrictFPOpcode();
8504 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8505 EVT SrcVT = Src.getValueType();
8506 EVT DstVT =
Op.getValueType();