[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / utils / TableGen / CallingConvEmitter.cpp
blob127ae6247bd9c2f0924405c17f43a94c7030b653
1 //===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
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 // This tablegen backend is responsible for emitting descriptions of the calling
10 // conventions supported by this target.
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenTarget.h"
15 #include "llvm/TableGen/Error.h"
16 #include "llvm/TableGen/Record.h"
17 #include "llvm/TableGen/TableGenBackend.h"
18 #include <cassert>
19 using namespace llvm;
21 namespace {
22 class CallingConvEmitter {
23 RecordKeeper &Records;
24 public:
25 explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}
27 void run(raw_ostream &o);
29 private:
30 void EmitCallingConv(Record *CC, raw_ostream &O);
31 void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
32 unsigned Counter;
34 } // End anonymous namespace
36 void CallingConvEmitter::run(raw_ostream &O) {
37 std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");
39 // Emit prototypes for all of the non-custom CC's so that they can forward ref
40 // each other.
41 Records.startTimer("Emit prototypes");
42 for (Record *CC : CCs) {
43 if (!CC->getValueAsBit("Custom")) {
44 unsigned Pad = CC->getName().size();
45 if (CC->getValueAsBit("Entry")) {
46 O << "bool llvm::";
47 Pad += 12;
48 } else {
49 O << "static bool ";
50 Pad += 13;
52 O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n"
53 << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
54 << std::string(Pad, ' ')
55 << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
59 // Emit each non-custom calling convention description in full.
60 Records.startTimer("Emit full descriptions");
61 for (Record *CC : CCs) {
62 if (!CC->getValueAsBit("Custom"))
63 EmitCallingConv(CC, O);
68 void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
69 ListInit *CCActions = CC->getValueAsListInit("Actions");
70 Counter = 0;
72 O << "\n\n";
73 unsigned Pad = CC->getName().size();
74 if (CC->getValueAsBit("Entry")) {
75 O << "bool llvm::";
76 Pad += 12;
77 } else {
78 O << "static bool ";
79 Pad += 13;
81 O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n"
82 << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
83 << std::string(Pad, ' ') << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
84 // Emit all of the actions, in order.
85 for (unsigned i = 0, e = CCActions->size(); i != e; ++i) {
86 O << "\n";
87 EmitAction(CCActions->getElementAsRecord(i), 2, O);
90 O << "\n return true; // CC didn't match.\n";
91 O << "}\n";
94 void CallingConvEmitter::EmitAction(Record *Action,
95 unsigned Indent, raw_ostream &O) {
96 std::string IndentStr = std::string(Indent, ' ');
98 if (Action->isSubClassOf("CCPredicateAction")) {
99 O << IndentStr << "if (";
101 if (Action->isSubClassOf("CCIfType")) {
102 ListInit *VTs = Action->getValueAsListInit("VTs");
103 for (unsigned i = 0, e = VTs->size(); i != e; ++i) {
104 Record *VT = VTs->getElementAsRecord(i);
105 if (i != 0) O << " ||\n " << IndentStr;
106 O << "LocVT == " << getEnumName(getValueType(VT));
109 } else if (Action->isSubClassOf("CCIf")) {
110 O << Action->getValueAsString("Predicate");
111 } else {
112 errs() << *Action;
113 PrintFatalError(Action->getLoc(), "Unknown CCPredicateAction!");
116 O << ") {\n";
117 EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
118 O << IndentStr << "}\n";
119 } else {
120 if (Action->isSubClassOf("CCDelegateTo")) {
121 Record *CC = Action->getValueAsDef("CC");
122 O << IndentStr << "if (!" << CC->getName()
123 << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
124 << IndentStr << " return false;\n";
125 } else if (Action->isSubClassOf("CCAssignToReg")) {
126 ListInit *RegList = Action->getValueAsListInit("RegList");
127 if (RegList->size() == 1) {
128 O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
129 O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
130 } else {
131 O << IndentStr << "static const MCPhysReg RegList" << ++Counter
132 << "[] = {\n";
133 O << IndentStr << " ";
134 ListSeparator LS;
135 for (unsigned i = 0, e = RegList->size(); i != e; ++i)
136 O << LS << getQualifiedName(RegList->getElementAsRecord(i));
137 O << "\n" << IndentStr << "};\n";
138 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
139 << Counter << ")) {\n";
141 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
142 << "Reg, LocVT, LocInfo));\n";
143 O << IndentStr << " return false;\n";
144 O << IndentStr << "}\n";
145 } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
146 ListInit *RegList = Action->getValueAsListInit("RegList");
147 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
148 if (!ShadowRegList->empty() && ShadowRegList->size() != RegList->size())
149 PrintFatalError(Action->getLoc(),
150 "Invalid length of list of shadowed registers");
152 if (RegList->size() == 1) {
153 O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
154 O << getQualifiedName(RegList->getElementAsRecord(0));
155 O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
156 O << ")) {\n";
157 } else {
158 unsigned RegListNumber = ++Counter;
159 unsigned ShadowRegListNumber = ++Counter;
161 O << IndentStr << "static const MCPhysReg RegList" << RegListNumber
162 << "[] = {\n";
163 O << IndentStr << " ";
164 ListSeparator LS;
165 for (unsigned i = 0, e = RegList->size(); i != e; ++i)
166 O << LS << getQualifiedName(RegList->getElementAsRecord(i));
167 O << "\n" << IndentStr << "};\n";
169 O << IndentStr << "static const MCPhysReg RegList"
170 << ShadowRegListNumber << "[] = {\n";
171 O << IndentStr << " ";
172 ListSeparator LSS;
173 for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
174 O << LSS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
175 O << "\n" << IndentStr << "};\n";
177 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
178 << RegListNumber << ", " << "RegList" << ShadowRegListNumber
179 << ")) {\n";
181 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
182 << "Reg, LocVT, LocInfo));\n";
183 O << IndentStr << " return false;\n";
184 O << IndentStr << "}\n";
185 } else if (Action->isSubClassOf("CCAssignToStack")) {
186 int Size = Action->getValueAsInt("Size");
187 int Align = Action->getValueAsInt("Align");
189 O << IndentStr << "unsigned Offset" << ++Counter
190 << " = State.AllocateStack(";
191 if (Size)
192 O << Size << ", ";
193 else
194 O << "\n" << IndentStr
195 << " State.getMachineFunction().getDataLayout()."
196 "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
197 " ";
198 if (Align)
199 O << "Align(" << Align << ")";
200 else
201 O << "\n"
202 << IndentStr
203 << " State.getMachineFunction().getDataLayout()."
204 "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
205 "))";
206 O << ");\n" << IndentStr
207 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
208 << Counter << ", LocVT, LocInfo));\n";
209 O << IndentStr << "return false;\n";
210 } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
211 int Size = Action->getValueAsInt("Size");
212 int Align = Action->getValueAsInt("Align");
213 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
215 unsigned ShadowRegListNumber = ++Counter;
217 O << IndentStr << "static const MCPhysReg ShadowRegList"
218 << ShadowRegListNumber << "[] = {\n";
219 O << IndentStr << " ";
220 ListSeparator LS;
221 for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
222 O << LS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
223 O << "\n" << IndentStr << "};\n";
225 O << IndentStr << "unsigned Offset" << ++Counter
226 << " = State.AllocateStack(" << Size << ", Align(" << Align << "), "
227 << "ShadowRegList" << ShadowRegListNumber << ");\n";
228 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
229 << Counter << ", LocVT, LocInfo));\n";
230 O << IndentStr << "return false;\n";
231 } else if (Action->isSubClassOf("CCPromoteToType")) {
232 Record *DestTy = Action->getValueAsDef("DestTy");
233 MVT::SimpleValueType DestVT = getValueType(DestTy);
234 O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
235 if (MVT(DestVT).isFloatingPoint()) {
236 O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
237 } else {
238 O << IndentStr << "if (ArgFlags.isSExt())\n"
239 << IndentStr << " LocInfo = CCValAssign::SExt;\n"
240 << IndentStr << "else if (ArgFlags.isZExt())\n"
241 << IndentStr << " LocInfo = CCValAssign::ZExt;\n"
242 << IndentStr << "else\n"
243 << IndentStr << " LocInfo = CCValAssign::AExt;\n";
245 } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) {
246 Record *DestTy = Action->getValueAsDef("DestTy");
247 MVT::SimpleValueType DestVT = getValueType(DestTy);
248 O << IndentStr << "LocVT = " << getEnumName(DestVT) << ";\n";
249 if (MVT(DestVT).isFloatingPoint()) {
250 PrintFatalError(Action->getLoc(),
251 "CCPromoteToUpperBitsInType does not handle floating "
252 "point");
253 } else {
254 O << IndentStr << "if (ArgFlags.isSExt())\n"
255 << IndentStr << " LocInfo = CCValAssign::SExtUpper;\n"
256 << IndentStr << "else if (ArgFlags.isZExt())\n"
257 << IndentStr << " LocInfo = CCValAssign::ZExtUpper;\n"
258 << IndentStr << "else\n"
259 << IndentStr << " LocInfo = CCValAssign::AExtUpper;\n";
261 } else if (Action->isSubClassOf("CCBitConvertToType")) {
262 Record *DestTy = Action->getValueAsDef("DestTy");
263 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
264 O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
265 } else if (Action->isSubClassOf("CCTruncToType")) {
266 Record *DestTy = Action->getValueAsDef("DestTy");
267 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
268 O << IndentStr << "LocInfo = CCValAssign::Trunc;\n";
269 } else if (Action->isSubClassOf("CCPassIndirect")) {
270 Record *DestTy = Action->getValueAsDef("DestTy");
271 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
272 O << IndentStr << "LocInfo = CCValAssign::Indirect;\n";
273 } else if (Action->isSubClassOf("CCPassByVal")) {
274 int Size = Action->getValueAsInt("Size");
275 int Align = Action->getValueAsInt("Align");
276 O << IndentStr << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
277 << Size << ", Align(" << Align << "), ArgFlags);\n";
278 O << IndentStr << "return false;\n";
279 } else if (Action->isSubClassOf("CCCustom")) {
280 O << IndentStr
281 << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
282 << "LocVT, LocInfo, ArgFlags, State))\n";
283 O << IndentStr << " return false;\n";
284 } else {
285 errs() << *Action;
286 PrintFatalError(Action->getLoc(), "Unknown CCAction!");
291 namespace llvm {
293 void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) {
294 emitSourceFileHeader("Calling Convention Implementation Fragment", OS);
295 CallingConvEmitter(RK).run(OS);
298 } // End llvm namespace