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