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
anchor()220b57cec5SDimitry Andric void PPCFunctionInfo::anchor() {}
PPCFunctionInfo(const Function & F,const TargetSubtargetInfo * STI)23*bdd1243dSDimitry Andric PPCFunctionInfo::PPCFunctionInfo(const Function &F,
24*bdd1243dSDimitry Andric const TargetSubtargetInfo *STI)
255ffd83dbSDimitry Andric : DisableNonVolatileCR(PPCDisableNonVolatileCR) {}
260b57cec5SDimitry Andric
2781ad6265SDimitry Andric MachineFunctionInfo *
clone(BumpPtrAllocator & Allocator,MachineFunction & DestMF,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB) const2881ad6265SDimitry Andric PPCFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
2981ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
3081ad6265SDimitry Andric &Src2DstMBB) const {
3181ad6265SDimitry Andric return DestMF.cloneInfo<PPCFunctionInfo>(*this);
3281ad6265SDimitry Andric }
3381ad6265SDimitry Andric
getPICOffsetSymbol(MachineFunction & MF) const345ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getPICOffsetSymbol(MachineFunction &MF) const {
350b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
360b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
370b57cec5SDimitry Andric Twine(MF.getFunctionNumber()) +
380b57cec5SDimitry Andric "$poff");
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric
getGlobalEPSymbol(MachineFunction & MF) const415ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getGlobalEPSymbol(MachineFunction &MF) const {
420b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
430b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
440b57cec5SDimitry Andric "func_gep" +
450b57cec5SDimitry Andric Twine(MF.getFunctionNumber()));
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric
getLocalEPSymbol(MachineFunction & MF) const485ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getLocalEPSymbol(MachineFunction &MF) const {
490b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
500b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
510b57cec5SDimitry Andric "func_lep" +
520b57cec5SDimitry Andric Twine(MF.getFunctionNumber()));
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric
getTOCOffsetSymbol(MachineFunction & MF) const555ffd83dbSDimitry Andric MCSymbol *PPCFunctionInfo::getTOCOffsetSymbol(MachineFunction &MF) const {
560b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
570b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
580b57cec5SDimitry Andric "func_toc" +
590b57cec5SDimitry Andric Twine(MF.getFunctionNumber()));
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric
isLiveInSExt(Register VReg) const625ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInSExt(Register VReg) const {
635ffd83dbSDimitry Andric for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs)
640b57cec5SDimitry Andric if (LiveIn.first == VReg)
650b57cec5SDimitry Andric return LiveIn.second.isSExt();
660b57cec5SDimitry Andric return false;
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric
isLiveInZExt(Register VReg) const695ffd83dbSDimitry Andric bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
705ffd83dbSDimitry Andric for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs)
710b57cec5SDimitry Andric if (LiveIn.first == VReg)
720b57cec5SDimitry Andric return LiveIn.second.isZExt();
730b57cec5SDimitry Andric return false;
740b57cec5SDimitry Andric }
75e8d8bef9SDimitry Andric
appendParameterType(ParamType Type)76e8d8bef9SDimitry Andric void PPCFunctionInfo::appendParameterType(ParamType Type) {
77e8d8bef9SDimitry Andric
78fe6060f1SDimitry Andric ParamtersType.push_back(Type);
79fe6060f1SDimitry Andric switch (Type) {
80fe6060f1SDimitry Andric case FixedType:
81fe6060f1SDimitry Andric ++FixedParmsNum;
82fe6060f1SDimitry Andric return;
83fe6060f1SDimitry Andric case ShortFloatingPoint:
84fe6060f1SDimitry Andric case LongFloatingPoint:
85fe6060f1SDimitry Andric ++FloatingParmsNum;
86fe6060f1SDimitry Andric return;
87fe6060f1SDimitry Andric case VectorChar:
88fe6060f1SDimitry Andric case VectorShort:
89fe6060f1SDimitry Andric case VectorInt:
90fe6060f1SDimitry Andric case VectorFloat:
91fe6060f1SDimitry Andric ++VectorParmsNum;
92e8d8bef9SDimitry Andric return;
93e8d8bef9SDimitry Andric }
94fe6060f1SDimitry Andric llvm_unreachable("Error ParamType type.");
95fe6060f1SDimitry Andric }
96e8d8bef9SDimitry Andric
getVecExtParmsType() const97fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getVecExtParmsType() const {
98e8d8bef9SDimitry Andric
99fe6060f1SDimitry Andric uint32_t VectExtParamInfo = 0;
100fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
101fe6060f1SDimitry Andric int Bits = 0;
102fe6060f1SDimitry Andric
103fe6060f1SDimitry Andric if (!hasVectorParms())
104fe6060f1SDimitry Andric return 0;
105fe6060f1SDimitry Andric
106fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) {
107fe6060f1SDimitry Andric switch (Elt) {
108fe6060f1SDimitry Andric case VectorChar:
109fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
110fe6060f1SDimitry Andric VectExtParamInfo |=
111fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits;
112fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
113fe6060f1SDimitry Andric break;
114fe6060f1SDimitry Andric case VectorShort:
115fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
116fe6060f1SDimitry Andric VectExtParamInfo |=
117fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits;
118fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
119fe6060f1SDimitry Andric break;
120fe6060f1SDimitry Andric case VectorInt:
121fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
122fe6060f1SDimitry Andric VectExtParamInfo |=
123fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits;
124fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
125fe6060f1SDimitry Andric break;
126fe6060f1SDimitry Andric case VectorFloat:
127fe6060f1SDimitry Andric VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
128fe6060f1SDimitry Andric VectExtParamInfo |=
129fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits;
130fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
131fe6060f1SDimitry Andric break;
132fe6060f1SDimitry Andric default:
133fe6060f1SDimitry Andric break;
134fe6060f1SDimitry Andric }
135fe6060f1SDimitry Andric
136fe6060f1SDimitry Andric // There are only 32bits in the VectExtParamInfo.
137fe6060f1SDimitry Andric if (Bits >= 32)
138fe6060f1SDimitry Andric break;
139fe6060f1SDimitry Andric }
140fe6060f1SDimitry Andric return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo;
141fe6060f1SDimitry Andric }
142fe6060f1SDimitry Andric
getParmsType() const143fe6060f1SDimitry Andric uint32_t PPCFunctionInfo::getParmsType() const {
144fe6060f1SDimitry Andric uint32_t ParamsTypeInfo = 0;
145fe6060f1SDimitry Andric unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
146fe6060f1SDimitry Andric
147fe6060f1SDimitry Andric int Bits = 0;
148fe6060f1SDimitry Andric for (const auto &Elt : ParamtersType) {
149fe6060f1SDimitry Andric
150fe6060f1SDimitry Andric if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms())))
151fe6060f1SDimitry Andric break;
152fe6060f1SDimitry Andric
153fe6060f1SDimitry Andric switch (Elt) {
154fe6060f1SDimitry Andric case FixedType:
155fe6060f1SDimitry Andric if (hasVectorParms()) {
156fe6060f1SDimitry Andric //'00' ==> fixed parameter if HasVectorParms is true.
157fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
158fe6060f1SDimitry Andric ParamsTypeInfo |=
159fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits;
160fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
161e8d8bef9SDimitry Andric } else {
162fe6060f1SDimitry Andric //'0' ==> fixed parameter if HasVectorParms is false.
163fe6060f1SDimitry Andric ParamsTypeInfo <<= 1;
164e8d8bef9SDimitry Andric ++Bits;
165e8d8bef9SDimitry Andric }
166fe6060f1SDimitry Andric break;
167fe6060f1SDimitry Andric case ShortFloatingPoint:
168fe6060f1SDimitry Andric // '10'b => floating point short parameter.
169fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
170fe6060f1SDimitry Andric ParamsTypeInfo |=
171fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits;
172fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
173fe6060f1SDimitry Andric break;
174fe6060f1SDimitry Andric case LongFloatingPoint:
175fe6060f1SDimitry Andric // '11'b => floating point long parameter.
176fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
177fe6060f1SDimitry Andric ParamsTypeInfo |=
178fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits;
179fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
180fe6060f1SDimitry Andric break;
181fe6060f1SDimitry Andric case VectorChar:
182fe6060f1SDimitry Andric case VectorShort:
183fe6060f1SDimitry Andric case VectorInt:
184fe6060f1SDimitry Andric case VectorFloat:
185fe6060f1SDimitry Andric // '01' ==> vector parameter
186fe6060f1SDimitry Andric ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
187fe6060f1SDimitry Andric ParamsTypeInfo |=
188fe6060f1SDimitry Andric XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits;
189fe6060f1SDimitry Andric Bits += XCOFF::TracebackTable::WidthOfParamType;
190fe6060f1SDimitry Andric break;
191fe6060f1SDimitry Andric }
192e8d8bef9SDimitry Andric }
193e8d8bef9SDimitry Andric
194fe6060f1SDimitry Andric return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo;
195e8d8bef9SDimitry Andric }
196