Finegrainify namespacification
[oota-llvm.git] / utils / TableGen / TableGen.cpp
index 17f2b2e7181600667299149ec0f71017dcd94bbc..7bd52b37cf06eaf602f9266d0d10d18ab87d39fb 100644 (file)
@@ -1,15 +1,40 @@
+//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// TableGen is a tool which can be used to build up a description of something,
+// then invoke one or more "tablegen backends" to emit information about the
+// description in some predefined format.  In practice, this is used by the LLVM
+// code generators to automate generation of a code generator through a
+// high-level description of the target.
+//
+//===----------------------------------------------------------------------===//
+
 #include "Record.h"
 #include "Support/CommandLine.h"
-#include "Support/Signals.h"
+#include "llvm/System/Signals.h"
+#include "Support/FileUtilities.h"
 #include "CodeEmitterGen.h"
+#include "RegisterInfoEmitter.h"
+#include "InstrInfoEmitter.h"
+#include "InstrSelectorEmitter.h"
 #include <algorithm>
+#include <cstdio>
 #include <fstream>
+using namespace llvm;
 
 enum ActionType {
   PrintRecords,
   GenEmitter,
+  GenRegisterEnums, GenRegister, GenRegisterHeader,
+  GenInstrEnums, GenInstrs, GenInstrSelector,
   PrintEnums,
-  Parse,
+  Parse
 };
 
 namespace {
@@ -19,25 +44,46 @@ namespace {
                                "Print all records to stdout (default)"),
                     clEnumValN(GenEmitter, "gen-emitter",
                                "Generate machine code emitter"),
+                    clEnumValN(GenRegisterEnums, "gen-register-enums",
+                               "Generate enum values for registers"),
+                    clEnumValN(GenRegister, "gen-register-desc",
+                               "Generate a register info description"),
+                    clEnumValN(GenRegisterHeader, "gen-register-desc-header",
+                               "Generate a register info description header"),
+                    clEnumValN(GenInstrEnums, "gen-instr-enums",
+                               "Generate enum values for instructions"),
+                    clEnumValN(GenInstrs, "gen-instr-desc",
+                               "Generate instruction descriptions"),
+                    clEnumValN(GenInstrSelector, "gen-instr-selector",
+                               "Generate an instruction selector"),
                     clEnumValN(PrintEnums, "print-enums",
                                "Print enum values for a class"),
                     clEnumValN(Parse, "parse",
                                "Interpret machine code (testing only)"),
-                    0));
+                    clEnumValEnd));
 
   cl::opt<std::string>
   Class("class", cl::desc("Print Enum list for this class"),
         cl::value_desc("class name"));
 
- cl::opt<std::string>
- OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
-                cl::init("-"));
-}
+  cl::opt<std::string>
+  OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
+                 cl::init("-"));
 
+  cl::opt<std::string>
+  InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
 
-void ParseFile();
+  cl::opt<std::string>
+  IncludeDir("I", cl::desc("Directory of include files"),
+                  cl::value_desc("directory"), cl::init(""));
+}
+
+namespace llvm {
+  void ParseFile(const std::string &Filename,
+                 const std::string &IncludeDir);
+}
 
-RecordKeeper Records;
+RecordKeeper llvm::Records;
 
 static Init *getBit(Record *R, unsigned BitNo) {
   const std::vector<RecordVal> &V = R->getValues();
@@ -52,7 +98,7 @@ static Init *getBit(Record *R, unsigned BitNo) {
     }
 
   std::cerr << "Cannot find requested bit!\n";
-  abort();
+  exit(1);
   return 0;
 }
 
@@ -157,9 +203,9 @@ static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
 }
 
 // ParseMachineCode - Try to split the vector of instructions (which is
-// intentially taken by-copy) in half, narrowing down the possible instructions
-// that we may have found.  Eventually, this list will get pared down to zero or
-// one instruction, in which case we have a match or failure.
+// intentionally taken by-copy) in half, narrowing down the possible
+// instructions that we may have found.  Eventually, this list will get pared
+// down to zero or one instruction, in which case we have a match or failure.
 //
 static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB, 
                                std::vector<Record*>::iterator InstsE,
@@ -171,7 +217,7 @@ static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
     for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i)
       if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i)))
        if (getMemoryBit(M, i) != BI->getValue())
-         return 0;
+         throw std::string("Parse failed!\n");
     return Inst;
   }
 
@@ -228,7 +274,7 @@ static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
     if (RangeBegin == InstsB && RangeEnd == InstsE) {
       std::cerr << "Error: Could not distinguish among the following insts!:\n";
       PrintRange(InstsB, InstsE);
-      abort();
+      exit(1);
     }
     
 #if 0
@@ -350,24 +396,11 @@ static void ParseMachineCode() {
   };
 #endif
 
-  std::vector<Record*> Insts;
-
-  const std::map<std::string, Record*> &Defs = Records.getDefs();
-  Record *Inst = Records.getClass("Instruction");
-  assert(Inst && "Couldn't find Instruction class!");
-
-  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
-        E = Defs.end(); I != E; ++I)
-    if (I->second->isSubClassOf(Inst))
-      Insts.push_back(I->second);
+  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
 
   unsigned char *BuffPtr = Buffer;
   while (1) {
     Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr);
-    if (R == 0) {
-      std::cout << "Parse failed!\n";
-      return;
-    }
     PrintInstruction(R, BuffPtr);
 
     unsigned Bits = getNumBits(R);
@@ -376,10 +409,9 @@ static void ParseMachineCode() {
   }
 }
 
-
 int main(int argc, char **argv) {
   cl::ParseCommandLineOptions(argc, argv);
-  ParseFile();
+  ParseFile(InputFilename, IncludeDir);
 
   std::ostream *Out = &std::cout;
   if (OutputFilename != "-") {
@@ -394,34 +426,60 @@ int main(int argc, char **argv) {
     RemoveFileOnSignal(OutputFilename);
   }
 
-  int ErrorCode = 0;
-
-  switch (Action) {
-  case Parse: ParseMachineCode(); break;
-  case GenEmitter:
-    ErrorCode = CodeEmitterGen(Records).createEmitter(*Out);
-    break;
-  case PrintRecords:
-    *Out << Records;           // No argument, dump all contents
-    break;
-  case PrintEnums:
-    Record *R = Records.getClass(Class);
-    if (R == 0) {
-      std::cerr << "Cannot find class '" << Class << "'!\n";
-      abort();
+  try {
+    switch (Action) {
+    case PrintRecords:
+      *Out << Records;           // No argument, dump all contents
+      break;
+    case Parse:
+      ParseMachineCode();
+      break;
+    case GenEmitter:
+      CodeEmitterGen(Records).run(*Out);
+      break;
+
+    case GenRegisterEnums:
+      RegisterInfoEmitter(Records).runEnums(*Out);
+      break;
+    case GenRegister:
+      RegisterInfoEmitter(Records).run(*Out);
+      break;
+    case GenRegisterHeader:
+      RegisterInfoEmitter(Records).runHeader(*Out);
+      break;
+
+    case GenInstrEnums:
+      InstrInfoEmitter(Records).runEnums(*Out);
+      break;
+    case GenInstrs:
+      InstrInfoEmitter(Records).run(*Out);
+      break;
+    case GenInstrSelector:
+      InstrSelectorEmitter(Records).run(*Out);
+      break;
+    case PrintEnums:
+    {
+      std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
+      for (unsigned i = 0, e = Recs.size(); i != e; ++i)
+        *Out << Recs[i]->getName() << ", ";
+      *Out << "\n";
+      break;
     }
-
-    const std::map<std::string, Record*> &Defs = Records.getDefs();
-    for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
-          E = Defs.end(); I != E; ++I) {
-      if (I->second->isSubClassOf(R)) {
-       *Out << I->first << ", ";
-      }
+    default:
+      assert(1 && "Invalid Action");
+      return 1;
+    }
+  } catch (const std::string &Error) {
+    std::cerr << Error << "\n";
+    if (Out != &std::cout) {
+      delete Out;                             // Close the file
+      std::remove(OutputFilename.c_str());    // Remove the file, it's broken
     }
-    *Out << "\n";
-    break;
+    return 1;
   }
 
-  if (Out != &std::cout) delete Out;
-  return ErrorCode;
+  if (Out != &std::cout) {
+    delete Out;                               // Close the file
+  }
+  return 0;
 }