summaryrefslogtreecommitdiff
path: root/utils/TableGen/NeonEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/NeonEmitter.cpp')
-rw-r--r--utils/TableGen/NeonEmitter.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index eca03a5892e22..f92110d5d7acc 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -494,6 +494,7 @@ private:
std::pair<Type, std::string> emitDagSaveTemp(DagInit *DI);
std::pair<Type, std::string> emitDagSplat(DagInit *DI);
std::pair<Type, std::string> emitDagDup(DagInit *DI);
+ std::pair<Type, std::string> emitDagDupTyped(DagInit *DI);
std::pair<Type, std::string> emitDagShuffle(DagInit *DI);
std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast);
std::pair<Type, std::string> emitDagCall(DagInit *DI);
@@ -897,6 +898,18 @@ void Type::applyModifier(char Mod) {
Float = true;
ElementBitwidth = 16;
break;
+ case '0':
+ Float = true;
+ if (AppliedQuad)
+ Bitwidth /= 2;
+ ElementBitwidth = 16;
+ break;
+ case '1':
+ Float = true;
+ if (!AppliedQuad)
+ Bitwidth *= 2;
+ ElementBitwidth = 16;
+ break;
case 'g':
if (AppliedQuad)
Bitwidth /= 2;
@@ -1507,6 +1520,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) {
return emitDagShuffle(DI);
if (Op == "dup")
return emitDagDup(DI);
+ if (Op == "dup_typed")
+ return emitDagDupTyped(DI);
if (Op == "splat")
return emitDagSplat(DI);
if (Op == "save_temp")
@@ -1771,6 +1786,28 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
return std::make_pair(T, S);
}
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDupTyped(DagInit *DI) {
+ assert_with_loc(DI->getNumArgs() == 2, "dup_typed() expects two arguments");
+ std::pair<Type, std::string> A = emitDagArg(DI->getArg(0),
+ DI->getArgNameStr(0));
+ std::pair<Type, std::string> B = emitDagArg(DI->getArg(1),
+ DI->getArgNameStr(1));
+ assert_with_loc(B.first.isScalar(),
+ "dup_typed() requires a scalar as the second argument");
+
+ Type T = A.first;
+ assert_with_loc(T.isVector(), "dup_typed() used but target type is scalar!");
+ std::string S = "(" + T.str() + ") {";
+ for (unsigned I = 0; I < T.getNumElements(); ++I) {
+ if (I != 0)
+ S += ", ";
+ S += B.second;
+ }
+ S += "}";
+
+ return std::make_pair(T, S);
+}
+
std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) {
assert_with_loc(DI->getNumArgs() == 2, "splat() expects two arguments");
std::pair<Type, std::string> A = emitDagArg(DI->getArg(0),
@@ -2020,7 +2057,7 @@ void NeonEmitter::createIntrinsic(Record *R,
}
}
- llvm::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+ llvm::sort(NewTypeSpecs);
NewTypeSpecs.erase(std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end()),
NewTypeSpecs.end());
auto &Entry = IntrinsicMap[Name];
@@ -2409,7 +2446,7 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "#endif\n";
OS << "\n";
- OS << "#define __ai static inline __attribute__((__always_inline__, "
+ OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
"__nodebug__))\n\n";
SmallVector<Intrinsic *, 128> Defs;
@@ -2518,7 +2555,7 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
OS << "typedef __fp16 float16_t;\n";
- OS << "#define __ai static inline __attribute__((__always_inline__, "
+ OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
"__nodebug__))\n\n";
SmallVector<Intrinsic *, 128> Defs;