1 //===-- PPCMachineFunctionInfo.cpp - Private data used for PowerPC --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PPCMachineFunctionInfo.h"
10 #include "llvm/ADT/Twine.h"
11 #include "llvm/BinaryFormat/XCOFF.h"
12 #include "llvm/IR/DataLayout.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/Support/CommandLine.h"
15 
16 using namespace llvm;
17 static cl::opt<bool> PPCDisableNonVolatileCR(
18     "ppc-disable-non-volatile-cr",
19     cl::desc("Disable the use of non-volatile CR register fields"),
20     cl::init(false), cl::Hidden);
21 
22 void PPCFunctionInfo::anchor() {}
23 PPCFunctionInfo::PPCFunctionInfo(const MachineFunction &MF)
24     : DisableNonVolatileCR(PPCDisableNonVolatileCR) {}
25 
26 MachineFunctionInfo *
27 PPCFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
28                        const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
29                            &Src2DstMBB) const {
30   return DestMF.cloneInfo<PPCFunctionInfo>(*this);
31 }
32 
33 MCSymbol *PPCFunctionInfo::getPICOffsetSymbol(MachineFunction &MF) const {
34   const DataLayout &DL = MF.getDataLayout();
35   return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
36                                            Twine(MF.getFunctionNumber()) +
37                                            "$poff");
38 }
39 
40 MCSymbol *PPCFunctionInfo::getGlobalEPSymbol(MachineFunction &MF) const {
41   const DataLayout &DL = MF.getDataLayout();
42   return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
43                                            "func_gep" +
44                                            Twine(MF.getFunctionNumber()));
45 }
46 
47 MCSymbol *PPCFunctionInfo::getLocalEPSymbol(MachineFunction &MF) const {
48   const DataLayout &DL = MF.getDataLayout();
49   return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
50                                            "func_lep" +
51                                            Twine(MF.getFunctionNumber()));
52 }
53 
54 MCSymbol *PPCFunctionInfo::getTOCOffsetSymbol(MachineFunction &MF) const {
55   const DataLayout &DL = MF.getDataLayout();
56   return MF.getContext().getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
57                                            "func_toc" +
58                                            Twine(MF.getFunctionNumber()));
59 }
60 
61 bool PPCFunctionInfo::isLiveInSExt(Register VReg) const {
62   for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs)
63     if (LiveIn.first == VReg)
64       return LiveIn.second.isSExt();
65   return false;
66 }
67 
68 bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
69   for (const std::pair<Register, ISD::ArgFlagsTy> &LiveIn : LiveInAttrs)
70     if (LiveIn.first == VReg)
71       return LiveIn.second.isZExt();
72   return false;
73 }
74 
75 void PPCFunctionInfo::appendParameterType(ParamType Type) {
76 
77   ParamtersType.push_back(Type);
78   switch (Type) {
79   case FixedType:
80     ++FixedParmsNum;
81     return;
82   case ShortFloatingPoint:
83   case LongFloatingPoint:
84     ++FloatingParmsNum;
85     return;
86   case VectorChar:
87   case VectorShort:
88   case VectorInt:
89   case VectorFloat:
90     ++VectorParmsNum;
91     return;
92   }
93   llvm_unreachable("Error ParamType type.");
94 }
95 
96 uint32_t PPCFunctionInfo::getVecExtParmsType() const {
97 
98   uint32_t VectExtParamInfo = 0;
99   unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
100   int Bits = 0;
101 
102   if (!hasVectorParms())
103     return 0;
104 
105   for (const auto &Elt : ParamtersType) {
106     switch (Elt) {
107     case VectorChar:
108       VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
109       VectExtParamInfo |=
110           XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits;
111       Bits += XCOFF::TracebackTable::WidthOfParamType;
112       break;
113     case VectorShort:
114       VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
115       VectExtParamInfo |=
116           XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits;
117       Bits += XCOFF::TracebackTable::WidthOfParamType;
118       break;
119     case VectorInt:
120       VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
121       VectExtParamInfo |=
122           XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits;
123       Bits += XCOFF::TracebackTable::WidthOfParamType;
124       break;
125     case VectorFloat:
126       VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
127       VectExtParamInfo |=
128           XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits;
129       Bits += XCOFF::TracebackTable::WidthOfParamType;
130       break;
131     default:
132       break;
133     }
134 
135     // There are only 32bits in the VectExtParamInfo.
136     if (Bits >= 32)
137       break;
138   }
139   return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo;
140 }
141 
142 uint32_t PPCFunctionInfo::getParmsType() const {
143   uint32_t ParamsTypeInfo = 0;
144   unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
145 
146   int Bits = 0;
147   for (const auto &Elt : ParamtersType) {
148 
149     if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms())))
150       break;
151 
152     switch (Elt) {
153     case FixedType:
154       if (hasVectorParms()) {
155         //'00'  ==> fixed parameter if HasVectorParms is true.
156         ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
157         ParamsTypeInfo |=
158             XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits;
159         Bits += XCOFF::TracebackTable::WidthOfParamType;
160       } else {
161         //'0'  ==> fixed parameter if HasVectorParms is false.
162         ParamsTypeInfo <<= 1;
163         ++Bits;
164       }
165       break;
166     case ShortFloatingPoint:
167       // '10'b => floating point short parameter.
168       ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
169       ParamsTypeInfo |=
170           XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits;
171       Bits += XCOFF::TracebackTable::WidthOfParamType;
172       break;
173     case LongFloatingPoint:
174       // '11'b => floating point long parameter.
175       ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
176       ParamsTypeInfo |=
177           XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits;
178       Bits += XCOFF::TracebackTable::WidthOfParamType;
179       break;
180     case VectorChar:
181     case VectorShort:
182     case VectorInt:
183     case VectorFloat:
184       //	'01' ==> vector parameter
185       ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
186       ParamsTypeInfo |=
187           XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits;
188       Bits += XCOFF::TracebackTable::WidthOfParamType;
189       break;
190     }
191   }
192 
193   return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo;
194 }
195