1193323Sed//===- CallingConvEmitter.cpp - Generate calling conventions --------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This tablegen backend is responsible for emitting descriptions of the calling 11193323Sed// conventions supported by this target. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#include "CodeGenTarget.h" 16243830Sdim#include "llvm/TableGen/Error.h" 17226633Sdim#include "llvm/TableGen/Record.h" 18239462Sdim#include "llvm/TableGen/TableGenBackend.h" 19239462Sdim#include <cassert> 20193323Sedusing namespace llvm; 21193323Sed 22239462Sdimnamespace { 23239462Sdimclass CallingConvEmitter { 24239462Sdim RecordKeeper &Records; 25239462Sdimpublic: 26239462Sdim explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {} 27239462Sdim 28239462Sdim void run(raw_ostream &o); 29239462Sdim 30239462Sdimprivate: 31239462Sdim void EmitCallingConv(Record *CC, raw_ostream &O); 32239462Sdim void EmitAction(Record *Action, unsigned Indent, raw_ostream &O); 33239462Sdim unsigned Counter; 34239462Sdim}; 35239462Sdim} // End anonymous namespace 36239462Sdim 37195340Sedvoid CallingConvEmitter::run(raw_ostream &O) { 38193323Sed 39193323Sed std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv"); 40193323Sed 41193323Sed // Emit prototypes for all of the CC's so that they can forward ref each 42193323Sed // other. 43193323Sed for (unsigned i = 0, e = CCs.size(); i != e; ++i) { 44193323Sed O << "static bool " << CCs[i]->getName() 45218893Sdim << "(unsigned ValNo, MVT ValVT,\n" 46193323Sed << std::string(CCs[i]->getName().size()+13, ' ') 47218893Sdim << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 48193323Sed << std::string(CCs[i]->getName().size()+13, ' ') 49193323Sed << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n"; 50193323Sed } 51193323Sed 52193323Sed // Emit each calling convention description in full. 53193323Sed for (unsigned i = 0, e = CCs.size(); i != e; ++i) 54193323Sed EmitCallingConv(CCs[i], O); 55193323Sed} 56193323Sed 57193323Sed 58195340Sedvoid CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) { 59193323Sed ListInit *CCActions = CC->getValueAsListInit("Actions"); 60193323Sed Counter = 0; 61193323Sed 62193323Sed O << "\n\nstatic bool " << CC->getName() 63218893Sdim << "(unsigned ValNo, MVT ValVT,\n" 64193323Sed << std::string(CC->getName().size()+13, ' ') 65218893Sdim << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 66193323Sed << std::string(CC->getName().size()+13, ' ') 67193323Sed << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n"; 68193323Sed // Emit all of the actions, in order. 69193323Sed for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { 70193323Sed O << "\n"; 71193323Sed EmitAction(CCActions->getElementAsRecord(i), 2, O); 72193323Sed } 73193323Sed 74193323Sed O << "\n return true; // CC didn't match.\n"; 75193323Sed O << "}\n"; 76193323Sed} 77193323Sed 78193323Sedvoid CallingConvEmitter::EmitAction(Record *Action, 79195340Sed unsigned Indent, raw_ostream &O) { 80193323Sed std::string IndentStr = std::string(Indent, ' '); 81193323Sed 82193323Sed if (Action->isSubClassOf("CCPredicateAction")) { 83193323Sed O << IndentStr << "if ("; 84193323Sed 85193323Sed if (Action->isSubClassOf("CCIfType")) { 86193323Sed ListInit *VTs = Action->getValueAsListInit("VTs"); 87193323Sed for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { 88193323Sed Record *VT = VTs->getElementAsRecord(i); 89193323Sed if (i != 0) O << " ||\n " << IndentStr; 90193323Sed O << "LocVT == " << getEnumName(getValueType(VT)); 91193323Sed } 92193323Sed 93193323Sed } else if (Action->isSubClassOf("CCIf")) { 94193323Sed O << Action->getValueAsString("Predicate"); 95193323Sed } else { 96193323Sed Action->dump(); 97243830Sdim PrintFatalError("Unknown CCPredicateAction!"); 98193323Sed } 99193323Sed 100193323Sed O << ") {\n"; 101193323Sed EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); 102193323Sed O << IndentStr << "}\n"; 103193323Sed } else { 104193323Sed if (Action->isSubClassOf("CCDelegateTo")) { 105193323Sed Record *CC = Action->getValueAsDef("CC"); 106193323Sed O << IndentStr << "if (!" << CC->getName() 107193323Sed << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" 108193323Sed << IndentStr << " return false;\n"; 109193323Sed } else if (Action->isSubClassOf("CCAssignToReg")) { 110193323Sed ListInit *RegList = Action->getValueAsListInit("RegList"); 111193323Sed if (RegList->getSize() == 1) { 112193323Sed O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 113193323Sed O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; 114193323Sed } else { 115234353Sdim O << IndentStr << "static const uint16_t RegList" << ++Counter 116193323Sed << "[] = {\n"; 117193323Sed O << IndentStr << " "; 118193323Sed for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 119193323Sed if (i != 0) O << ", "; 120193323Sed O << getQualifiedName(RegList->getElementAsRecord(i)); 121193323Sed } 122193323Sed O << "\n" << IndentStr << "};\n"; 123193323Sed O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 124193323Sed << Counter << ", " << RegList->getSize() << ")) {\n"; 125193323Sed } 126193323Sed O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 127193323Sed << "Reg, LocVT, LocInfo));\n"; 128193323Sed O << IndentStr << " return false;\n"; 129193323Sed O << IndentStr << "}\n"; 130193323Sed } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) { 131193323Sed ListInit *RegList = Action->getValueAsListInit("RegList"); 132193323Sed ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); 133193323Sed if (ShadowRegList->getSize() >0 && 134193323Sed ShadowRegList->getSize() != RegList->getSize()) 135243830Sdim PrintFatalError("Invalid length of list of shadowed registers"); 136193323Sed 137193323Sed if (RegList->getSize() == 1) { 138193323Sed O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 139193323Sed O << getQualifiedName(RegList->getElementAsRecord(0)); 140193323Sed O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0)); 141193323Sed O << ")) {\n"; 142193323Sed } else { 143193323Sed unsigned RegListNumber = ++Counter; 144193323Sed unsigned ShadowRegListNumber = ++Counter; 145193323Sed 146234353Sdim O << IndentStr << "static const uint16_t RegList" << RegListNumber 147193323Sed << "[] = {\n"; 148193323Sed O << IndentStr << " "; 149193323Sed for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 150193323Sed if (i != 0) O << ", "; 151193323Sed O << getQualifiedName(RegList->getElementAsRecord(i)); 152193323Sed } 153193323Sed O << "\n" << IndentStr << "};\n"; 154193323Sed 155234353Sdim O << IndentStr << "static const uint16_t RegList" 156193323Sed << ShadowRegListNumber << "[] = {\n"; 157193323Sed O << IndentStr << " "; 158193323Sed for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { 159193323Sed if (i != 0) O << ", "; 160193323Sed O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); 161193323Sed } 162193323Sed O << "\n" << IndentStr << "};\n"; 163193323Sed 164193323Sed O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 165193323Sed << RegListNumber << ", " << "RegList" << ShadowRegListNumber 166193323Sed << ", " << RegList->getSize() << ")) {\n"; 167193323Sed } 168193323Sed O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 169193323Sed << "Reg, LocVT, LocInfo));\n"; 170193323Sed O << IndentStr << " return false;\n"; 171193323Sed O << IndentStr << "}\n"; 172193323Sed } else if (Action->isSubClassOf("CCAssignToStack")) { 173193323Sed int Size = Action->getValueAsInt("Size"); 174193323Sed int Align = Action->getValueAsInt("Align"); 175193323Sed 176193323Sed O << IndentStr << "unsigned Offset" << ++Counter 177193323Sed << " = State.AllocateStack("; 178193323Sed if (Size) 179193323Sed O << Size << ", "; 180193323Sed else 181243830Sdim O << "\n" << IndentStr << " State.getTarget().getDataLayout()" 182218893Sdim "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), "; 183193323Sed if (Align) 184193323Sed O << Align; 185193323Sed else 186243830Sdim O << "\n" << IndentStr << " State.getTarget().getDataLayout()" 187218893Sdim "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))"; 188212904Sdim if (Action->isSubClassOf("CCAssignToStackWithShadow")) 189212904Sdim O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg")); 190193323Sed O << ");\n" << IndentStr 191193323Sed << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 192193323Sed << Counter << ", LocVT, LocInfo));\n"; 193193323Sed O << IndentStr << "return false;\n"; 194193323Sed } else if (Action->isSubClassOf("CCPromoteToType")) { 195193323Sed Record *DestTy = Action->getValueAsDef("DestTy"); 196193323Sed O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 197193323Sed O << IndentStr << "if (ArgFlags.isSExt())\n" 198193323Sed << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 199193323Sed << IndentStr << "else if (ArgFlags.isZExt())\n" 200193323Sed << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 201193323Sed << IndentStr << "else\n" 202193323Sed << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 203193323Sed } else if (Action->isSubClassOf("CCBitConvertToType")) { 204193323Sed Record *DestTy = Action->getValueAsDef("DestTy"); 205193323Sed O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 206193323Sed O << IndentStr << "LocInfo = CCValAssign::BCvt;\n"; 207198090Srdivacky } else if (Action->isSubClassOf("CCPassIndirect")) { 208198090Srdivacky Record *DestTy = Action->getValueAsDef("DestTy"); 209198090Srdivacky O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 210198090Srdivacky O << IndentStr << "LocInfo = CCValAssign::Indirect;\n"; 211193323Sed } else if (Action->isSubClassOf("CCPassByVal")) { 212193323Sed int Size = Action->getValueAsInt("Size"); 213193323Sed int Align = Action->getValueAsInt("Align"); 214193323Sed O << IndentStr 215193323Sed << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " 216193323Sed << Size << ", " << Align << ", ArgFlags);\n"; 217193323Sed O << IndentStr << "return false;\n"; 218193323Sed } else if (Action->isSubClassOf("CCCustom")) { 219193323Sed O << IndentStr 220193323Sed << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, " 221193323Sed << "LocVT, LocInfo, ArgFlags, State))\n"; 222193323Sed O << IndentStr << IndentStr << "return false;\n"; 223193323Sed } else { 224193323Sed Action->dump(); 225243830Sdim PrintFatalError("Unknown CCAction!"); 226193323Sed } 227193323Sed } 228193323Sed} 229239462Sdim 230239462Sdimnamespace llvm { 231239462Sdim 232239462Sdimvoid EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) { 233239462Sdim emitSourceFileHeader("Calling Convention Implementation Fragment", OS); 234239462Sdim CallingConvEmitter(RK).run(OS); 235239462Sdim} 236239462Sdim 237239462Sdim} // End llvm namespace 238