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