IntrinsicEmitter.cpp revision 9b843b249462980ae4630dc37d1bcccde884a5a7
19e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
29e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//
39e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//                     The LLVM Compiler Infrastructure
49e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//
59e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// This file was developed by Chris Lattner and is distributed under
69e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
79e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//
89e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
99e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//
109e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// This tablegen backend emits information about intrinsic functions.
119e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//
129e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
139e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
149e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner#include "IntrinsicEmitter.h"
159e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner#include "Record.h"
169e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnerusing namespace llvm;
179e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
189e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
199e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// CodeGenIntrinsic Implementation
209e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
219e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
229e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnerstd::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
239e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
249e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  return std::vector<CodeGenIntrinsic>(I.begin(), I.end());
259e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner}
269e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
279e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris LattnerCodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
289e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  std::string DefName = R->getName();
299e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
309e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  if (DefName.size() <= 4 ||
319e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      std::string(DefName.begin(), DefName.begin()+4) != "int_")
329e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    throw "Intrinsic '" + DefName + "' does not start with 'int_'!";
339e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  EnumName = std::string(DefName.begin()+4, DefName.end());
349e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
359e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  Name = R->getValueAsString("LLVMName");
369e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  if (Name == "") {
379e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    // If an explicit name isn't specified, derive one from the DefName.
389e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    Name = "llvm.";
399e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
409e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      if (EnumName[i] == '_')
419e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner        Name += '.';
429e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      else
439e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner        Name += EnumName[i];
449e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  }
459e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner}
469e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
479e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
489e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// IntrinsicEmitter Implementation
499e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===//
509e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
519e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnervoid IntrinsicEmitter::run(std::ostream &OS) {
529e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
539e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
549e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records);
559e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
569e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  // Emit the enum information.
579e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  EmitEnumInfo(Ints, OS);
589b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner
599b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  // Emit the function name recognizer.
609b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  EmitFnNameRecognizer(Ints, OS);
619e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner}
629e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner
639e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnervoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
649e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner                                    std::ostream &OS) {
659b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "// Enum values for Intrinsics.h\n";
669e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
679e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
689e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    OS << "    " << Ints[i].EnumName;
699e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    OS << ((i != e-1) ? ", " : "  ");
709e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    OS << std::string(40-Ints[i].EnumName.size(), ' ')
719e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      << "// " << Ints[i].Name << "\n";
729e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  }
739e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  OS << "#endif\n\n";
749e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner}
759b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner
769b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattnervoid IntrinsicEmitter::
779b843b249462980ae4630dc37d1bcccde884a5a7Chris LattnerEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
789b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner                     std::ostream &OS) {
799b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  // Build a function name -> intrinsic name mapping.
809b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  std::map<std::string, std::string> IntMapping;
819b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
829b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner    IntMapping[Ints[i].Name] = Ints[i].EnumName;
839b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner
849b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "// Function name -> enum value recognizer code.\n";
859b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
869b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "  switch (Name[5]) {\n";
879b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "  // The 'llvm.' namespace is reserved!\n";
889b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "  default: assert(0 && \"Unknown LLVM intrinsic function!\");\n";
899b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  // Emit the intrinsics in sorted order.
909b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  char LastChar = 0;
919b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  for (std::map<std::string, std::string>::iterator I = IntMapping.begin(),
929b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner       E = IntMapping.end(); I != E; ++I) {
939b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner    assert(I->first.size() > 5 && std::string(I->first.begin(),
949b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner                                              I->first.begin()+5) == "llvm." &&
959b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner           "Invalid intrinsic name!");
969b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner    if (I->first[5] != LastChar) {
979b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner      LastChar = I->first[5];
989b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner      OS << "  case '" << LastChar << "':\n";
999b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner    }
1009b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner
1019b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner    OS << "    if (Name == \"" << I->first << "\") return Intrinsic::"
1029b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner       << I->second << ";\n";
1039b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  }
1049b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "  }\n";
1059b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner  OS << "#endif\n";
1069b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner}
1079b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner
108