diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp b/llvm/utils/TableGen/CallingConvEmitter.cpp new file mode 100644 index 000000000000..977191f92d3c --- /dev/null +++ b/llvm/utils/TableGen/CallingConvEmitter.cpp @@ -0,0 +1,128 @@ +//===- CallingConvEmitter.cpp - Generate calling conventions --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting descriptions of the calling +// conventions supported by this target. +// +//===----------------------------------------------------------------------===// + +#include "CallingConvEmitter.h" +#include "Record.h" +#include "CodeGenTarget.h" +using namespace llvm; + +void CallingConvEmitter::run(std::ostream &O) { + EmitSourceFileHeader("Calling Convention Implementation Fragment", O); + + std::vector CCs = Records.getAllDerivedDefinitions("CallingConv"); + + // Emit prototypes for all of the CC's so that they can forward ref each + // other. + for (unsigned i = 0, e = CCs.size(); i != e; ++i) { + O << "static bool " << CCs[i]->getName() + << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n" + << std::string(CCs[i]->getName().size()+13, ' ') + << "CCValAssign::LocInfo LocInfo, unsigned ArgFlags, CCState &State);\n"; + } + + // Emit each calling convention description in full. + for (unsigned i = 0, e = CCs.size(); i != e; ++i) + EmitCallingConv(CCs[i], O); +} + + +void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) { + ListInit *CCActions = CC->getValueAsListInit("Actions"); + Counter = 0; + + O << "\n\nstatic bool " << CC->getName() + << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n" + << std::string(CC->getName().size()+13, ' ') + << "CCValAssign::LocInfo LocInfo, " + << "unsigned ArgFlags, CCState &State) {\n"; + + // Emit all of the actions, in order. + for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) { + O << "\n"; + EmitAction(CCActions->getElementAsRecord(i), 2, O); + } + + O << "\n return true; // CC didn't match.\n"; + O << "}\n"; +} + +void CallingConvEmitter::EmitAction(Record *Action, + unsigned Indent, std::ostream &O) { + std::string IndentStr = std::string(Indent, ' '); + + if (Action->isSubClassOf("CCPredicateAction")) { + O << IndentStr << "if ("; + + if (Action->isSubClassOf("CCMatchType")) { + ListInit *VTs = Action->getValueAsListInit("VTs"); + for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) { + Record *VT = VTs->getElementAsRecord(i); + if (i != 0) O << " || \n " << IndentStr; + O << "LocVT == " << getEnumName(getValueType(VT)); + } + + } else if (Action->isSubClassOf("CCMatchIf")) { + O << Action->getValueAsString("Predicate"); + } else { + Action->dump(); + throw "Unknown CCPredicateAction!"; + } + + O << ") {\n"; + EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O); + O << IndentStr << "}\n"; + } else { + if (Action->isSubClassOf("CCDelegateTo")) { + Record *CC = Action->getValueAsDef("CC"); + O << IndentStr << "if (!" << CC->getName() + << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" + << IndentStr << " return false;\n"; + } else if (Action->isSubClassOf("CCAssignToReg")) { + ListInit *RegList = Action->getValueAsListInit("RegList"); + if (RegList->getSize() == 1) { + O << IndentStr << "if (unsigned Reg = State.AllocateReg("; + O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n"; + } else { + O << IndentStr << "static const unsigned RegList" << ++Counter + << "[] = {\n"; + O << IndentStr << " "; + for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { + if (i != 0) O << ", "; + O << getQualifiedName(RegList->getElementAsRecord(i)); + } + O << "\n" << IndentStr << "};\n"; + O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList" + << Counter << ", " << RegList->getSize() << ")) {\n"; + } + O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " + << "Reg, LocVT, LocInfo));\n"; + O << IndentStr << " return false;\n"; + O << IndentStr << "}\n"; + } else if (Action->isSubClassOf("CCAssignToStack")) { + int Size = Action->getValueAsInt("Size"); + int Align = Action->getValueAsInt("Align"); + + O << IndentStr << "unsigned Offset" << ++Counter + << " = State.AllocateStack(" << Size << ", " << Align << ");\n"; + O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ArgVT, Offset" + << Counter << ", LocVT, LocInfo));\n"; + O << IndentStr << "return false;\n"; + } else if (Action->isSubClassOf("CCPromoteToType")) { + + } else { + Action->dump(); + throw "Unknown CCAction!"; + } + } +} \ No newline at end of file diff --git a/llvm/utils/TableGen/CallingConvEmitter.h b/llvm/utils/TableGen/CallingConvEmitter.h new file mode 100644 index 000000000000..a0bfab3e75cf --- /dev/null +++ b/llvm/utils/TableGen/CallingConvEmitter.h @@ -0,0 +1,38 @@ +//===- CallingConvEmitter.h - Generate calling conventions ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting descriptions of the calling +// conventions supported by this target. +// +//===----------------------------------------------------------------------===// + +#ifndef CALLINGCONV_EMITTER_H +#define CALLINGCONV_EMITTER_H + +#include "TableGenBackend.h" +#include +#include +#include + +namespace llvm { + class CallingConvEmitter : public TableGenBackend { + RecordKeeper &Records; + public: + CallingConvEmitter(RecordKeeper &R) : Records(R) {} + + // run - Output the asmwriter, returning true on failure. + void run(std::ostream &o); + + private: + void EmitCallingConv(Record *CC, std::ostream &O); + void EmitAction(Record *Action, unsigned Indent, std::ostream &O); + unsigned Counter; + }; +} +#endif