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