CallingConvEmitter.cpp revision e3ef744d3e3557ee286d2ed3bf8306e5fbbd1ac4
1//===- CallingConvEmitter.cpp - Generate calling conventions --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source 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(std::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::ValueType ValVT,\n" 30 << std::string(CCs[i]->getName().size()+13, ' ') 31 << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n" 32 << std::string(CCs[i]->getName().size()+13, ' ') 33 << "unsigned 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, std::ostream &O) { 43 ListInit *CCActions = CC->getValueAsListInit("Actions"); 44 Counter = 0; 45 46 O << "\n\nstatic bool " << CC->getName() 47 << "(unsigned ValNo, MVT::ValueType ValVT,\n" 48 << std::string(CC->getName().size()+13, ' ') 49 << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n" 50 << std::string(CC->getName().size()+13, ' ') 51 << "unsigned 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, std::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("CCAssignToStack")) { 115 int Size = Action->getValueAsInt("Size"); 116 int Align = Action->getValueAsInt("Align"); 117 118 O << IndentStr << "unsigned Offset" << ++Counter 119 << " = State.AllocateStack(" << Size << ", " << Align << ");\n"; 120 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 121 << Counter << ", LocVT, LocInfo));\n"; 122 O << IndentStr << "return false;\n"; 123 } else if (Action->isSubClassOf("CCAssignToStackABISizeAlign")) { 124 O << IndentStr << "unsigned Offset" << ++Counter 125 << " = State.AllocateStack(State.getTarget().getTargetData()" 126 "->getABITypeSize(MVT::getTypeForValueType(LocVT)),\n"; 127 O << IndentStr << " State.getTarget().getTargetData()" 128 "->getABITypeAlignment(MVT::getTypeForValueType(LocVT)));\n"; 129 O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset" 130 << Counter << ", LocVT, LocInfo));\n"; 131 O << IndentStr << "return false;\n"; 132 } else if (Action->isSubClassOf("CCPromoteToType")) { 133 Record *DestTy = Action->getValueAsDef("DestTy"); 134 O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n"; 135 O << IndentStr << "if (ArgFlags & ISD::ParamFlags::SExt)\n" 136 << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n" 137 << IndentStr << "else if (ArgFlags & ISD::ParamFlags::ZExt)\n" 138 << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" 139 << IndentStr << "else\n" 140 << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; 141 } else if (Action->isSubClassOf("CCStructAssign")) { 142 O << IndentStr << 143 "State.HandleStruct(ValNo, ValVT, LocVT, LocInfo, ArgFlags);\n"; 144 O << IndentStr << "return false;\n"; 145 } else { 146 Action->dump(); 147 throw "Unknown CCAction!"; 148 } 149 } 150} 151