forked from OSchip/llvm-project
mangle aarch64 Neon ACLE scalar instrinsic name with BHSD suffix.
llvm-svn: 189574
This commit is contained in:
parent
d4b9d068f0
commit
c076d0682b
|
@ -150,6 +150,7 @@ class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
|
||||||
// d: double
|
// d: double
|
||||||
|
|
||||||
// size modifiers:
|
// size modifiers:
|
||||||
|
// S: scalar, only used for function mangling.
|
||||||
// U: unsigned
|
// U: unsigned
|
||||||
// Q: 128b
|
// Q: 128b
|
||||||
// H: 128b without mangling 'q'
|
// H: 128b without mangling 'q'
|
||||||
|
|
|
@ -264,7 +264,7 @@ static void ParseTypes(Record *r, std::string &s,
|
||||||
|
|
||||||
for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
|
for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
|
||||||
if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U'
|
if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U'
|
||||||
|| data[len] == 'H')
|
|| data[len] == 'H' || data[len] == 'S')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (data[len]) {
|
switch (data[len]) {
|
||||||
|
@ -324,7 +324,10 @@ static char Narrow(const char t) {
|
||||||
/// the quad-vector, polynomial, or unsigned modifiers set.
|
/// the quad-vector, polynomial, or unsigned modifiers set.
|
||||||
static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
|
static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
|
||||||
unsigned off = 0;
|
unsigned off = 0;
|
||||||
|
// ignore scalar.
|
||||||
|
if (ty[off] == 'S') {
|
||||||
|
++off;
|
||||||
|
}
|
||||||
// remember quad.
|
// remember quad.
|
||||||
if (ty[off] == 'Q' || ty[off] == 'H') {
|
if (ty[off] == 'Q' || ty[off] == 'H') {
|
||||||
quad = true;
|
quad = true;
|
||||||
|
@ -689,9 +692,29 @@ static void InstructionTypeCode(const StringRef &typeStr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char Insert_BHSD_Suffix(StringRef typestr){
|
||||||
|
unsigned off = 0;
|
||||||
|
if(typestr[off++] == 'S'){
|
||||||
|
while(typestr[off] == 'Q' || typestr[off] == 'H'||
|
||||||
|
typestr[off] == 'P' || typestr[off] == 'U')
|
||||||
|
++off;
|
||||||
|
switch (typestr[off]){
|
||||||
|
default : break;
|
||||||
|
case 'c' : return 'b';
|
||||||
|
case 's' : return 'h';
|
||||||
|
case 'i' :
|
||||||
|
case 'f' : return 's';
|
||||||
|
case 'l' :
|
||||||
|
case 'd' : return 'd';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// MangleName - Append a type or width suffix to a base neon function name,
|
/// MangleName - Append a type or width suffix to a base neon function name,
|
||||||
/// and insert a 'q' in the appropriate location if type string starts with 'Q'.
|
/// and insert a 'q' in the appropriate location if type string starts with 'Q'.
|
||||||
/// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
|
/// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
|
||||||
|
/// Insert proper 'b' 'h' 's' 'd' if prefix 'S' is used.
|
||||||
static std::string MangleName(const std::string &name, StringRef typestr,
|
static std::string MangleName(const std::string &name, StringRef typestr,
|
||||||
ClassKind ck) {
|
ClassKind ck) {
|
||||||
if (name == "vcvt_f32_f16")
|
if (name == "vcvt_f32_f16")
|
||||||
|
@ -713,10 +736,15 @@ static std::string MangleName(const std::string &name, StringRef typestr,
|
||||||
|
|
||||||
// Insert a 'q' before the first '_' character so that it ends up before
|
// Insert a 'q' before the first '_' character so that it ends up before
|
||||||
// _lane or _n on vector-scalar operations.
|
// _lane or _n on vector-scalar operations.
|
||||||
if (typestr.startswith("Q")) {
|
if (typestr.find("Q") != StringRef::npos) {
|
||||||
size_t pos = s.find('_');
|
size_t pos = s.find('_');
|
||||||
s = s.insert(pos, "q");
|
s = s.insert(pos, "q");
|
||||||
}
|
}
|
||||||
|
char ins = Insert_BHSD_Suffix(typestr);
|
||||||
|
if(ins){
|
||||||
|
size_t pos = s.find('_');
|
||||||
|
s = s.insert(pos, &ins, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -2057,6 +2085,7 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
|
||||||
std::string name = R->getValueAsString("Name");
|
std::string name = R->getValueAsString("Name");
|
||||||
std::string Proto = R->getValueAsString("Prototype");
|
std::string Proto = R->getValueAsString("Prototype");
|
||||||
std::string Types = R->getValueAsString("Types");
|
std::string Types = R->getValueAsString("Types");
|
||||||
|
std::string Rename = name + "@" + Proto;
|
||||||
|
|
||||||
// Functions with 'a' (the splat code) in the type prototype should not get
|
// Functions with 'a' (the splat code) in the type prototype should not get
|
||||||
// their own builtin as they use the non-splat variant.
|
// their own builtin as they use the non-splat variant.
|
||||||
|
@ -2084,8 +2113,8 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
|
||||||
|
|
||||||
// Include ARM range checks in AArch64 but only if ARM intrinsics are not
|
// Include ARM range checks in AArch64 but only if ARM intrinsics are not
|
||||||
// redefined by AArch64 to handle new types.
|
// redefined by AArch64 to handle new types.
|
||||||
if (isA64RangeCheck && !isA64 && A64IntrinsicMap.count(name)) {
|
if (isA64RangeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
|
||||||
ClassKind &A64CK = A64IntrinsicMap[name];
|
ClassKind &A64CK = A64IntrinsicMap[Rename];
|
||||||
if (A64CK == ck && ck != ClassNone)
|
if (A64CK == ck && ck != ClassNone)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2186,7 +2215,8 @@ NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
|
||||||
std::string Proto = R->getValueAsString("Prototype");
|
std::string Proto = R->getValueAsString("Prototype");
|
||||||
std::string Types = R->getValueAsString("Types");
|
std::string Types = R->getValueAsString("Types");
|
||||||
std::string name = R->getValueAsString("Name");
|
std::string name = R->getValueAsString("Name");
|
||||||
|
std::string Rename = name + "@" + Proto;
|
||||||
|
|
||||||
// Functions with 'a' (the splat code) in the type prototype should not get
|
// Functions with 'a' (the splat code) in the type prototype should not get
|
||||||
// their own builtin as they use the non-splat variant.
|
// their own builtin as they use the non-splat variant.
|
||||||
if (Proto.find('a') != std::string::npos)
|
if (Proto.find('a') != std::string::npos)
|
||||||
|
@ -2212,8 +2242,8 @@ NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
|
||||||
// are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
|
// are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
|
||||||
// redefined in AArch64 to handle an additional 2 x f64 type.
|
// redefined in AArch64 to handle an additional 2 x f64 type.
|
||||||
ClassKind ck = ClassMap[R->getSuperClasses()[1]];
|
ClassKind ck = ClassMap[R->getSuperClasses()[1]];
|
||||||
if (isA64TypeCheck && !isA64 && A64IntrinsicMap.count(name)) {
|
if (isA64TypeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
|
||||||
ClassKind &A64CK = A64IntrinsicMap[name];
|
ClassKind &A64CK = A64IntrinsicMap[Rename];
|
||||||
if (A64CK == ck && ck != ClassNone)
|
if (A64CK == ck && ck != ClassNone)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2316,6 +2346,7 @@ void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
|
||||||
|
|
||||||
std::string Proto = R->getValueAsString("Prototype");
|
std::string Proto = R->getValueAsString("Prototype");
|
||||||
std::string name = R->getValueAsString("Name");
|
std::string name = R->getValueAsString("Name");
|
||||||
|
std::string Rename = name + "@" + Proto;
|
||||||
|
|
||||||
// Functions with 'a' (the splat code) in the type prototype should not get
|
// Functions with 'a' (the splat code) in the type prototype should not get
|
||||||
// their own builtin as they use the non-splat variant.
|
// their own builtin as they use the non-splat variant.
|
||||||
|
@ -2340,8 +2371,8 @@ void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
|
||||||
// Include ARM BUILTIN() macros in AArch64 but only if ARM intrinsics
|
// Include ARM BUILTIN() macros in AArch64 but only if ARM intrinsics
|
||||||
// are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
|
// are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
|
||||||
// redefined in AArch64 to handle an additional 2 x f64 type.
|
// redefined in AArch64 to handle an additional 2 x f64 type.
|
||||||
if (isA64GenBuiltinDef && !isA64 && A64IntrinsicMap.count(name)) {
|
if (isA64GenBuiltinDef && !isA64 && A64IntrinsicMap.count(Rename)) {
|
||||||
ClassKind &A64CK = A64IntrinsicMap[name];
|
ClassKind &A64CK = A64IntrinsicMap[Rename];
|
||||||
if (A64CK == ck && ck != ClassNone)
|
if (A64CK == ck && ck != ClassNone)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2382,9 +2413,11 @@ void NeonEmitter::runHeader(raw_ostream &OS) {
|
||||||
CK = ClassMap[R->getSuperClasses()[1]];
|
CK = ClassMap[R->getSuperClasses()[1]];
|
||||||
|
|
||||||
std::string Name = R->getValueAsString("Name");
|
std::string Name = R->getValueAsString("Name");
|
||||||
if (A64IntrinsicMap.count(Name))
|
std::string Proto = R->getValueAsString("Prototype");
|
||||||
|
std::string Rename = Name + "@" + Proto;
|
||||||
|
if (A64IntrinsicMap.count(Rename))
|
||||||
continue;
|
continue;
|
||||||
A64IntrinsicMap[Name] = CK;
|
A64IntrinsicMap[Rename] = CK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate BuiltinsARM.def for ARM
|
// Generate BuiltinsARM.def for ARM
|
||||||
|
|
Loading…
Reference in New Issue