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" 11af732203SDimitry 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 anchor()220b57cec5SDimitry Andricvoid PPCFunctionInfo::anchor() {} PPCFunctionInfo(const MachineFunction & MF)235ffd83dbSDimitry AndricPPCFunctionInfo::PPCFunctionInfo(const MachineFunction &MF) 245ffd83dbSDimitry Andric : DisableNonVolatileCR(PPCDisableNonVolatileCR) {} 250b57cec5SDimitry Andric getPICOffsetSymbol(MachineFunction & MF) const265ffd83dbSDimitry AndricMCSymbol *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 getGlobalEPSymbol(MachineFunction & MF) const335ffd83dbSDimitry AndricMCSymbol *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 getLocalEPSymbol(MachineFunction & MF) const405ffd83dbSDimitry AndricMCSymbol *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 getTOCOffsetSymbol(MachineFunction & MF) const475ffd83dbSDimitry AndricMCSymbol *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 isLiveInSExt(Register VReg) const545ffd83dbSDimitry Andricbool 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 isLiveInZExt(Register VReg) const615ffd83dbSDimitry Andricbool 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 } 67af732203SDimitry Andric appendParameterType(ParamType Type)68af732203SDimitry Andricvoid PPCFunctionInfo::appendParameterType(ParamType Type) { 69af732203SDimitry Andric 70*5f7ddb14SDimitry Andric ParamtersType.push_back(Type); 71*5f7ddb14SDimitry Andric switch (Type) { 72*5f7ddb14SDimitry Andric case FixedType: 73*5f7ddb14SDimitry Andric ++FixedParmsNum; 74*5f7ddb14SDimitry Andric return; 75*5f7ddb14SDimitry Andric case ShortFloatingPoint: 76*5f7ddb14SDimitry Andric case LongFloatingPoint: 77*5f7ddb14SDimitry Andric ++FloatingParmsNum; 78*5f7ddb14SDimitry Andric return; 79*5f7ddb14SDimitry Andric case VectorChar: 80*5f7ddb14SDimitry Andric case VectorShort: 81*5f7ddb14SDimitry Andric case VectorInt: 82*5f7ddb14SDimitry Andric case VectorFloat: 83*5f7ddb14SDimitry Andric ++VectorParmsNum; 84af732203SDimitry Andric return; 85af732203SDimitry Andric } 86*5f7ddb14SDimitry Andric llvm_unreachable("Error ParamType type."); 87*5f7ddb14SDimitry Andric } 88af732203SDimitry Andric getVecExtParmsType() const89*5f7ddb14SDimitry Andricuint32_t PPCFunctionInfo::getVecExtParmsType() const { 90af732203SDimitry Andric 91*5f7ddb14SDimitry Andric uint32_t VectExtParamInfo = 0; 92*5f7ddb14SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 93*5f7ddb14SDimitry Andric int Bits = 0; 94*5f7ddb14SDimitry Andric 95*5f7ddb14SDimitry Andric if (!hasVectorParms()) 96*5f7ddb14SDimitry Andric return 0; 97*5f7ddb14SDimitry Andric 98*5f7ddb14SDimitry Andric for (const auto &Elt : ParamtersType) { 99*5f7ddb14SDimitry Andric switch (Elt) { 100*5f7ddb14SDimitry Andric case VectorChar: 101*5f7ddb14SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 102*5f7ddb14SDimitry Andric VectExtParamInfo |= 103*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits; 104*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 105*5f7ddb14SDimitry Andric break; 106*5f7ddb14SDimitry Andric case VectorShort: 107*5f7ddb14SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 108*5f7ddb14SDimitry Andric VectExtParamInfo |= 109*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits; 110*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 111*5f7ddb14SDimitry Andric break; 112*5f7ddb14SDimitry Andric case VectorInt: 113*5f7ddb14SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 114*5f7ddb14SDimitry Andric VectExtParamInfo |= 115*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits; 116*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 117*5f7ddb14SDimitry Andric break; 118*5f7ddb14SDimitry Andric case VectorFloat: 119*5f7ddb14SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType; 120*5f7ddb14SDimitry Andric VectExtParamInfo |= 121*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits; 122*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 123*5f7ddb14SDimitry Andric break; 124*5f7ddb14SDimitry Andric default: 125*5f7ddb14SDimitry Andric break; 126*5f7ddb14SDimitry Andric } 127*5f7ddb14SDimitry Andric 128*5f7ddb14SDimitry Andric // There are only 32bits in the VectExtParamInfo. 129*5f7ddb14SDimitry Andric if (Bits >= 32) 130*5f7ddb14SDimitry Andric break; 131*5f7ddb14SDimitry Andric } 132*5f7ddb14SDimitry Andric return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo; 133*5f7ddb14SDimitry Andric } 134*5f7ddb14SDimitry Andric getParmsType() const135*5f7ddb14SDimitry Andricuint32_t PPCFunctionInfo::getParmsType() const { 136*5f7ddb14SDimitry Andric uint32_t ParamsTypeInfo = 0; 137*5f7ddb14SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType; 138*5f7ddb14SDimitry Andric 139*5f7ddb14SDimitry Andric int Bits = 0; 140*5f7ddb14SDimitry Andric for (const auto &Elt : ParamtersType) { 141*5f7ddb14SDimitry Andric 142*5f7ddb14SDimitry Andric if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms()))) 143*5f7ddb14SDimitry Andric break; 144*5f7ddb14SDimitry Andric 145*5f7ddb14SDimitry Andric switch (Elt) { 146*5f7ddb14SDimitry Andric case FixedType: 147*5f7ddb14SDimitry Andric if (hasVectorParms()) { 148*5f7ddb14SDimitry Andric //'00' ==> fixed parameter if HasVectorParms is true. 149*5f7ddb14SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 150*5f7ddb14SDimitry Andric ParamsTypeInfo |= 151*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits; 152*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 153af732203SDimitry Andric } else { 154*5f7ddb14SDimitry Andric //'0' ==> fixed parameter if HasVectorParms is false. 155*5f7ddb14SDimitry Andric ParamsTypeInfo <<= 1; 156af732203SDimitry Andric ++Bits; 157af732203SDimitry Andric } 158*5f7ddb14SDimitry Andric break; 159*5f7ddb14SDimitry Andric case ShortFloatingPoint: 160*5f7ddb14SDimitry Andric // '10'b => floating point short parameter. 161*5f7ddb14SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 162*5f7ddb14SDimitry Andric ParamsTypeInfo |= 163*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits; 164*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 165*5f7ddb14SDimitry Andric break; 166*5f7ddb14SDimitry Andric case LongFloatingPoint: 167*5f7ddb14SDimitry Andric // '11'b => floating point long parameter. 168*5f7ddb14SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 169*5f7ddb14SDimitry Andric ParamsTypeInfo |= 170*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits; 171*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 172*5f7ddb14SDimitry Andric break; 173*5f7ddb14SDimitry Andric case VectorChar: 174*5f7ddb14SDimitry Andric case VectorShort: 175*5f7ddb14SDimitry Andric case VectorInt: 176*5f7ddb14SDimitry Andric case VectorFloat: 177*5f7ddb14SDimitry Andric // '01' ==> vector parameter 178*5f7ddb14SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType; 179*5f7ddb14SDimitry Andric ParamsTypeInfo |= 180*5f7ddb14SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits; 181*5f7ddb14SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType; 182*5f7ddb14SDimitry Andric break; 183*5f7ddb14SDimitry Andric } 184af732203SDimitry Andric } 185af732203SDimitry Andric 186*5f7ddb14SDimitry Andric return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo; 187af732203SDimitry Andric } 188