CallingConvEmitter.cpp revision d4a9066c93da9a5aab47ca228d82e796fdec70c0
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 "CallingConvEmitter.h" 16#include "Record.h" 17#include "CodeGenTarget.h" 18using namespace llvm; 19 20void CallingConvEmitter::run(raw_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 ValVT,\n" 30 << std::string(CCs[i]->getName().size()+13, ' ') 31 << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 32 << std::string(CCs[i]->getName().size()+13, ' ') 33 << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n"; 34 } 35 36 // Emit each calling convention description in full. 37 for (unsigned i = 0, e = CCs.size(); i != e; ++i) 38 EmitCallingConv(CCs[i], O); 39} 40 41 42void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) { 43 const ListInit *CCActions = CC->getValueAsListInit("Actions"); 44 Counter = 0; 45 46 O << "\n\nstatic bool " << CC->getName() 47 << "(unsigned ValNo, MVT ValVT,\n" 48 << std::string(CC->getName().size()+13, ' ') 49 << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" 50 << std::string(CC->getName().size()+13, ' ') 51 << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n"; 52 // Emit all of the actions, in order. 53 for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { 54 O << "\n"; 55 EmitAction(CCActions->getElementAsRecord(i), 2, O); 56 } 57 58 O << "\n return true; // CC didn't match.\n"; 59 O << "}\n"; 60} 61 62void CallingConvEmitter::EmitAction(Record *Action, 63 unsigned Indent, raw_ostream &O) { 64 std::string IndentStr = std::string(Indent, ' '); 65 66 if (Action->isSubClassOf("CCPredicateAction")) { 67 O << IndentStr << "if ("; 68 69 if (Action->isSubClassOf("CCIfType")) { 70 const ListInit *VTs = Action->getValueAsListInit("VTs"); 71 for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { 72 Record *VT = VTs->getElementAsRecord(i); 73 if (i != 0) O << " ||\n " << IndentStr; 74 O << "LocVT == " << getEnumName(getValueType(VT)); 75 } 76 77 } else if (Action->isSubClassOf("CCIf")) { 78 O << Action->getValueAsString("Predicate"); 79 } else { 80 Action->dump(); 81 throw "Unknown CCPredicateAction!"; 82 } 83 84 O << ") {\n"; 85 EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); 86 O << IndentStr << "}\n"; 87 } else { 88 if (Action->isSubClassOf("CCDelegateTo")) { 89 Record *CC = Action->getValueAsDef("CC"); 90 O << IndentStr << "if (!" << CC->getName() 91 << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" 92 << IndentStr << " return false;\n"; 93 } else if (Action->isSubClassOf("CCAssignToReg")) { 94 const ListInit *RegList = Action->getValueAsListInit("RegList"); 95 if (RegList->getSize() == 1) { 96 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 97 O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; 98 } else { 99 O << IndentStr << "static const unsigned RegList" << ++Counter 100 << "[] = {\n"; 101 O << IndentStr << " "; 102 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 103 if (i != 0) O << ", "; 104 O << getQualifiedName(RegList->getElementAsRecord(i)); 105 } 106 O << "\n" << IndentStr << "};\n"; 107 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 108 << Counter << ", " << RegList->getSize() << ")) {\n"; 109 } 110 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 111 << "Reg, LocVT, LocInfo));\n"; 112 O << IndentStr << " return false;\n"; 113 O << IndentStr << "}\n"; 114 } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) { 115 const ListInit *RegList = Action->getValueAsListInit("RegList"); 116 const ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList"); 117 if (ShadowRegList->getSize() >0 && 118 ShadowRegList->getSize() != RegList->getSize()) 119 throw "Invalid length of list of shadowed registers"; 120 121 if (RegList->getSize() == 1) { 122 O << IndentStr << "if (unsigned Reg = State.AllocateReg("; 123 O << getQualifiedName(RegList->getElementAsRecord(0)); 124 O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0)); 125 O << ")) {\n"; 126 } else { 127 unsigned RegListNumber = ++Counter; 128 unsigned ShadowRegListNumber = ++Counter; 129 130 O << IndentStr << "static const unsigned RegList" << RegListNumber 131 << "[] = {\n"; 132 O << IndentStr << " "; 133 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 134 if (i != 0) O << ", "; 135 O << getQualifiedName(RegList->getElementAsRecord(i)); 136 } 137 O << "\n" << IndentStr << "};\n"; 138 139 O << IndentStr << "static const unsigned RegList" 140 << ShadowRegListNumber << "[] = {\n"; 141 O << IndentStr << " "; 142 for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) { 143 if (i != 0) O << ", "; 144 O << getQualifiedName(ShadowRegList->getElementAsRecord(i)); 145 } 146 O << "\n" << IndentStr << "};\n"; 147 148 O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" 149 << RegListNumber << ", " << "RegList" << ShadowRegListNumber 150 << ", " << RegList->getSize() << ")) {\n"; 151 } 152 O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " 153 << "Reg, LocVT, LocInfo));\n"; 154 O << IndentStr << " return false;\n"; 155 O << IndentStr << "}\n"; 156 } else if (Action->isSubClassOf("CCAssignToStack")) { 157 int Size = Action->getValueAsInt("Size"); 158 int Align = Action->getValueAsInt("Align"); 159 160 O << IndentStr << "unsigned Offset" << ++Counter 161 << " = State.AllocateStack("; 162 if (Size) 163 O << Size << ", "; 164 else 165 O << "\n" << IndentStr << " State.getTarget().getTargetData()" 166 "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), "; 167 if (Align) 168 O << Align; 169 else 170 O << "\n" << IndentStr << " State.getTarget().getTargetData()" 171 "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))"; 172 if (Action->isSubClassOf("CCAssignToStackWithShadow")) 173 O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg")); 174 O << ");\n" << IndentStr 175 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 176 << Counter << ", LocVT, LocInfo));\n"; 177 O << IndentStr << "return false;\n"; 178 } else if (Action->isSubClassOf("CCPromoteToType")) { 179 Record *DestTy = Action->getValueAsDef("DestTy"); 180 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 181 O << IndentStr << "if (ArgFlags.isSExt())\n" 182 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 183 << IndentStr << "else if (ArgFlags.isZExt())\n" 184 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 185 << IndentStr << "else\n" 186 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 187 } else if (Action->isSubClassOf("CCBitConvertToType")) { 188 Record *DestTy = Action->getValueAsDef("DestTy"); 189 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 190 O << IndentStr << "LocInfo = CCValAssign::BCvt;\n"; 191 } else if (Action->isSubClassOf("CCPassIndirect")) { 192 Record *DestTy = Action->getValueAsDef("DestTy"); 193 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 194 O << IndentStr << "LocInfo = CCValAssign::Indirect;\n"; 195 } else if (Action->isSubClassOf("CCPassByVal")) { 196 int Size = Action->getValueAsInt("Size"); 197 int Align = Action->getValueAsInt("Align"); 198 O << IndentStr 199 << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " 200 << Size << ", " << Align << ", ArgFlags);\n"; 201 O << IndentStr << "return false;\n"; 202 } else if (Action->isSubClassOf("CCCustom")) { 203 O << IndentStr 204 << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, " 205 << "LocVT, LocInfo, ArgFlags, State))\n"; 206 O << IndentStr << IndentStr << "return false;\n"; 207 } else { 208 Action->dump(); 209 throw "Unknown CCAction!"; 210 } 211 } 212} 213