Make clang-tblgen backends functions instead of TableGenBackends.

Get rid of a bunch of header files. TableGen output should be unaffected.

Patch by Sean Silva!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158388 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 385deb8..5cb40c5 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -23,16 +23,206 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "NeonEmitter.h"
-#include "llvm/TableGen/Error.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
 #include <string>
-
 using namespace llvm;
 
+enum OpKind {
+  OpNone,
+  OpUnavailable,
+  OpAdd,
+  OpAddl,
+  OpAddw,
+  OpSub,
+  OpSubl,
+  OpSubw,
+  OpMul,
+  OpMla,
+  OpMlal,
+  OpMls,
+  OpMlsl,
+  OpMulN,
+  OpMlaN,
+  OpMlsN,
+  OpMlalN,
+  OpMlslN,
+  OpMulLane,
+  OpMullLane,
+  OpMlaLane,
+  OpMlsLane,
+  OpMlalLane,
+  OpMlslLane,
+  OpQDMullLane,
+  OpQDMlalLane,
+  OpQDMlslLane,
+  OpQDMulhLane,
+  OpQRDMulhLane,
+  OpEq,
+  OpGe,
+  OpLe,
+  OpGt,
+  OpLt,
+  OpNeg,
+  OpNot,
+  OpAnd,
+  OpOr,
+  OpXor,
+  OpAndNot,
+  OpOrNot,
+  OpCast,
+  OpConcat,
+  OpDup,
+  OpDupLane,
+  OpHi,
+  OpLo,
+  OpSelect,
+  OpRev16,
+  OpRev32,
+  OpRev64,
+  OpReinterpret,
+  OpAbdl,
+  OpAba,
+  OpAbal
+};
+
+enum ClassKind {
+  ClassNone,
+  ClassI,           // generic integer instruction, e.g., "i8" suffix
+  ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
+  ClassW,           // width-specific instruction, e.g., "8" suffix
+  ClassB            // bitcast arguments with enum argument to specify type
+};
+
+/// NeonTypeFlags - Flags to identify the types for overloaded Neon
+/// builtins.  These must be kept in sync with the flags in
+/// include/clang/Basic/TargetBuiltins.h.
+namespace {
+class NeonTypeFlags {
+  enum {
+    EltTypeMask = 0xf,
+    UnsignedFlag = 0x10,
+    QuadFlag = 0x20
+  };
+  uint32_t Flags;
+
+public:
+  enum EltType {
+    Int8,
+    Int16,
+    Int32,
+    Int64,
+    Poly8,
+    Poly16,
+    Float16,
+    Float32
+  };
+
+  NeonTypeFlags(unsigned F) : Flags(F) {}
+  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
+    if (IsUnsigned)
+      Flags |= UnsignedFlag;
+    if (IsQuad)
+      Flags |= QuadFlag;
+  }
+
+  uint32_t getFlags() const { return Flags; }
+};
+} // end anonymous namespace
+
+namespace {
+class NeonEmitter {
+  RecordKeeper &Records;
+  StringMap<OpKind> OpMap;
+  DenseMap<Record*, ClassKind> ClassMap;
+
+public:
+  NeonEmitter(RecordKeeper &R) : Records(R) {
+    OpMap["OP_NONE"]  = OpNone;
+    OpMap["OP_UNAVAILABLE"] = OpUnavailable;
+    OpMap["OP_ADD"]   = OpAdd;
+    OpMap["OP_ADDL"]  = OpAddl;
+    OpMap["OP_ADDW"]  = OpAddw;
+    OpMap["OP_SUB"]   = OpSub;
+    OpMap["OP_SUBL"]  = OpSubl;
+    OpMap["OP_SUBW"]  = OpSubw;
+    OpMap["OP_MUL"]   = OpMul;
+    OpMap["OP_MLA"]   = OpMla;
+    OpMap["OP_MLAL"]  = OpMlal;
+    OpMap["OP_MLS"]   = OpMls;
+    OpMap["OP_MLSL"]  = OpMlsl;
+    OpMap["OP_MUL_N"] = OpMulN;
+    OpMap["OP_MLA_N"] = OpMlaN;
+    OpMap["OP_MLS_N"] = OpMlsN;
+    OpMap["OP_MLAL_N"] = OpMlalN;
+    OpMap["OP_MLSL_N"] = OpMlslN;
+    OpMap["OP_MUL_LN"]= OpMulLane;
+    OpMap["OP_MULL_LN"] = OpMullLane;
+    OpMap["OP_MLA_LN"]= OpMlaLane;
+    OpMap["OP_MLS_LN"]= OpMlsLane;
+    OpMap["OP_MLAL_LN"] = OpMlalLane;
+    OpMap["OP_MLSL_LN"] = OpMlslLane;
+    OpMap["OP_QDMULL_LN"] = OpQDMullLane;
+    OpMap["OP_QDMLAL_LN"] = OpQDMlalLane;
+    OpMap["OP_QDMLSL_LN"] = OpQDMlslLane;
+    OpMap["OP_QDMULH_LN"] = OpQDMulhLane;
+    OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane;
+    OpMap["OP_EQ"]    = OpEq;
+    OpMap["OP_GE"]    = OpGe;
+    OpMap["OP_LE"]    = OpLe;
+    OpMap["OP_GT"]    = OpGt;
+    OpMap["OP_LT"]    = OpLt;
+    OpMap["OP_NEG"]   = OpNeg;
+    OpMap["OP_NOT"]   = OpNot;
+    OpMap["OP_AND"]   = OpAnd;
+    OpMap["OP_OR"]    = OpOr;
+    OpMap["OP_XOR"]   = OpXor;
+    OpMap["OP_ANDN"]  = OpAndNot;
+    OpMap["OP_ORN"]   = OpOrNot;
+    OpMap["OP_CAST"]  = OpCast;
+    OpMap["OP_CONC"]  = OpConcat;
+    OpMap["OP_HI"]    = OpHi;
+    OpMap["OP_LO"]    = OpLo;
+    OpMap["OP_DUP"]   = OpDup;
+    OpMap["OP_DUP_LN"] = OpDupLane;
+    OpMap["OP_SEL"]   = OpSelect;
+    OpMap["OP_REV16"] = OpRev16;
+    OpMap["OP_REV32"] = OpRev32;
+    OpMap["OP_REV64"] = OpRev64;
+    OpMap["OP_REINT"] = OpReinterpret;
+    OpMap["OP_ABDL"]  = OpAbdl;
+    OpMap["OP_ABA"]   = OpAba;
+    OpMap["OP_ABAL"]  = OpAbal;
+
+    Record *SI = R.getClass("SInst");
+    Record *II = R.getClass("IInst");
+    Record *WI = R.getClass("WInst");
+    ClassMap[SI] = ClassS;
+    ClassMap[II] = ClassI;
+    ClassMap[WI] = ClassW;
+  }
+
+  // run - Emit arm_neon.h.inc
+  void run(raw_ostream &o);
+
+  // runHeader - Emit all the __builtin prototypes used in arm_neon.h
+  void runHeader(raw_ostream &o);
+
+  // runTests - Emit tests for all the Neon intrinsics.
+  void runTests(raw_ostream &o);
+
+private:
+  void emitIntrinsic(raw_ostream &OS, Record *R);
+};
+} // end anonymous namespace
+
 /// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,
 /// which each StringRef representing a single type declared in the string.
 /// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing
@@ -1576,3 +1766,14 @@
   }
 }
 
+namespace clang {
+void EmitNeon(RecordKeeper &Records, raw_ostream &OS) {
+  NeonEmitter(Records).run(OS);
+}
+void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
+  NeonEmitter(Records).runHeader(OS);
+}
+void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
+  NeonEmitter(Records).runTests(OS);
+}
+} // End namespace clang