mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
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
This commit is contained in:
parent
b304ba94db
commit
a8979a0e7b
@ -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) {
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user