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> 20 using namespace llvm; 21 22 namespace { 23 class CallingConvEmitter { 24 RecordKeeper &Records; 25 public: 26 explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {} 27 28 void run(raw_ostream &o); 29 30 private: 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 37 void CallingConvEmitter::run(raw_ostream &O) { 38 std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv"); 39 40 // Emit prototypes for all of the non-custom CC's so that they can forward ref 41 // each other. 42 for (unsigned i = 0, e = CCs.size(); i != e; ++i) { 43 if (!CCs[i]->getValueAsBit("Custom")) { 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 53 // Emit each non-custom calling convention description in full. 54 for (unsigned i = 0, e = CCs.size(); i != e; ++i) { 55 if (!CCs[i]->getValueAsBit("Custom")) 56 EmitCallingConv(CCs[i], O); 57 } 58 } 59 60 61 void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) { 62 ListInit *CCActions = CC->getValueAsListInit("Actions"); 63 Counter = 0; 64 65 O << "\n\nstatic bool " << CC->getName() 66 << "(unsigned ValNo, MVT ValVT,\n" 67 << std::string(CC->getName().size()+13, ' ') 68 << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 69 << std::string(CC->getName().size()+13, ' ') 70 << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n"; 71 // Emit all of the actions, in order. 72 for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { 73 O << "\n"; 74 EmitAction(CCActions->getElementAsRecord(i), 2, O); 75 } 76 77 O << "\n return true; // CC didn't match.\n"; 78 O << "}\n"; 79 } 80 81 void CallingConvEmitter::EmitAction(Record *Action, 82 unsigned Indent, raw_ostream &O) { 83 std::string IndentStr = std::string(Indent, ' '); 84 85 if (Action->isSubClassOf("CCPredicateAction")) { 86 O << IndentStr << "if ("; 87 88 if (Action->isSubClassOf("CCIfType")) { 89 ListInit *VTs = Action->getValueAsListInit("VTs"); 90 for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { 91 Record *VT = VTs->getElementAsRecord(i); 92 if (i != 0) O << " ||\n " << IndentStr; 93 O << "LocVT == " << getEnumName(getValueType(VT)); 94 } 95 96 } else if (Action->isSubClassOf("CCIf")) { 97 O << Action->getValueAsString("Predicate"); 98 } else { 99 Action->dump(); 100 PrintFatalError("Unknown CCPredicateAction!"); 101 } 102 103 O << ") {\n"; 104 EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); 105 O << IndentStr << "}\n"; 106 } else { 107 if (Action->isSubClassOf("CCDelegateTo")) { 108 Record *CC = Action->getValueAsDef("CC"); 109 O << IndentStr << "if (!" << CC->getName() 110 << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" 111 << IndentStr << " return false;\n"; 112 } else if (Action->isSubClassOf("CCAssignToReg")) { 113 ListInit *RegList = Action->getValueAsListInit("RegList"); 114 if (RegList->getSize() == 1) { 115 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 116 O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; 117 } else { 118 O << IndentStr << "static const MCPhysReg RegList" << ++Counter 119 << "[] = {\n"; 120 O << IndentStr << " "; 121 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 122 if (i != 0) O << ", "; 123 O << getQualifiedName(RegList->getElementAsRecord(i)); 124 } 125 O << "\n" << IndentStr << "};\n"; 126 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 127 << Counter << ")) {\n"; 128 } 129 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 130 << "Reg, LocVT, LocInfo));\n"; 131 O << IndentStr << " return false;\n"; 132 O << IndentStr << "}\n"; 133 } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) { 134 ListInit *RegList = Action->getValueAsListInit("RegList"); 135 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); 136 if (ShadowRegList->getSize() >0 && 137 ShadowRegList->getSize() != RegList->getSize()) 138 PrintFatalError("Invalid length of list of shadowed registers"); 139 140 if (RegList->getSize() == 1) { 141 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 142 O << getQualifiedName(RegList->getElementAsRecord(0)); 143 O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0)); 144 O << ")) {\n"; 145 } else { 146 unsigned RegListNumber = ++Counter; 147 unsigned ShadowRegListNumber = ++Counter; 148 149 O << IndentStr << "static const MCPhysReg RegList" << RegListNumber 150 << "[] = {\n"; 151 O << IndentStr << " "; 152 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 153 if (i != 0) O << ", "; 154 O << getQualifiedName(RegList->getElementAsRecord(i)); 155 } 156 O << "\n" << IndentStr << "};\n"; 157 158 O << IndentStr << "static const MCPhysReg RegList" 159 << ShadowRegListNumber << "[] = {\n"; 160 O << IndentStr << " "; 161 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { 162 if (i != 0) O << ", "; 163 O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); 164 } 165 O << "\n" << IndentStr << "};\n"; 166 167 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 168 << RegListNumber << ", " << "RegList" << ShadowRegListNumber 169 << ")) {\n"; 170 } 171 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 172 << "Reg, LocVT, LocInfo));\n"; 173 O << IndentStr << " return false;\n"; 174 O << IndentStr << "}\n"; 175 } else if (Action->isSubClassOf("CCAssignToStack")) { 176 int Size = Action->getValueAsInt("Size"); 177 int Align = Action->getValueAsInt("Align"); 178 179 O << IndentStr << "unsigned Offset" << ++Counter 180 << " = State.AllocateStack("; 181 if (Size) 182 O << Size << ", "; 183 else 184 O << "\n" << IndentStr 185 << " State.getMachineFunction().getTarget().getDataLayout()" 186 "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext()))," 187 " "; 188 if (Align) 189 O << Align; 190 else 191 O << "\n" << IndentStr 192 << " State.getMachineFunction().getTarget().getDataLayout()" 193 "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()" 194 "))"; 195 O << ");\n" << IndentStr 196 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 197 << Counter << ", LocVT, LocInfo));\n"; 198 O << IndentStr << "return false;\n"; 199 } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) { 200 int Size = Action->getValueAsInt("Size"); 201 int Align = Action->getValueAsInt("Align"); 202 ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); 203 204 unsigned ShadowRegListNumber = ++Counter; 205 206 O << IndentStr << "static const MCPhysReg ShadowRegList" 207 << ShadowRegListNumber << "[] = {\n"; 208 O << IndentStr << " "; 209 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { 210 if (i != 0) O << ", "; 211 O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); 212 } 213 O << "\n" << IndentStr << "};\n"; 214 215 O << IndentStr << "unsigned Offset" << ++Counter 216 << " = State.AllocateStack(" 217 << Size << ", " << Align << ", " 218 << "ShadowRegList" << ShadowRegListNumber << ");\n"; 219 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 220 << Counter << ", LocVT, LocInfo));\n"; 221 O << IndentStr << "return false;\n"; 222 } else if (Action->isSubClassOf("CCPromoteToType")) { 223 Record *DestTy = Action->getValueAsDef("DestTy"); 224 MVT::SimpleValueType DestVT = getValueType(DestTy); 225 O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n"; 226 if (MVT(DestVT).isFloatingPoint()) { 227 O << IndentStr << "LocInfo = CCValAssign::FPExt;\n"; 228 } else { 229 O << IndentStr << "if (ArgFlags.isSExt())\n" 230 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 231 << IndentStr << "else if (ArgFlags.isZExt())\n" 232 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 233 << IndentStr << "else\n" 234 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 235 } 236 } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) { 237 Record *DestTy = Action->getValueAsDef("DestTy"); 238 MVT::SimpleValueType DestVT = getValueType(DestTy); 239 O << IndentStr << "LocVT = " << getEnumName(DestVT) << ";\n"; 240 if (MVT(DestVT).isFloatingPoint()) { 241 PrintFatalError("CCPromoteToUpperBitsInType does not handle floating " 242 "point"); 243 } else { 244 O << IndentStr << "if (ArgFlags.isSExt())\n" 245 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExtUpper;\n" 246 << IndentStr << "else if (ArgFlags.isZExt())\n" 247 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExtUpper;\n" 248 << IndentStr << "else\n" 249 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExtUpper;\n"; 250 } 251 } else if (Action->isSubClassOf("CCBitConvertToType")) { 252 Record *DestTy = Action->getValueAsDef("DestTy"); 253 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 254 O << IndentStr << "LocInfo = CCValAssign::BCvt;\n"; 255 } else if (Action->isSubClassOf("CCPassIndirect")) { 256 Record *DestTy = Action->getValueAsDef("DestTy"); 257 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 258 O << IndentStr << "LocInfo = CCValAssign::Indirect;\n"; 259 } else if (Action->isSubClassOf("CCPassByVal")) { 260 int Size = Action->getValueAsInt("Size"); 261 int Align = Action->getValueAsInt("Align"); 262 O << IndentStr 263 << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " 264 << Size << ", " << Align << ", ArgFlags);\n"; 265 O << IndentStr << "return false;\n"; 266 } else if (Action->isSubClassOf("CCCustom")) { 267 O << IndentStr 268 << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, " 269 << "LocVT, LocInfo, ArgFlags, State))\n"; 270 O << IndentStr << IndentStr << "return false;\n"; 271 } else { 272 Action->dump(); 273 PrintFatalError("Unknown CCAction!"); 274 } 275 } 276 } 277 278 namespace llvm { 279 280 void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) { 281 emitSourceFileHeader("Calling Convention Implementation Fragment", OS); 282 CallingConvEmitter(RK).run(OS); 283 } 284 285 } // End llvm namespace 286