xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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