diff options
author | Hao Liu <Hao.Liu@arm.com> | 2013-09-04 09:29:13 +0000 |
---|---|---|
committer | Hao Liu <Hao.Liu@arm.com> | 2013-09-04 09:29:13 +0000 |
commit | 912502b4996b14db31b498cb1eef2b17d7d66d57 (patch) | |
tree | 11186ac44aac7f474e0bbb42f87a810aaf3b3c36 /utils | |
parent | 31e44f7a5d50ab8f7f623a7d2e18d5d877ef400d (diff) | |
download | clang-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.cpp | 60 |
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. |