CallingConvEmitter.cpp revision e50ed30282bb5b4a9ed952580523f2dda16215ac
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, EVT ValVT,\n" 30 << std::string(CCs[i]->getName().size()+13, ' ') 31 << "EVT 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 ListInit *CCActions = CC->getValueAsListInit("Actions"); 44 Counter = 0; 45 46 O << "\n\nstatic bool " << CC->getName() 47 << "(unsigned ValNo, EVT ValVT,\n" 48 << std::string(CC->getName().size()+13, ' ') 49 << "EVT 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 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 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 ListInit *RegList = Action->getValueAsListInit("RegList"); 116 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(LocVT.getTypeForEVT()), "; 167 if (Align) 168 O << Align; 169 else 170 O << "\n" << IndentStr << " State.getTarget().getTargetData()" 171 "->getABITypeAlignment(LocVT.getTypeForEVT())"; 172 O << ");\n" << IndentStr 173 << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 174 << Counter << ", LocVT, LocInfo));\n"; 175 O << IndentStr << "return false;\n"; 176 } else if (Action->isSubClassOf("CCPromoteToType")) { 177 Record *DestTy = Action->getValueAsDef("DestTy"); 178 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 179 O << IndentStr << "if (ArgFlags.isSExt())\n" 180 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 181 << IndentStr << "else if (ArgFlags.isZExt())\n" 182 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 183 << IndentStr << "else\n" 184 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 185 } else if (Action->isSubClassOf("CCBitConvertToType")) { 186 Record *DestTy = Action->getValueAsDef("DestTy"); 187 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 188 O << IndentStr << "LocInfo = CCValAssign::BCvt;\n"; 189 } else if (Action->isSubClassOf("CCPassIndirect")) { 190 Record *DestTy = Action->getValueAsDef("DestTy"); 191 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 192 O << IndentStr << "LocInfo = CCValAssign::Indirect;\n"; 193 } else if (Action->isSubClassOf("CCPassByVal")) { 194 int Size = Action->getValueAsInt("Size"); 195 int Align = Action->getValueAsInt("Align"); 196 O << IndentStr 197 << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, " 198 << Size << ", " << Align << ", ArgFlags);\n"; 199 O << IndentStr << "return false;\n"; 200 } else if (Action->isSubClassOf("CCCustom")) { 201 O << IndentStr 202 << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, " 203 << "LocVT, LocInfo, ArgFlags, State))\n"; 204 O << IndentStr << IndentStr << "return false;\n"; 205 } else { 206 Action->dump(); 207 throw "Unknown CCAction!"; 208 } 209 } 210} 211