llvm.org GIT mirror llvm / 88ee2a1
*** empty log message *** git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34696 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 13 years ago
2 changed file(s) with 166 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Chris Lattner and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tablegen backend is responsible for emitting descriptions of the calling
10 // conventions supported by this target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CallingConvEmitter.h"
15 #include "Record.h"
16 #include "CodeGenTarget.h"
17 using namespace llvm;
18
19 void CallingConvEmitter::run(std::ostream &O) {
20 EmitSourceFileHeader("Calling Convention Implementation Fragment", O);
21
22 std::vector CCs = Records.getAllDerivedDefinitions("CallingConv");
23
24 // Emit prototypes for all of the CC's so that they can forward ref each
25 // other.
26 for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
27 O << "static bool " << CCs[i]->getName()
28 << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n"
29 << std::string(CCs[i]->getName().size()+13, ' ')
30 << "CCValAssign::LocInfo LocInfo, unsigned ArgFlags, CCState &State);\n";
31 }
32
33 // Emit each calling convention description in full.
34 for (unsigned i = 0, e = CCs.size(); i != e; ++i)
35 EmitCallingConv(CCs[i], O);
36 }
37
38
39 void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) {
40 ListInit *CCActions = CC->getValueAsListInit("Actions");
41 Counter = 0;
42
43 O << "\n\nstatic bool " << CC->getName()
44 << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n"
45 << std::string(CC->getName().size()+13, ' ')
46 << "CCValAssign::LocInfo LocInfo, "
47 << "unsigned ArgFlags, CCState &State) {\n";
48
49 // Emit all of the actions, in order.
50 for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
51 O << "\n";
52 EmitAction(CCActions->getElementAsRecord(i), 2, O);
53 }
54
55 O << "\n return true; // CC didn't match.\n";
56 O << "}\n";
57 }
58
59 void CallingConvEmitter::EmitAction(Record *Action,
60 unsigned Indent, std::ostream &O) {
61 std::string IndentStr = std::string(Indent, ' ');
62
63 if (Action->isSubClassOf("CCPredicateAction")) {
64 O << IndentStr << "if (";
65
66 if (Action->isSubClassOf("CCMatchType")) {
67 ListInit *VTs = Action->getValueAsListInit("VTs");
68 for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
69 Record *VT = VTs->getElementAsRecord(i);
70 if (i != 0) O << " || \n " << IndentStr;
71 O << "LocVT == " << getEnumName(getValueType(VT));
72 }
73
74 } else if (Action->isSubClassOf("CCMatchIf")) {
75 O << Action->getValueAsString("Predicate");
76 } else {
77 Action->dump();
78 throw "Unknown CCPredicateAction!";
79 }
80
81 O << ") {\n";
82 EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
83 O << IndentStr << "}\n";
84 } else {
85 if (Action->isSubClassOf("CCDelegateTo")) {
86 Record *CC = Action->getValueAsDef("CC");
87 O << IndentStr << "if (!" << CC->getName()
88 << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
89 << IndentStr << " return false;\n";
90 } else if (Action->isSubClassOf("CCAssignToReg")) {
91 ListInit *RegList = Action->getValueAsListInit("RegList");
92 if (RegList->getSize() == 1) {
93 O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
94 O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
95 } else {
96 O << IndentStr << "static const unsigned RegList" << ++Counter
97 << "[] = {\n";
98 O << IndentStr << " ";
99 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
100 if (i != 0) O << ", ";
101 O << getQualifiedName(RegList->getElementAsRecord(i));
102 }
103 O << "\n" << IndentStr << "};\n";
104 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
105 << Counter << ", " << RegList->getSize() << ")) {\n";
106 }
107 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
108 << "Reg, LocVT, LocInfo));\n";
109 O << IndentStr << " return false;\n";
110 O << IndentStr << "}\n";
111 } else if (Action->isSubClassOf("CCAssignToStack")) {
112 int Size = Action->getValueAsInt("Size");
113 int Align = Action->getValueAsInt("Align");
114
115 O << IndentStr << "unsigned Offset" << ++Counter
116 << " = State.AllocateStack(" << Size << ", " << Align << ");\n";
117 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ArgVT, Offset"
118 << Counter << ", LocVT, LocInfo));\n";
119 O << IndentStr << "return false;\n";
120 } else if (Action->isSubClassOf("CCPromoteToType")) {
121
122 } else {
123 Action->dump();
124 throw "Unknown CCAction!";
125 }
126 }
127 }
0 //===- CallingConvEmitter.h - Generate calling conventions ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Chris Lattner and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This tablegen backend is responsible for emitting descriptions of the calling
10 // conventions supported by this target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef CALLINGCONV_EMITTER_H
15 #define CALLINGCONV_EMITTER_H
16
17 #include "TableGenBackend.h"
18 #include
19 #include
20 #include
21
22 namespace llvm {
23 class CallingConvEmitter : public TableGenBackend {
24 RecordKeeper &Records;
25 public:
26 CallingConvEmitter(RecordKeeper &R) : Records(R) {}
27
28 // run - Output the asmwriter, returning true on failure.
29 void run(std::ostream &o);
30
31 private:
32 void EmitCallingConv(Record *CC, std::ostream &O);
33 void EmitAction(Record *Action, unsigned Indent, std::ostream &O);
34 unsigned Counter;
35 };
36 }
37 #endif