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