summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2010-06-12 03:09:49 +0000
committerNate Begeman <natebegeman@mac.com>2010-06-12 03:09:49 +0000
commitcc3c41a9c396d60709724c487d258eeafdeb4f28 (patch)
tree0bbff12aaf32cf138f7956e4d8fd0369a6561f24 /utils
parent11ae95c175fbbee3e38d6ddb8b9f39f88fe8988b (diff)
downloadllvm-cc3c41a9c396d60709724c487d258eeafdeb4f28.tar.gz
llvm-cc3c41a9c396d60709724c487d258eeafdeb4f28.tar.bz2
llvm-cc3c41a9c396d60709724c487d258eeafdeb4f28.tar.xz
Add generic vector support for bitselect & element byteswap
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105874 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/NeonEmitter.cpp96
-rw-r--r--utils/TableGen/NeonEmitter.h10
2 files changed, 75 insertions, 31 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 9153ac8377..3c7a9fee00 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -443,20 +443,8 @@ static std::string GenArgs(const std::string &proto, StringRef typestr) {
return s;
}
-static std::string Duplicate(StringRef typestr, const std::string &a) {
- bool dummy, quad = false;
- char type = ClassifyType(typestr, quad, dummy, dummy);
- unsigned nElts = 0;
- switch (type) {
- case 'c': nElts = 8; break;
- case 's': nElts = 4; break;
- case 'i': nElts = 2; break;
- case 'l': nElts = 1; break;
- case 'h': nElts = 4; break;
- case 'f': nElts = 2; break;
- }
- nElts <<= quad;
-
+static std::string Duplicate(unsigned nElts, StringRef typestr,
+ const std::string &a) {
std::string s;
s = "(__neon_" + TypeString('d', typestr) + "){ ";
@@ -475,6 +463,18 @@ static std::string Duplicate(StringRef typestr, const std::string &a) {
// than vector types, and the call becomes "a.val + b.val"
static std::string GenOpString(OpKind op, const std::string &proto,
StringRef typestr, bool structTypes = true) {
+ bool dummy, quad = false;
+ char type = ClassifyType(typestr, quad, dummy, dummy);
+ unsigned nElts = 0;
+ switch (type) {
+ case 'c': nElts = 8; break;
+ case 's': nElts = 4; break;
+ case 'i': nElts = 2; break;
+ case 'l': nElts = 1; break;
+ case 'h': nElts = 4; break;
+ case 'f': nElts = 2; break;
+ }
+
std::string ts = TypeString(proto[0], typestr);
std::string s = ts + " r; r";
@@ -497,17 +497,17 @@ static std::string GenOpString(OpKind op, const std::string &proto,
s += a + " - " + b;
break;
case OpMulN:
- b = Duplicate(typestr, "b");
+ b = Duplicate(nElts << quad, typestr, "b");
case OpMul:
s += a + " * " + b;
break;
case OpMlaN:
- c = Duplicate(typestr, "c");
+ c = Duplicate(nElts << quad, typestr, "c");
case OpMla:
s += a + " + ( " + b + " * " + c + " )";
break;
case OpMlsN:
- c = Duplicate(typestr, "c");
+ c = Duplicate(nElts << quad, typestr, "c");
case OpMls:
s += a + " - ( " + b + " * " + c + " )";
break;
@@ -561,7 +561,35 @@ static std::string GenOpString(OpKind op, const std::string &proto,
s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[0])";
break;
case OpDup:
- s += Duplicate(typestr, a);
+ s += Duplicate(nElts << quad, typestr, a);
+ break;
+ case OpSelect:
+ // ((0 & 1) | (~0 & 2))
+ ts = TypeString(proto[1], typestr);
+ s += "( " + a + " & (__neon_" + ts + ")" + b + ") | ";
+ s += "(~" + a + " & (__neon_" + ts + ")" + c + ")";
+ break;
+ case OpRev16:
+ s += "__builtin_shufflevector(" + a + ", " + a;
+ for (unsigned i = 2; i <= nElts << quad; i += 2)
+ for (unsigned j = 0; j != 2; ++j)
+ s += ", " + utostr(i - j - 1);
+ s += ")";
+ break;
+ case OpRev32:
+ nElts >>= 1;
+ s += "__builtin_shufflevector(" + a + ", " + a;
+ for (unsigned i = nElts; i <= nElts << (1 + quad); i += nElts)
+ for (unsigned j = 0; j != nElts; ++j)
+ s += ", " + utostr(i - j - 1);
+ s += ")";
+ break;
+ case OpRev64:
+ s += "__builtin_shufflevector(" + a + ", " + a;
+ for (unsigned i = nElts; i <= nElts << quad; i += nElts)
+ for (unsigned j = 0; j != nElts; ++j)
+ s += ", " + utostr(i - j - 1);
+ s += ")";
break;
default:
throw "unknown OpKind!";
@@ -630,6 +658,19 @@ static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
static std::string GenBuiltin(const std::string &name, const std::string &proto,
StringRef typestr, ClassKind ck,
bool structTypes = true) {
+ bool dummy, quad = false;
+ char type = ClassifyType(typestr, quad, dummy, dummy);
+ unsigned nElts = 0;
+ switch (type) {
+ case 'c': nElts = 8; break;
+ case 's': nElts = 4; break;
+ case 'i': nElts = 2; break;
+ case 'l': nElts = 1; break;
+ case 'h': nElts = 4; break;
+ case 'f': nElts = 2; break;
+ }
+ nElts <<= quad;
+
char arg = 'a';
std::string s;
@@ -678,12 +719,15 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
s += "(";
for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
+ std::string args = std::string(&arg, 1);
+ if (define)
+ args = "(" + args + ")";
+
// Handle multiple-vector values specially, emitting each subvector as an
// argument to the __builtin.
if (structTypes && (proto[i] == '2' || proto[i] == '3' || proto[i] == '4')){
for (unsigned vi = 0, ve = proto[i] - '0'; vi != ve; ++vi) {
- s.push_back(arg);
- s += ".val[" + utostr(vi) + "]";
+ s += args + ".val[" + utostr(vi) + "]";
if ((vi + 1) < ve)
s += ", ";
}
@@ -693,18 +737,10 @@ static std::string GenBuiltin(const std::string &name, const std::string &proto,
continue;
}
- // Parenthesize the args from the macro.
- if (define)
- s.push_back('(');
-
if (splat && (i + 1) == e)
- s += Duplicate(typestr, std::string(&arg, 1));
+ s += Duplicate(nElts, typestr, args);
else
- s.push_back(arg);
-
- // Parenthesize the args from the macro.
- if (define)
- s.push_back(')');
+ s += args;
if (structTypes && proto[i] != 's' && proto[i] != 'i' && proto[i] != 'l' &&
proto[i] != 'p' && proto[i] != 'c' && proto[i] != 'a') {
diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h
index 7b9c50585e..6c6760d732 100644
--- a/utils/TableGen/NeonEmitter.h
+++ b/utils/TableGen/NeonEmitter.h
@@ -47,7 +47,11 @@ enum OpKind {
OpConcat,
OpDup,
OpHi,
- OpLo
+ OpLo,
+ OpSelect,
+ OpRev16,
+ OpRev32,
+ OpRev64
};
enum ClassKind {
@@ -93,6 +97,10 @@ namespace llvm {
OpMap["OP_HI"] = OpHi;
OpMap["OP_LO"] = OpLo;
OpMap["OP_DUP"] = OpDup;
+ OpMap["OP_SEL"] = OpSelect;
+ OpMap["OP_REV16"] = OpRev16;
+ OpMap["OP_REV32"] = OpRev32;
+ OpMap["OP_REV64"] = OpRev64;
Record *SI = R.getClass("SInst");
Record *II = R.getClass("IInst");