1//===- CallingConvEmitter.cpp - Generate calling conventions --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// 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 "CodeGenTarget.h" 16#include "llvm/TableGen/Error.h" 17#include "llvm/TableGen/Record.h" 18#include "llvm/TableGen/TableGenBackend.h" 19#include <cassert> 20using namespace llvm; 21 22namespace { 23class CallingConvEmitter { 24 RecordKeeper &Records; 25public: 26 explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {} 27 28 void run(raw_ostream &o); 29 30private: 31 void EmitCallingConv(Record *CC, raw_ostream &O); 32 void EmitAction(Record *Action, unsigned Indent, raw_ostream &O); 33 unsigned Counter; 34}; 35} // End anonymous namespace 36 37void CallingConvEmitter::run(raw_ostream &O) { 38 39 std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv"); 40 41 // Emit prototypes for all of the CC's so that they can forward ref each 42 // other. 43 for (unsigned i = 0, e = CCs.size(); i != e; ++i) { 44 O << "static bool " << CCs[i]->getName() 45 << "(unsigned ValNo, MVT ValVT,\n" 46 << std::string(CCs[i]->getName().size()+13, ' ') 47 << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 48 << std::string(CCs[i]->getName().size()+13, ' ') 49 << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n"; 50 } 51 52 // Emit each calling convention description in full. 53 for (unsigned i = 0, e = CCs.size(); i != e; ++i) 54 EmitCallingConv(CCs[i], O); 55} 56 57 58void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) { 59 ListInit *CCActions = CC->getValueAsListInit("Actions"); 60 Counter = 0; 61 62 O << "\n\nstatic bool " << CC->getName() 63 << "(unsigned ValNo, MVT ValVT,\n" 64 << std::string(CC->getName().size()+13, ' ') 65 << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 66 << std::string(CC->getName().size()+13, ' ') 67 << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n"; 68 // Emit all of the actions, in order. 69 for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { 70 O << "\n"; 71 EmitAction(CCActions->getElementAsRecord(i), 2, O); 72 } 73 74 O << "\n return true; // CC didn't match.\n"; 75 O << "}\n"; 76} 77 78void CallingConvEmitter::EmitAction(Record *Action, 79 unsigned Indent, raw_ostream &O) { 80 std::string IndentStr = std::string(Indent, ' '); 81 82 if (Action->isSubClassOf("CCPredicateAction")) { 83 O << IndentStr << "if ("; 84 85 if (Action->isSubClassOf("CCIfType")) { 86 ListInit *VTs = Action->getValueAsListInit("VTs"); 87 for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { 88 Record *VT = VTs->getElementAsRecord(i); 89 if (i != 0) O << " ||\n " << IndentStr; 90 O << "LocVT == " << getEnumName(getValueType(VT)); 91 } 92 93 } else if (Action->isSubClassOf("CCIf")) { 94 O << Action->getValueAsString("Predicate"); 95 } else { 96 Action->dump(); 97 PrintFatalError("Unknown CCPredicateAction!"); 98 } 99 100 O << ") {\n"; 101 EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); 102 O << IndentStr << "}\n"; 103 } else { 104 if (Action->isSubClassOf("CCDelegateTo")) { 105 Record *CC = Action->getValueAsDef("CC"); 106 O << IndentStr << "if (!" << CC->getName() 107 << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" 108 << IndentStr << " return false;\n"; 109 } else if (Action->isSubClassOf("CCAssignToReg")) { 110 ListInit *RegList = Action->getValueAsListInit("RegList"); 111 if (RegList->getSize() == 1) { 112 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 113 O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; 114 } else { 115 O << IndentStr << "static const uint16_t RegList" << ++Counter 116 << "[] = {\n"; 117 O << IndentStr << " "; 118 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 119 if (i != 0) O << ", "; 120 O << getQualifiedName(RegList->getElementAsRecord(i)); 121 } 122 O << "\n" << IndentStr << "};\n"; 123 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 124 << Counter << ", " << RegList->getSize() << ")) {\n"; 125 } 126 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 127 << "Reg, LocVT, LocInfo));\n"; 128 O << IndentStr << " return false;\n"; 129 O << IndentStr << "}\n"; 130 } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) { 131 ListInit *RegList = Action->getValueAsListInit("RegList"); 132 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); 133 if (ShadowRegList->getSize() >0 && 134 ShadowRegList->getSize() != RegList->getSize()) 135 PrintFatalError("Invalid length of list of shadowed registers"); 136 137 if (RegList->getSize() == 1) { 138 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 139 O << getQualifiedName(RegList->getElementAsRecord(0)); 140 O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0)); 141 O << ")) {\n"; 142 } else { 143 unsigned RegListNumber = ++Counter; 144 unsigned ShadowRegListNumber = ++Counter; 145 146 O << IndentStr << "static const uint16_t RegList" << RegListNumber 147 << "[] = {\n"; 148 O << IndentStr << " "; 149 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 150 if (i != 0) O << ", "; 151 O << getQualifiedName(RegList->getElementAsRecord(i)); 152 } 153 O << "\n" << IndentStr << "};\n"; 154 155 O << IndentStr << "static const uint16_t RegList" 156 << ShadowRegListNumber << "[] = {\n"; 157 O << IndentStr << " "; 158 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { 159 if (i != 0) O << ", "; 160 O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); 161 } 162 O << "\n" << IndentStr << "};\n"; 163 164 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 165 << RegListNumber << ", " << "RegList" << ShadowRegListNumber 166 << ", " << RegList->getSize() << ")) {\n"; 167 } 168 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 169 << "Reg, LocVT, LocInfo));\n"; 170 O << IndentStr << " return false;\n"; 171 O << IndentStr << "}\n"; 172 } else if (Action->isSubClassOf("CCAssignToStack")) { 173 int Size = Action->getValueAsInt("Size"); 174 int Align = Action->getValueAsInt("Align"); 175 176 O << IndentStr << "unsigned Offset" << ++Counter 177 << " = State.AllocateStack("; 178 if (Size) 179 O << Size << ", "; 180 else 181 O << "\n" << IndentStr << " State.getTarget().getDataLayout()" 182 "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), "; 183 if (Align) 184 O << Align; 185 else 186 O << "\n" << IndentStr << " State.getTarget().getDataLayout()" 187 "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))"; 188 if (Action->isSubClassOf("CCAssignToStackWithShadow")) 189 O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg")); 190 O << ");\n" << IndentStr 191 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 192 << Counter << ", LocVT, LocInfo));\n"; 193 O << IndentStr << "return false;\n"; 194 } else if (Action->isSubClassOf("CCPromoteToType")) { 195 Record *DestTy = Action->getValueAsDef("DestTy"); 196 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 197 O << IndentStr << "if (ArgFlags.isSExt())\n" 198 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 199 << IndentStr << "else if (ArgFlags.isZExt())\n" 200 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 201 << IndentStr << "else\n" 202 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 203 } else if (Action->isSubClassOf("CCBitConvertToType")) { 204 Record *DestTy = Action->getValueAsDef("DestTy"); 205 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 206 O << IndentStr << "LocInfo = CCValAssign::BCvt;\n"; 207 } else if (Action->isSubClassOf("CCPassIndirect")) { 208 Record *DestTy = Action->getValueAsDef("DestTy"); 209 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 210 O << IndentStr << "LocInfo = CCValAssign::Indirect;\n"; 211 } else if (Action->isSubClassOf("CCPassByVal")) { 212 int Size = Action->getValueAsInt("Size"); 213 int Align = Action->getValueAsInt("Align"); 214 O << IndentStr 215 << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " 216 << Size << ", " << Align << ", ArgFlags);\n"; 217 O << IndentStr << "return false;\n"; 218 } else if (Action->isSubClassOf("CCCustom")) { 219 O << IndentStr 220 << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, " 221 << "LocVT, LocInfo, ArgFlags, State))\n"; 222 O << IndentStr << IndentStr << "return false;\n"; 223 } else { 224 Action->dump(); 225 PrintFatalError("Unknown CCAction!"); 226 } 227 } 228} 229 230namespace llvm { 231 232void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) { 233 emitSourceFileHeader("Calling Convention Implementation Fragment", OS); 234 CallingConvEmitter(RK).run(OS); 235} 236 237} // End llvm namespace 238