10b57cec5SDimitry Andric //===-- PPCMachineFunctionInfo.cpp - Private data used for PowerPC --------===// 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 #include "PPCMachineFunctionInfo.h" 100b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 11e8d8bef9SDimitry Andric #include "llvm/BinaryFormat/XCOFF.h" 120b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 145ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric using namespace llvm; 175ffd83dbSDimitry Andric static cl::opt<bool> PPCDisableNonVolatileCR( 185ffd83dbSDimitry Andric "ppc-disable-non-volatile-cr", 195ffd83dbSDimitry Andric cl::desc("Disable the use of non-volatile CR register fields"), 205ffd83dbSDimitry Andric cl::init(false), cl::Hidden); 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric void PPCFunctionInfo::anchor() {} 235ffd83dbSDimitry Andric PPCFunctionInfo::PPCFunctionInfo(const MachineFunction &MF) 245ffd83dbSDimitry Andric : DisableNonVolatileCR(PPCDisableNonVolatileCR) {} 250b57cec5SDimitry Andric 26*81ad6265SDimitry Andric MachineFunctionInfo * 27*81ad6265SDimitry Andric PPCFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 28*81ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *> 29*81ad6265SDimitry Andric &Src2DstMBB) const { 30*81ad6265SDimitry Andric return DestMF.cloneInfo<PPCFunctionInfo>(*this); 31*81ad6265SDimitry Andric } 32*81ad6265SDimitry Andric 335ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getPICOffsetSymbol(MachineFunction &MF) const { 340b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 350b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 360b57cec5SDimitry Andric Twine(MF.getFunctionNumber()) + 370b57cec5SDimitry Andric "$poff"); 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric 405ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getGlobalEPSymbol(MachineFunction &MF) const { 410b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 420b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 430b57cec5SDimitry Andric "func_gep" + 440b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 475ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getLocalEPSymbol(MachineFunction &MF) const { 480b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 490b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 500b57cec5SDimitry Andric "func_lep" + 510b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 545ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getTOCOffsetSymbol(MachineFunction &MF) const { 550b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 560b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 570b57cec5SDimitry Andric "func_toc" + 580b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 615ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInSExt(Register VReg) const { 625ffd83dbSDimitry Andric for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs) 630b57cec5SDimitry Andric if (LiveIn.first == VReg) 640b57cec5SDimitry Andric return LiveIn.second.isSExt(); 650b57cec5SDimitry Andric return false; 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 685ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInZExt(Register VReg) const { 695ffd83dbSDimitry Andric for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs) 700b57cec5SDimitry Andric if (LiveIn.first == VReg) 710b57cec5SDimitry Andric return LiveIn.second.isZExt(); 720b57cec5SDimitry Andric return false; 730b57cec5SDimitry Andric } 74e8d8bef9SDimitry Andric 75e8d8bef9SDimitry Andric void PPCFunctionInfo::appendParameterType(ParamType Type) { 76e8d8bef9SDimitry Andric 77fe6060f1SDimitry Andric ParamtersType.push_back(Type); 78fe6060f1SDimitry Andric switch (Type) { 79fe6060f1SDimitry Andric case FixedType: 80fe6060f1SDimitry Andric ++FixedParmsNum; 81fe6060f1SDimitry Andric return; 82fe6060f1SDimitry Andric case ShortFloatingPoint: 83fe6060f1SDimitry Andric case LongFloatingPoint: 84fe6060f1SDimitry Andric ++FloatingParmsNum; 85fe6060f1SDimitry Andric return; 86fe6060f1SDimitry Andric case VectorChar: 87fe6060f1SDimitry Andric case VectorShort: 88fe6060f1SDimitry Andric case VectorInt: 89fe6060f1SDimitry Andric case VectorFloat: 90fe6060f1SDimitry Andric ++VectorParmsNum; 91e8d8bef9SDimitry Andric return; 92e8d8bef9SDimitry Andric } 93fe6060f1SDimitry Andric llvm_unreachable("Error ParamType type."); 94fe6060f1SDimitry Andric } 95e8d8bef9SDimitry Andric 96fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getVecExtParmsType() const { 97e8d8bef9SDimitry Andric 98fe6060f1SDimitry Andric uint32_t VectExtParamInfo = 0; 99fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 100fe6060f1SDimitry Andric int Bits = 0; 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric if (!hasVectorParms()) 103fe6060f1SDimitry Andric return 0; 104fe6060f1SDimitry Andric 105fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) { 106fe6060f1SDimitry Andric switch (Elt) { 107fe6060f1SDimitry Andric case VectorChar: 108fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 109fe6060f1SDimitry Andric VectExtParamInfo |= 110fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits; 111fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 112fe6060f1SDimitry Andric break; 113fe6060f1SDimitry Andric case VectorShort: 114fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 115fe6060f1SDimitry Andric VectExtParamInfo |= 116fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits; 117fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 118fe6060f1SDimitry Andric break; 119fe6060f1SDimitry Andric case VectorInt: 120fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 121fe6060f1SDimitry Andric VectExtParamInfo |= 122fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits; 123fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 124fe6060f1SDimitry Andric break; 125fe6060f1SDimitry Andric case VectorFloat: 126fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 127fe6060f1SDimitry Andric VectExtParamInfo |= 128fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits; 129fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 130fe6060f1SDimitry Andric break; 131fe6060f1SDimitry Andric default: 132fe6060f1SDimitry Andric break; 133fe6060f1SDimitry Andric } 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric // There are only 32bits in the VectExtParamInfo. 136fe6060f1SDimitry Andric if (Bits >= 32) 137fe6060f1SDimitry Andric break; 138fe6060f1SDimitry Andric } 139fe6060f1SDimitry Andric return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo; 140fe6060f1SDimitry Andric } 141fe6060f1SDimitry Andric 142fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getParmsType() const { 143fe6060f1SDimitry Andric uint32_t ParamsTypeInfo = 0; 144fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 145fe6060f1SDimitry Andric 146fe6060f1SDimitry Andric int Bits = 0; 147fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) { 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms()))) 150fe6060f1SDimitry Andric break; 151fe6060f1SDimitry Andric 152fe6060f1SDimitry Andric switch (Elt) { 153fe6060f1SDimitry Andric case FixedType: 154fe6060f1SDimitry Andric if (hasVectorParms()) { 155fe6060f1SDimitry Andric //'00' ==> fixed parameter if HasVectorParms is true. 156fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 157fe6060f1SDimitry Andric ParamsTypeInfo |= 158fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits; 159fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 160e8d8bef9SDimitry Andric } else { 161fe6060f1SDimitry Andric //'0' ==> fixed parameter if HasVectorParms is false. 162fe6060f1SDimitry Andric ParamsTypeInfo <<= 1; 163e8d8bef9SDimitry Andric ++Bits; 164e8d8bef9SDimitry Andric } 165fe6060f1SDimitry Andric break; 166fe6060f1SDimitry Andric case ShortFloatingPoint: 167fe6060f1SDimitry Andric // '10'b => floating point short parameter. 168fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 169fe6060f1SDimitry Andric ParamsTypeInfo |= 170fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits; 171fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 172fe6060f1SDimitry Andric break; 173fe6060f1SDimitry Andric case LongFloatingPoint: 174fe6060f1SDimitry Andric // '11'b => floating point long parameter. 175fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 176fe6060f1SDimitry Andric ParamsTypeInfo |= 177fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits; 178fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 179fe6060f1SDimitry Andric break; 180fe6060f1SDimitry Andric case VectorChar: 181fe6060f1SDimitry Andric case VectorShort: 182fe6060f1SDimitry Andric case VectorInt: 183fe6060f1SDimitry Andric case VectorFloat: 184fe6060f1SDimitry Andric // '01' ==> vector parameter 185fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 186fe6060f1SDimitry Andric ParamsTypeInfo |= 187fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits; 188fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 189fe6060f1SDimitry Andric break; 190fe6060f1SDimitry Andric } 191e8d8bef9SDimitry Andric } 192e8d8bef9SDimitry Andric 193fe6060f1SDimitry Andric return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo; 194e8d8bef9SDimitry Andric } 195