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 265ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getPICOffsetSymbol(MachineFunction &MF) const { 270b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 280b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 290b57cec5SDimitry Andric Twine(MF.getFunctionNumber()) + 300b57cec5SDimitry Andric "$poff"); 310b57cec5SDimitry Andric } 320b57cec5SDimitry Andric 335ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getGlobalEPSymbol(MachineFunction &MF) const { 340b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 350b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 360b57cec5SDimitry Andric "func_gep" + 370b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric 405ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getLocalEPSymbol(MachineFunction &MF) const { 410b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 420b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 430b57cec5SDimitry Andric "func_lep" + 440b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 475ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getTOCOffsetSymbol(MachineFunction &MF) const { 480b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 490b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 500b57cec5SDimitry Andric "func_toc" + 510b57cec5SDimitry Andric Twine(MF.getFunctionNumber())); 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 545ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInSExt(Register VReg) const { 555ffd83dbSDimitry Andric for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs) 560b57cec5SDimitry Andric if (LiveIn.first == VReg) 570b57cec5SDimitry Andric return LiveIn.second.isSExt(); 580b57cec5SDimitry Andric return false; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 615ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInZExt(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.isZExt(); 650b57cec5SDimitry Andric return false; 660b57cec5SDimitry Andric } 67e8d8bef9SDimitry Andric 68e8d8bef9SDimitry Andric void PPCFunctionInfo::appendParameterType(ParamType Type) { 69e8d8bef9SDimitry Andric 70*fe6060f1SDimitry Andric ParamtersType.push_back(Type); 71*fe6060f1SDimitry Andric switch (Type) { 72*fe6060f1SDimitry Andric case FixedType: 73*fe6060f1SDimitry Andric ++FixedParmsNum; 74*fe6060f1SDimitry Andric return; 75*fe6060f1SDimitry Andric case ShortFloatingPoint: 76*fe6060f1SDimitry Andric case LongFloatingPoint: 77*fe6060f1SDimitry Andric ++FloatingParmsNum; 78*fe6060f1SDimitry Andric return; 79*fe6060f1SDimitry Andric case VectorChar: 80*fe6060f1SDimitry Andric case VectorShort: 81*fe6060f1SDimitry Andric case VectorInt: 82*fe6060f1SDimitry Andric case VectorFloat: 83*fe6060f1SDimitry Andric ++VectorParmsNum; 84e8d8bef9SDimitry Andric return; 85e8d8bef9SDimitry Andric } 86*fe6060f1SDimitry Andric llvm_unreachable("Error ParamType type."); 87*fe6060f1SDimitry Andric } 88e8d8bef9SDimitry Andric 89*fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getVecExtParmsType() const { 90e8d8bef9SDimitry Andric 91*fe6060f1SDimitry Andric uint32_t VectExtParamInfo = 0; 92*fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 93*fe6060f1SDimitry Andric int Bits = 0; 94*fe6060f1SDimitry Andric 95*fe6060f1SDimitry Andric if (!hasVectorParms()) 96*fe6060f1SDimitry Andric return 0; 97*fe6060f1SDimitry Andric 98*fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) { 99*fe6060f1SDimitry Andric switch (Elt) { 100*fe6060f1SDimitry Andric case VectorChar: 101*fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 102*fe6060f1SDimitry Andric VectExtParamInfo |= 103*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits; 104*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 105*fe6060f1SDimitry Andric break; 106*fe6060f1SDimitry Andric case VectorShort: 107*fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 108*fe6060f1SDimitry Andric VectExtParamInfo |= 109*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits; 110*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 111*fe6060f1SDimitry Andric break; 112*fe6060f1SDimitry Andric case VectorInt: 113*fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 114*fe6060f1SDimitry Andric VectExtParamInfo |= 115*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits; 116*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 117*fe6060f1SDimitry Andric break; 118*fe6060f1SDimitry Andric case VectorFloat: 119*fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 120*fe6060f1SDimitry Andric VectExtParamInfo |= 121*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits; 122*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 123*fe6060f1SDimitry Andric break; 124*fe6060f1SDimitry Andric default: 125*fe6060f1SDimitry Andric break; 126*fe6060f1SDimitry Andric } 127*fe6060f1SDimitry Andric 128*fe6060f1SDimitry Andric // There are only 32bits in the VectExtParamInfo. 129*fe6060f1SDimitry Andric if (Bits >= 32) 130*fe6060f1SDimitry Andric break; 131*fe6060f1SDimitry Andric } 132*fe6060f1SDimitry Andric return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo; 133*fe6060f1SDimitry Andric } 134*fe6060f1SDimitry Andric 135*fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getParmsType() const { 136*fe6060f1SDimitry Andric uint32_t ParamsTypeInfo = 0; 137*fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 138*fe6060f1SDimitry Andric 139*fe6060f1SDimitry Andric int Bits = 0; 140*fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) { 141*fe6060f1SDimitry Andric 142*fe6060f1SDimitry Andric if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms()))) 143*fe6060f1SDimitry Andric break; 144*fe6060f1SDimitry Andric 145*fe6060f1SDimitry Andric switch (Elt) { 146*fe6060f1SDimitry Andric case FixedType: 147*fe6060f1SDimitry Andric if (hasVectorParms()) { 148*fe6060f1SDimitry Andric //'00' ==> fixed parameter if HasVectorParms is true. 149*fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 150*fe6060f1SDimitry Andric ParamsTypeInfo |= 151*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits; 152*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 153e8d8bef9SDimitry Andric } else { 154*fe6060f1SDimitry Andric //'0' ==> fixed parameter if HasVectorParms is false. 155*fe6060f1SDimitry Andric ParamsTypeInfo <<= 1; 156e8d8bef9SDimitry Andric ++Bits; 157e8d8bef9SDimitry Andric } 158*fe6060f1SDimitry Andric break; 159*fe6060f1SDimitry Andric case ShortFloatingPoint: 160*fe6060f1SDimitry Andric // '10'b => floating point short parameter. 161*fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 162*fe6060f1SDimitry Andric ParamsTypeInfo |= 163*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits; 164*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 165*fe6060f1SDimitry Andric break; 166*fe6060f1SDimitry Andric case LongFloatingPoint: 167*fe6060f1SDimitry Andric // '11'b => floating point long parameter. 168*fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 169*fe6060f1SDimitry Andric ParamsTypeInfo |= 170*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits; 171*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 172*fe6060f1SDimitry Andric break; 173*fe6060f1SDimitry Andric case VectorChar: 174*fe6060f1SDimitry Andric case VectorShort: 175*fe6060f1SDimitry Andric case VectorInt: 176*fe6060f1SDimitry Andric case VectorFloat: 177*fe6060f1SDimitry Andric // '01' ==> vector parameter 178*fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 179*fe6060f1SDimitry Andric ParamsTypeInfo |= 180*fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits; 181*fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 182*fe6060f1SDimitry Andric break; 183*fe6060f1SDimitry Andric } 184e8d8bef9SDimitry Andric } 185e8d8bef9SDimitry Andric 186*fe6060f1SDimitry Andric return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo; 187e8d8bef9SDimitry Andric } 188