BuiltinsARM.def emitter, still needs a substantial bit of tweaking to lighten the load on clang.

llvm-svn: 105456
This commit is contained in:
Nate Begeman 2010-06-04 01:26:15 +00:00
parent 4e5e6a8973
commit 1ca8dba557
3 changed files with 119 additions and 71 deletions

View File

@ -14,46 +14,13 @@
//===----------------------------------------------------------------------===//
#include "NeonEmitter.h"
#include "Record.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 <string>
using namespace llvm;
enum OpKind {
OpNone,
OpAdd,
OpSub,
OpMul,
OpMla,
OpMls,
OpEq,
OpGe,
OpLe,
OpGt,
OpLt,
OpNeg,
OpNot,
OpAnd,
OpOr,
OpXor,
OpAndNot,
OpOrNot,
OpCast
};
enum ClassKind {
ClassNone,
ClassI,
ClassS,
ClassW,
ClassB
};
static void ParseTypes(Record *r, std::string &s,
SmallVectorImpl<StringRef> &TV) {
const char *data = s.data();
@ -483,6 +450,20 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
return s;
}
static std::string GenBuiltinDef(const std::string &name,
const std::string &proto,
StringRef typestr, ClassKind ck) {
std::string s("BUILTIN(__builtin_neon_");
s += MangleName(name, typestr, ck);
s += ", \"";
for (unsigned i = 0, e = proto.size(); i != e; ++i) {
}
s += "\", \"n\")";
return s;
}
void NeonEmitter::run(raw_ostream &OS) {
EmitSourceFileHeader("ARM NEON Header", OS);
@ -539,37 +520,6 @@ void NeonEmitter::run(raw_ostream &OS) {
std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
StringMap<OpKind> OpMap;
OpMap["OP_NONE"] = OpNone;
OpMap["OP_ADD"] = OpAdd;
OpMap["OP_SUB"] = OpSub;
OpMap["OP_MUL"] = OpMul;
OpMap["OP_MLA"] = OpMla;
OpMap["OP_MLS"] = OpMls;
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;
DenseMap<Record*, ClassKind> ClassMap;
Record *SI = Records.getClass("SInst");
Record *II = Records.getClass("IInst");
Record *WI = Records.getClass("WInst");
Record *BI = Records.getClass("BInst");
ClassMap[SI] = ClassS;
ClassMap[II] = ClassI;
ClassMap[WI] = ClassW;
ClassMap[BI] = ClassB;
// Unique the return+pattern types, and assign them.
for (unsigned i = 0, e = RV.size(); i != e; ++i) {
Record *R = RV[i];
@ -614,14 +564,41 @@ void NeonEmitter::run(raw_ostream &OS) {
}
OS << "\n";
}
// TODO:
// Unique the return+pattern types, and assign them to each record
// Emit a #define for each unique "type" of intrinsic declaring all variants.
// Emit a #define for each intrinsic mapping it to a particular type.
OS << "#undef __ai\n\n";
OS << "#endif /* __ARM_NEON_H */\n";
}
void NeonEmitter::runHeader(raw_ostream &OS) {
std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
StringMap<OpKind> EmittedMap;
for (unsigned i = 0, e = RV.size(); i != e; ++i) {
Record *R = RV[i];
OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
if (k != OpNone)
continue;
std::string name = LowercaseString(R->getName());
std::string Proto = R->getValueAsString("Prototype");
std::string Types = R->getValueAsString("Types");
SmallVector<StringRef, 16> TypeVec;
ParseTypes(R, Types, TypeVec);
if (R->getSuperClasses().size() < 2)
throw TGError(R->getLoc(), "Builtin has no class kind");
ClassKind ck = ClassMap[R->getSuperClasses()[1]];
for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
if (EmittedMap.count(bd))
continue;
EmittedMap[bd] = OpNone;
OS << bd << "\n";
}
}
}

View File

@ -16,14 +16,79 @@
#ifndef NEON_EMITTER_H
#define NEON_EMITTER_H
#include "Record.h"
#include "TableGenBackend.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
enum OpKind {
OpNone,
OpAdd,
OpSub,
OpMul,
OpMla,
OpMls,
OpEq,
OpGe,
OpLe,
OpGt,
OpLt,
OpNeg,
OpNot,
OpAnd,
OpOr,
OpXor,
OpAndNot,
OpOrNot,
OpCast
};
enum ClassKind {
ClassNone,
ClassI,
ClassS,
ClassW,
ClassB
};
namespace llvm {
class NeonEmitter : public TableGenBackend {
RecordKeeper &Records;
StringMap<OpKind> OpMap;
DenseMap<Record*, ClassKind> ClassMap;
public:
NeonEmitter(RecordKeeper &R) : Records(R) {}
NeonEmitter(RecordKeeper &R) : Records(R) {
OpMap["OP_NONE"] = OpNone;
OpMap["OP_ADD"] = OpAdd;
OpMap["OP_SUB"] = OpSub;
OpMap["OP_MUL"] = OpMul;
OpMap["OP_MLA"] = OpMla;
OpMap["OP_MLS"] = OpMls;
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;
Record *SI = R.getClass("SInst");
Record *II = R.getClass("IInst");
Record *WI = R.getClass("WInst");
Record *BI = R.getClass("BInst");
ClassMap[SI] = ClassS;
ClassMap[II] = ClassI;
ClassMap[WI] = ClassW;
ClassMap[BI] = ClassB;
}
// run - Emit arm_neon.h.inc
void run(raw_ostream &o);

View File

@ -66,6 +66,7 @@ enum ActionType {
GenLLVMCConf,
GenEDHeader, GenEDInfo,
GenNeonHeader,
GenNeonBuiltinsDef,
PrintEnums
};
@ -126,6 +127,8 @@ namespace {
"Generate enhanced disassembly info"),
clEnumValN(GenNeonHeader, "gen-arm-neon-header",
"Generate arm_neon.h for clang"),
clEnumValN(GenNeonBuiltinsDef, "gen-arm-neon-builtins-def",
"Generate NEON BuiltinsARM.def for clang"),
clEnumValN(PrintEnums, "print-enums",
"Print enum values for a class"),
clEnumValEnd));
@ -294,6 +297,9 @@ int main(int argc, char **argv) {
case GenNeonHeader:
NeonEmitter(Records).run(Out);
break;
case GenNeonBuiltinsDef:
NeonEmitter(Records).runHeader(Out);
break;
case PrintEnums:
{
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);