Resurrect mcc16, it is useful as an example.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117198 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvmc/examples/mcc16/Hooks.cpp b/tools/llvmc/examples/mcc16/Hooks.cpp
new file mode 100644
index 0000000..edb91e1
--- /dev/null
+++ b/tools/llvmc/examples/mcc16/Hooks.cpp
@@ -0,0 +1,109 @@
+#include "llvm/System/Path.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <string>
+
+namespace llvmc {
+  extern char *ProgramName;
+
+  namespace autogenerated {
+    extern llvm::cl::opt<std::string> Parameter_p;
+  }
+}
+
+using namespace llvm;
+using namespace llvmc;
+
+// Returns the platform specific directory separator via #ifdefs.
+// FIXME: This currently work on linux and windows only. It does not
+// work on other unices.
+static std::string GetDirSeparator() {
+#if __linux__ || __APPLE__
+  return "/";
+#else
+  return "\\";
+#endif
+}
+
+namespace hooks {
+// Get preprocessor define for the part.
+// It is __partname format in lower case.
+std::string
+GetLowerCasePartDefine(void) {
+  std::string Partname;
+  if (autogenerated::Parameter_p.empty()) {
+    Partname = "16f1xxx";
+  } else {
+    Partname = autogenerated::Parameter_p;
+  }
+
+  std::string LowerCase;
+  for (unsigned i = 0; i < Partname.size(); i++) {
+    LowerCase.push_back(std::tolower(Partname[i]));
+  }
+
+  return "__" + LowerCase;
+}
+
+std::string
+GetUpperCasePartDefine(void) {
+  std::string Partname;
+  if (autogenerated::Parameter_p.empty()) {
+    Partname = "16f1xxx";
+  } else {
+    Partname = autogenerated::Parameter_p;
+  }
+
+  std::string UpperCase;
+  for (unsigned i = 0; i < Partname.size(); i++) {
+    UpperCase.push_back(std::toupper(Partname[i]));
+  }
+
+  return "__" +  UpperCase;
+}
+
+// Get the dir where c16 executables reside.
+std::string GetBinDir() {
+  // Construct a Path object from the program name.
+  void *P = (void*) (intptr_t) GetBinDir;
+  sys::Path ProgramFullPath
+    = sys::Path::GetMainExecutable(llvmc::ProgramName, P);
+
+  // Get the dir name for the program. It's last component should be 'bin'.
+  std::string BinDir = ProgramFullPath.getDirname();
+
+  // llvm::errs() << "BinDir: " << BinDir << '\n';
+  return BinDir + GetDirSeparator();
+}
+
+// Get the Top-level Installation dir for c16.
+std::string GetInstallDir() {
+  sys::Path BinDirPath = sys::Path(GetBinDir());
+
+  // Go one more level up to get the install dir.
+  std::string InstallDir  = BinDirPath.getDirname();
+
+  return InstallDir + GetDirSeparator();
+}
+
+// Get the dir where the c16 header files reside.
+std::string GetStdHeadersDir() {
+  return GetInstallDir() + "include";
+}
+
+// Get the dir where the assembler header files reside.
+std::string GetStdAsmHeadersDir() {
+  return GetInstallDir() + "inc";
+}
+
+// Get the dir where the linker scripts reside.
+std::string GetStdLinkerScriptsDir() {
+  return GetInstallDir() + "lkr";
+}
+
+// Get the dir where startup code, intrinsics and lib reside.
+std::string GetStdLibsDir() {
+  return GetInstallDir() + "lib";
+}
+}