X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FIntrinsicEmitter.cpp;h=155d1abea33182c9fcf07c0bdd33a4af7e6e7703;hb=6f36fa981a59461466e12e5056ba209d289b81b1;hp=748573e367d3c3f65d642a49a4532e907ff47336;hpb=20aedcdfa35f4b6494d4990cf6dd4459d7172c49;p=oota-llvm.git diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 748573e367d..155d1abea33 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -11,24 +11,62 @@ // //===----------------------------------------------------------------------===// +#include "CodeGenIntrinsics.h" #include "CodeGenTarget.h" -#include "IntrinsicEmitter.h" #include "SequenceToOffsetTable.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/TableGenBackend.h" #include using namespace llvm; +namespace { +class IntrinsicEmitter { + RecordKeeper &Records; + bool TargetOnly; + std::string TargetPrefix; + +public: + IntrinsicEmitter(RecordKeeper &R, bool T) + : Records(R), TargetOnly(T) {} + + void run(raw_ostream &OS); + + void EmitPrefix(raw_ostream &OS); + + void EmitEnumInfo(const std::vector &Ints, + raw_ostream &OS); + + void EmitFnNameRecognizer(const std::vector &Ints, + raw_ostream &OS); + void EmitIntrinsicToNameTable(const std::vector &Ints, + raw_ostream &OS); + void EmitIntrinsicToOverloadTable(const std::vector &Ints, + raw_ostream &OS); + void EmitVerifier(const std::vector &Ints, + raw_ostream &OS); + void EmitGenerator(const std::vector &Ints, + raw_ostream &OS); + void EmitAttributes(const std::vector &Ints, + raw_ostream &OS); + void EmitModRefBehavior(const std::vector &Ints, + raw_ostream &OS); + void EmitIntrinsicToGCCBuiltinMap(const std::vector &Ints, + raw_ostream &OS); + void EmitSuffix(raw_ostream &OS); +}; +} // End anonymous namespace + //===----------------------------------------------------------------------===// // IntrinsicEmitter Implementation //===----------------------------------------------------------------------===// void IntrinsicEmitter::run(raw_ostream &OS) { - EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); - + emitSourceFileHeader("Intrinsic Function Source Fragment", OS); + std::vector Ints = LoadIntrinsics(Records, TargetOnly); - + if (TargetOnly && !Ints.empty()) TargetPrefix = Ints[0].TargetPrefix; @@ -338,7 +376,7 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int, EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig); } -void printIITEntry(raw_ostream &OS, unsigned char X) { +static void printIITEntry(raw_ostream &OS, unsigned char X) { OS << (unsigned)X; } @@ -424,48 +462,48 @@ void IntrinsicEmitter::EmitGenerator(const std::vector &Ints, OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL } -namespace { - enum ModRefKind { - MRK_none, - MRK_readonly, - MRK_readnone - }; - - ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { - switch (intrinsic.ModRef) { - case CodeGenIntrinsic::NoMem: - return MRK_readnone; - case CodeGenIntrinsic::ReadArgMem: - case CodeGenIntrinsic::ReadMem: - return MRK_readonly; - case CodeGenIntrinsic::ReadWriteArgMem: - case CodeGenIntrinsic::ReadWriteMem: - return MRK_none; - } - llvm_unreachable("bad mod-ref kind"); - } - - struct AttributeComparator { - bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { - // Sort throwing intrinsics after non-throwing intrinsics. - if (L->canThrow != R->canThrow) - return R->canThrow; - - if (L->isNoReturn != R->isNoReturn) - return R->isNoReturn; - - // Try to order by readonly/readnone attribute. - ModRefKind LK = getModRefKind(*L); - ModRefKind RK = getModRefKind(*R); - if (LK != RK) return (LK > RK); +enum ModRefKind { + MRK_none, + MRK_readonly, + MRK_readnone +}; - // Order by argument attributes. - // This is reliable because each side is already sorted internally. - return (L->ArgumentAttributes < R->ArgumentAttributes); - } - }; +static ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { + switch (intrinsic.ModRef) { + case CodeGenIntrinsic::NoMem: + return MRK_readnone; + case CodeGenIntrinsic::ReadArgMem: + case CodeGenIntrinsic::ReadMem: + return MRK_readonly; + case CodeGenIntrinsic::ReadWriteArgMem: + case CodeGenIntrinsic::ReadWriteMem: + return MRK_none; + } + llvm_unreachable("bad mod-ref kind"); } +namespace { +struct AttributeComparator { + bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { + // Sort throwing intrinsics after non-throwing intrinsics. + if (L->canThrow != R->canThrow) + return R->canThrow; + + if (L->isNoReturn != R->isNoReturn) + return R->isNoReturn; + + // Try to order by readonly/readnone attribute. + ModRefKind LK = getModRefKind(*L); + ModRefKind RK = getModRefKind(*R); + if (LK != RK) return (LK > RK); + + // Order by argument attributes. + // This is reliable because each side is already sorted internally. + return (L->ArgumentAttributes < R->ArgumentAttributes); + } +}; +} // End anonymous namespace + /// EmitAttributes - This emits the Intrinsic::getAttributes method. void IntrinsicEmitter:: EmitAttributes(const std::vector &Ints, raw_ostream &OS) { @@ -705,3 +743,11 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector &Ints, OS << "}\n"; OS << "#endif\n\n"; } + +namespace llvm { + +void EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly = false) { + IntrinsicEmitter(RK, TargetOnly).run(OS); +} + +} // End llvm namespace