aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-12-02 07:10:39 +0000
committerBob Wilson <bob.wilson@apple.com>2010-12-02 07:10:39 +0000
commit377296e301c12ef551d7089ef68df48a300fb8b7 (patch)
tree175915eb48d55bd9cd7e710fa0b4b8bdc0cbd86c /utils
parente23930543c0de0adcfec00cd18e9243ad812a167 (diff)
downloadexternal_llvm-377296e301c12ef551d7089ef68df48a300fb8b7.zip
external_llvm-377296e301c12ef551d7089ef68df48a300fb8b7.tar.gz
external_llvm-377296e301c12ef551d7089ef68df48a300fb8b7.tar.bz2
Assign arguments of Neon intrinsic macros to local temporaries.
Since we're casting them for the calls to the builtins, we need this to make sure their types get checked in the same way they would if the intrinsics were implemented as inline functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120693 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/NeonEmitter.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 41c55fa..d45910e 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -481,6 +481,28 @@ static std::string GenArgs(const std::string &proto, StringRef typestr) {
return s;
}
+// Generate the local temporaries used to provide type checking for macro
+// arguments.
+static std::string GenMacroLocals(const std::string &proto, StringRef typestr) {
+ char arg = 'a';
+ std::string s;
+
+ for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
+ // Do not create a temporary for an immediate argument.
+ // That would defeat the whole point of using a macro!
+ if (proto[i] == 'i') continue;
+
+ s += TypeString(proto[i], typestr) + " __";
+ s.push_back(arg);
+ s += " = (";
+ s.push_back(arg);
+ s += "); ";
+ }
+
+ s += "\\\n ";
+ return s;
+}
+
static std::string Duplicate(unsigned nElts, StringRef typestr,
const std::string &a) {
std::string s;
@@ -706,7 +728,6 @@ static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
static std::string GenBuiltin(const std::string &name, const std::string &proto,
StringRef typestr, ClassKind ck) {
- char arg = 'a';
std::string s;
// If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
@@ -724,6 +745,11 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
if (proto.find('s') == std::string::npos)
ck = ClassB;
+ // Macro arguments are not type-checked like inline function arguments, so
+ // assign them to local temporaries to get the right type checking.
+ if (define)
+ s += GenMacroLocals(proto, typestr);
+
if (proto[0] != 'v') {
std::string ts = TypeString(proto[0], typestr);
@@ -756,12 +782,13 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
if (sret)
s += "&r, ";
+ char arg = 'a';
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
std::string args = std::string(&arg, 1);
- // Wrap macro arguments in parenthesis.
- if (define)
- args = "(" + args + ")";
+ // For macros, use the local temporaries instead of the macro arguments.
+ if (define && proto[i] != 'i')
+ args = "__" + args;
bool argQuad = false;
bool argPoly = false;