summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorHao Liu <Hao.Liu@arm.com>2013-09-04 09:29:13 +0000
committerHao Liu <Hao.Liu@arm.com>2013-09-04 09:29:13 +0000
commit912502b4996b14db31b498cb1eef2b17d7d66d57 (patch)
tree11186ac44aac7f474e0bbb42f87a810aaf3b3c36 /utils
parent31e44f7a5d50ab8f7f623a7d2e18d5d877ef400d (diff)
downloadclang-912502b4996b14db31b498cb1eef2b17d7d66d57.tar.gz
clang-912502b4996b14db31b498cb1eef2b17d7d66d57.tar.bz2
clang-912502b4996b14db31b498cb1eef2b17d7d66d57.tar.xz
Inplement aarch64 neon instructions in AdvSIMD(shift). About 24 shift instructions:
sshr,ushr,ssra,usra,srshr,urshr,srsra,ursra,sri,shl,sli,sqshlu,sqshl,uqshl,shrn,sqrshr$ and 4 convert instructions: scvtf,ucvtf,fcvtzs,fcvtzu git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189926 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/NeonEmitter.cpp60
1 files changed, 54 insertions, 6 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 1e43032da5..d8f203d3df 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -91,7 +91,10 @@ enum OpKind {
OpAbdl,
OpAba,
OpAbal,
- OpDiv
+ OpDiv,
+ OpLongHi,
+ OpNarrowHi,
+ OpMovlHi
};
enum ClassKind {
@@ -208,6 +211,9 @@ public:
OpMap["OP_ABA"] = OpAba;
OpMap["OP_ABAL"] = OpAbal;
OpMap["OP_DIV"] = OpDiv;
+ OpMap["OP_LONG_HI"] = OpLongHi;
+ OpMap["OP_NARROW_HI"] = OpNarrowHi;
+ OpMap["OP_MOVL_HI"] = OpMovlHi;
Record *SI = R.getClass("SInst");
Record *II = R.getClass("IInst");
@@ -374,6 +380,8 @@ static char ModType(const char mod, char type, bool &quad, bool &poly,
poly = false;
if (type == 'f')
type = 'i';
+ if (type == 'd')
+ type = 'l';
break;
case 'f':
if (type == 'h')
@@ -422,6 +430,10 @@ static char ModType(const char mod, char type, bool &quad, bool &poly,
type = Narrow(type);
usgn = true;
break;
+ case 'm':
+ type = Narrow(type);
+ quad = false;
+ break;
default:
break;
}
@@ -1305,6 +1317,15 @@ static std::string SplatLane(unsigned nElts, const std::string &vec,
return s;
}
+static std::string RemoveHigh(const std::string &name) {
+ std::string s = name;
+ std::size_t found = s.find("_high_");
+ if (found == std::string::npos)
+ PrintFatalError("name should contain \"_high_\" for high intrinsics");
+ s.replace(found, 5, "");
+ return s;
+}
+
static unsigned GetNumElements(StringRef typestr, bool &quad) {
quad = false;
bool dummy = false;
@@ -1328,8 +1349,8 @@ static unsigned GetNumElements(StringRef typestr, bool &quad) {
}
// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
-static std::string GenOpString(OpKind op, const std::string &proto,
- StringRef typestr) {
+static std::string GenOpString(const std::string &name, OpKind op,
+ const std::string &proto, StringRef typestr) {
bool quad;
unsigned nElts = GetNumElements(typestr, quad);
bool define = UseMacro(proto);
@@ -1559,6 +1580,27 @@ static std::string GenOpString(OpKind op, const std::string &proto,
case OpDiv:
s += "__a / __b;";
break;
+ case OpMovlHi: {
+ s = TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
+ MangleName("vget_high", typestr, ClassS) + "(__a);\n " + s;
+ s += "(" + ts + ")" + MangleName("vshll_n", typestr, ClassS);
+ s += "(__a1, 0);";
+ break;
+ }
+ case OpLongHi: {
+ // Another local variable __a1 is needed for calling a Macro,
+ // or using __a will have naming conflict when Macro expanding.
+ s += TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
+ MangleName("vget_high", typestr, ClassS) + "(__a); \\\n";
+ s += " (" + ts + ")" + MangleName(RemoveHigh(name), typestr, ClassS) +
+ "(__a1, __b);";
+ break;
+ }
+ case OpNarrowHi: {
+ s += "(" + ts + ")" + MangleName("vcombine", typestr, ClassS) + "(__a, " +
+ MangleName(RemoveHigh(name), typestr, ClassS) + "(__b, __c));";
+ break;
+ }
default:
PrintFatalError("unknown OpKind!");
}
@@ -1796,7 +1838,7 @@ static std::string GenIntrinsic(const std::string &name,
s += " {\n ";
if (kind != OpNone)
- s += GenOpString(kind, proto, outTypeStr);
+ s += GenOpString(name, kind, proto, outTypeStr);
else
s += GenBuiltin(name, proto, outTypeStr, classKind);
if (define)
@@ -2124,9 +2166,15 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
if (R->getValueAsBit("isVCVT_N")) {
// VCVT between floating- and fixed-point values takes an immediate
- // in the range 1 to 32.
+ // in the range [1, 32] for f32, or [1, 64] for f64.
ck = ClassB;
- rangestr = "l = 1; u = 31"; // upper bound = l + u
+ if (name.find("32") != std::string::npos)
+ rangestr = "l = 1; u = 31"; // upper bound = l + u
+ else if (name.find("64") != std::string::npos)
+ rangestr = "l = 1; u = 63";
+ else
+ PrintFatalError(R->getLoc(),
+ "Fixed point convert name should contains \"32\" or \"64\"");
} else if (Proto.find('s') == std::string::npos) {
// Builtins which are overloaded by type will need to have their upper
// bound computed at Sema time based on the type constant.