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 Andric void PPCFunctionInfo::anchor() {}
PPCFunctionInfo(const MachineFunction & MF)235ffd83dbSDimitry Andric PPCFunctionInfo::PPCFunctionInfo(const MachineFunction &MF)
245ffd83dbSDimitry Andric     : DisableNonVolatileCR(PPCDisableNonVolatileCR) {}
250b57cec5SDimitry Andric 
getPICOffsetSymbol(MachineFunction & MF) const265ffd83dbSDimitry 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 
getGlobalEPSymbol(MachineFunction & MF) const335ffd83dbSDimitry 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 
getLocalEPSymbol(MachineFunction & MF) const405ffd83dbSDimitry 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 
getTOCOffsetSymbol(MachineFunction & MF) const475ffd83dbSDimitry 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 
isLiveInSExt(Register VReg) const545ffd83dbSDimitry 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 
isLiveInZExt(Register VReg) const615ffd83dbSDimitry 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 }
67af732203SDimitry Andric 
appendParameterType(ParamType Type)68af732203SDimitry Andric void 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 Andric uint32_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 Andric uint32_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