aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2010-06-04 00:21:41 +0000
committerNate Begeman <natebegeman@mac.com>2010-06-04 00:21:41 +0000
commita8979a0e7b76273171e8592c5ca08bb6113923a5 (patch)
treeb21a1d202c699c6a62f2150008d65b4e6ece0a8c /utils/TableGen
parentb304ba94db047cc57eeb7657f641d03db95a35b6 (diff)
downloadexternal_llvm-a8979a0e7b76273171e8592c5ca08bb6113923a5.zip
external_llvm-a8979a0e7b76273171e8592c5ca08bb6113923a5.tar.gz
external_llvm-a8979a0e7b76273171e8592c5ca08bb6113923a5.tar.bz2
Mangle __builtin_neon_* names appropriately.
Add skeleton of support for emitting the list of prototypes for BuiltinsARM.def git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105443 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/NeonEmitter.cpp122
-rw-r--r--utils/TableGen/NeonEmitter.h5
2 files changed, 97 insertions, 30 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 90df782..43b7591 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -15,6 +15,7 @@
#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"
@@ -45,6 +46,14 @@ enum OpKind {
OpCast
};
+enum ClassKind {
+ ClassNone,
+ ClassI,
+ ClassS,
+ ClassW,
+ ClassB
+};
+
static void ParseTypes(Record *r, std::string &s,
SmallVectorImpl<StringRef> &TV) {
const char *data = s.data();
@@ -259,7 +268,8 @@ static std::string TypeString(const char mod, StringRef typestr) {
}
// Turn "vst2_lane" into "vst2q_lane_f32", etc.
-static std::string MangleName(const std::string &name, StringRef typestr) {
+static std::string MangleName(const std::string &name, StringRef typestr,
+ ClassKind ck) {
bool quad = false;
bool poly = false;
bool usgn = false;
@@ -268,29 +278,61 @@ static std::string MangleName(const std::string &name, StringRef typestr) {
std::string s = name;
switch (type) {
- case 'c':
- s += poly ? "_p8" : usgn ? "_u8" : "_s8";
- break;
- case 's':
- s += poly ? "_p16" : usgn ? "_u16" : "_s16";
- break;
- case 'i':
- s += usgn ? "_u32" : "_s32";
- break;
- case 'l':
- s += usgn ? "_u64" : "_s64";
- break;
- case 'h':
- s += "_f16";
- break;
- case 'f':
- s += "_f32";
- break;
- default:
- throw "unhandled type!";
- break;
+ case 'c':
+ switch (ck) {
+ case ClassS: s += poly ? "_p8" : usgn ? "_u8" : "_s8"; break;
+ case ClassI: s += "_i8"; break;
+ case ClassW: s += "_8"; break;
+ default: break;
+ }
+ break;
+ case 's':
+ switch (ck) {
+ case ClassS: s += poly ? "_p16" : usgn ? "_u16" : "_s16"; break;
+ case ClassI: s += "_i16"; break;
+ case ClassW: s += "_16"; break;
+ default: break;
+ }
+ break;
+ case 'i':
+ switch (ck) {
+ case ClassS: s += usgn ? "_u32" : "_s32"; break;
+ case ClassI: s += "_i32"; break;
+ case ClassW: s += "_32"; break;
+ default: break;
+ }
+ break;
+ case 'l':
+ switch (ck) {
+ case ClassS: s += usgn ? "_u64" : "_s64"; break;
+ case ClassI: s += "_i64"; break;
+ case ClassW: s += "_64"; break;
+ default: break;
+ }
+ break;
+ case 'h':
+ switch (ck) {
+ case ClassS:
+ case ClassI: s += "_f16"; break;
+ case ClassW: s += "_16"; break;
+ default: break;
+ }
+ break;
+ case 'f':
+ switch (ck) {
+ case ClassS:
+ case ClassI: s += "_f32"; break;
+ case ClassW: s += "_32"; break;
+ default: break;
+ }
+ break;
+ default:
+ throw "unhandled type!";
+ break;
}
-
+ if (ck == ClassB)
+ return s += "_v";
+
// Insert a 'q' before the first '_' character so that it ends up before
// _lane or _n on vector-scalar operations.
if (quad) {
@@ -405,7 +447,8 @@ static std::string GenOpString(OpKind op, const std::string &proto,
// If structTypes is true, the NEON types are structs of vector types rather
// than vector types, and the call becomes __builtin_neon_cls(a.val)
static std::string GenBuiltin(const std::string &name, const std::string &proto,
- StringRef typestr, bool structTypes = true) {
+ StringRef typestr, ClassKind ck,
+ bool structTypes = true) {
char arg = 'a';
std::string s;
@@ -420,7 +463,7 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
}
s += "__builtin_neon_";
- s += name;
+ s += MangleName(name, typestr, ck);
s += "(";
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
@@ -517,6 +560,16 @@ void NeonEmitter::run(raw_ostream &OS) {
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];
@@ -536,7 +589,7 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
// Function name with type suffix
- OS << " " << MangleName(name, TypeVec[ti]);
+ OS << " " << MangleName(name, TypeVec[ti], ClassS);
// Function arguments
OS << GenArgs(Proto, TypeVec[ti]);
@@ -544,10 +597,18 @@ void NeonEmitter::run(raw_ostream &OS) {
// Definition.
OS << " { ";
- if (k != OpNone)
+ if (k != OpNone) {
OS << GenOpString(k, Proto, TypeVec[ti]);
- else
- OS << GenBuiltin(name, Proto, TypeVec[ti]);
+ } else {
+ if (R->getSuperClasses().size() < 2)
+ throw TGError(R->getLoc(), "Builtin has no class kind");
+
+ ClassKind ck = ClassMap[R->getSuperClasses()[1]];
+
+ if (ck == ClassNone)
+ throw TGError(R->getLoc(), "Builtin has no class kind");
+ OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
+ }
OS << " }\n";
}
@@ -561,3 +622,6 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "#endif /* __ARM_NEON_H */\n";
}
+
+void NeonEmitter::runHeader(raw_ostream &OS) {
+}
diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h
index dc20794..133531d 100644
--- a/utils/TableGen/NeonEmitter.h
+++ b/utils/TableGen/NeonEmitter.h
@@ -25,8 +25,11 @@ namespace llvm {
public:
NeonEmitter(RecordKeeper &R) : Records(R) {}
- // runHeader - Emit a header file that allows use of the instruction table.
+ // run - Emit arm_neon.h.inc
void run(raw_ostream &o);
+
+ // runHeader - Emit all the __builtin prototypes used in arm_neon.h
+ void runHeader(raw_ostream &o);
};
} // End llvm namespace