[TableGen] Rename ListInit::getSize to just 'size' to be more consistent.
[oota-llvm.git] / utils / TableGen / CallingConvEmitter.cpp
index c51afd82a37a5faa3ffc33af51e3ec43f29d5f27..c7519b3e1528100dcaaa921a03b50bdd926c3c7d 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "CallingConvEmitter.h"
-#include "Record.h"
 #include "CodeGenTarget.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <cassert>
 using namespace llvm;
 
-void CallingConvEmitter::run(raw_ostream &O) {
-  EmitSourceFileHeader("Calling Convention Implementation Fragment", O);
+namespace {
+class CallingConvEmitter {
+  RecordKeeper &Records;
+public:
+  explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}
+
+  void run(raw_ostream &o);
 
+private:
+  void EmitCallingConv(Record *CC, raw_ostream &O);
+  void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
+  unsigned Counter;
+};
+} // End anonymous namespace
+
+void CallingConvEmitter::run(raw_ostream &O) {
   std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");
-  
-  // Emit prototypes for all of the CC's so that they can forward ref each
-  // other.
+
+  // Emit prototypes for all of the non-custom 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 ValVT,\n"
-      << std::string(CCs[i]->getName().size()+13, ' ')
-      << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
-      << std::string(CCs[i]->getName().size()+13, ' ')
-      << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
+    if (!CCs[i]->getValueAsBit("Custom")) {
+      O << "static bool " << CCs[i]->getName()
+        << "(unsigned ValNo, MVT ValVT,\n"
+        << std::string(CCs[i]->getName().size() + 13, ' ')
+        << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
+        << std::string(CCs[i]->getName().size() + 13, ' ')
+        << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
+    }
+  }
+
+  // Emit each non-custom calling convention description in full.
+  for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
+    if (!CCs[i]->getValueAsBit("Custom"))
+      EmitCallingConv(CCs[i], O);
   }
-  
-  // Emit each calling convention description in full.
-  for (unsigned i = 0, e = CCs.size(); i != e; ++i)
-    EmitCallingConv(CCs[i], O);
 }
 
 
@@ -50,7 +69,7 @@ void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
     << std::string(CC->getName().size()+13, ' ')
     << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
   // Emit all of the actions, in order.
-  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
+  for (unsigned i = 0, e = CCActions->size(); i != e; ++i) {
     O << "\n";
     EmitAction(CCActions->getElementAsRecord(i), 2, O);
   }
@@ -68,7 +87,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
     
     if (Action->isSubClassOf("CCIfType")) {
       ListInit *VTs = Action->getValueAsListInit("VTs");
-      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
+      for (unsigned i = 0, e = VTs->size(); i != e; ++i) {
         Record *VT = VTs->getElementAsRecord(i);
         if (i != 0) O << " ||\n    " << IndentStr;
         O << "LocVT == " << getEnumName(getValueType(VT));
@@ -78,7 +97,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
       O << Action->getValueAsString("Predicate");
     } else {
       Action->dump();
-      throw "Unknown CCPredicateAction!";
+      PrintFatalError("Unknown CCPredicateAction!");
     }
     
     O << ") {\n";
@@ -92,20 +111,20 @@ void CallingConvEmitter::EmitAction(Record *Action,
         << IndentStr << "  return false;\n";
     } else if (Action->isSubClassOf("CCAssignToReg")) {
       ListInit *RegList = Action->getValueAsListInit("RegList");
-      if (RegList->getSize() == 1) {
+      if (RegList->size() == 1) {
         O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
         O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
       } else {
-        O << IndentStr << "static const unsigned RegList" << ++Counter
+        O << IndentStr << "static const MCPhysReg RegList" << ++Counter
           << "[] = {\n";
         O << IndentStr << "  ";
-        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+        for (unsigned i = 0, e = RegList->size(); 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";
+          << Counter << ")) {\n";
       }
       O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
         << "Reg, LocVT, LocInfo));\n";
@@ -114,11 +133,10 @@ void CallingConvEmitter::EmitAction(Record *Action,
     } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
       ListInit *RegList = Action->getValueAsListInit("RegList");
       ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
-      if (ShadowRegList->getSize() >0 &&
-          ShadowRegList->getSize() != RegList->getSize())
-        throw "Invalid length of list of shadowed registers";
+      if (!ShadowRegList->empty() && ShadowRegList->size() != RegList->size())
+        PrintFatalError("Invalid length of list of shadowed registers");
 
-      if (RegList->getSize() == 1) {
+      if (RegList->size() == 1) {
         O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
         O << getQualifiedName(RegList->getElementAsRecord(0));
         O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
@@ -127,19 +145,19 @@ void CallingConvEmitter::EmitAction(Record *Action,
         unsigned RegListNumber = ++Counter;
         unsigned ShadowRegListNumber = ++Counter;
 
-        O << IndentStr << "static const unsigned RegList" << RegListNumber
+        O << IndentStr << "static const MCPhysReg RegList" << RegListNumber
           << "[] = {\n";
         O << IndentStr << "  ";
-        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
+        for (unsigned i = 0, e = RegList->size(); i != e; ++i) {
           if (i != 0) O << ", ";
           O << getQualifiedName(RegList->getElementAsRecord(i));
         }
         O << "\n" << IndentStr << "};\n";
 
-        O << IndentStr << "static const unsigned RegList"
+        O << IndentStr << "static const MCPhysReg RegList"
           << ShadowRegListNumber << "[] = {\n";
         O << IndentStr << "  ";
-        for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
+        for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i) {
           if (i != 0) O << ", ";
           O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
         }
@@ -147,7 +165,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
 
         O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
           << RegListNumber << ", " << "RegList" << ShadowRegListNumber
-          << ", " << RegList->getSize() << ")) {\n";
+          << ")) {\n";
       }
       O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
         << "Reg, LocVT, LocInfo));\n";
@@ -162,28 +180,73 @@ void CallingConvEmitter::EmitAction(Record *Action,
       if (Size)
         O << Size << ", ";
       else
-        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
-          "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), ";
+        O << "\n" << IndentStr
+          << "  State.getMachineFunction().getTarget().getDataLayout()"
+             "->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
+             " ";
       if (Align)
         O << Align;
       else
-        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
-          "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
-      if (Action->isSubClassOf("CCAssignToStackWithShadow"))
-        O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
+        O << "\n" << IndentStr
+          << "  State.getMachineFunction().getTarget().getDataLayout()"
+             "->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()"
+             "))";
       O << ");\n" << IndentStr
         << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
         << Counter << ", LocVT, LocInfo));\n";
       O << IndentStr << "return false;\n";
+    } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
+      int Size = Action->getValueAsInt("Size");
+      int Align = Action->getValueAsInt("Align");
+      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
+
+      unsigned ShadowRegListNumber = ++Counter;
+
+      O << IndentStr << "static const MCPhysReg ShadowRegList"
+          << ShadowRegListNumber << "[] = {\n";
+      O << IndentStr << "  ";
+      for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i) {
+        if (i != 0) O << ", ";
+        O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
+      }
+      O << "\n" << IndentStr << "};\n";
+
+      O << IndentStr << "unsigned Offset" << ++Counter
+        << " = State.AllocateStack("
+        << Size << ", " << Align << ", "
+        << "ShadowRegList" << ShadowRegListNumber << ");\n";
+      O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
+        << Counter << ", LocVT, LocInfo));\n";
+      O << IndentStr << "return false;\n";
     } else if (Action->isSubClassOf("CCPromoteToType")) {
       Record *DestTy = Action->getValueAsDef("DestTy");
-      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
-      O << IndentStr << "if (ArgFlags.isSExt())\n"
-        << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
-        << IndentStr << "else if (ArgFlags.isZExt())\n"
-        << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
-        << IndentStr << "else\n"
-        << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
+      MVT::SimpleValueType DestVT = getValueType(DestTy);
+      O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
+      if (MVT(DestVT).isFloatingPoint()) {
+        O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
+      } else {
+        O << IndentStr << "if (ArgFlags.isSExt())\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
+          << IndentStr << "else if (ArgFlags.isZExt())\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
+          << IndentStr << "else\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
+      }
+    } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) {
+      Record *DestTy = Action->getValueAsDef("DestTy");
+      MVT::SimpleValueType DestVT = getValueType(DestTy);
+      O << IndentStr << "LocVT = " << getEnumName(DestVT) << ";\n";
+      if (MVT(DestVT).isFloatingPoint()) {
+        PrintFatalError("CCPromoteToUpperBitsInType does not handle floating "
+                        "point");
+      } else {
+        O << IndentStr << "if (ArgFlags.isSExt())\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::SExtUpper;\n"
+          << IndentStr << "else if (ArgFlags.isZExt())\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExtUpper;\n"
+          << IndentStr << "else\n"
+          << IndentStr << IndentStr << "LocInfo = CCValAssign::AExtUpper;\n";
+      }
     } else if (Action->isSubClassOf("CCBitConvertToType")) {
       Record *DestTy = Action->getValueAsDef("DestTy");
       O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
@@ -206,7 +269,16 @@ void CallingConvEmitter::EmitAction(Record *Action,
       O << IndentStr << IndentStr << "return false;\n";
     } else {
       Action->dump();
-      throw "Unknown CCAction!";
+      PrintFatalError("Unknown CCAction!");
     }
   }
 }
+
+namespace llvm {
+
+void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) {
+  emitSourceFileHeader("Calling Convention Implementation Fragment", OS);
+  CallingConvEmitter(RK).run(OS);
+}
+
+} // End llvm namespace