diff options
author | Nate Begeman <natebegeman@mac.com> | 2010-06-14 05:17:23 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2010-06-14 05:17:23 +0000 |
commit | 918f8e4ab0fe645d26baface7958d3673437bc04 (patch) | |
tree | b916a9576ffc0cf649314980259959bccc9288e4 /utils | |
parent | c125fedcc72f37266ce896e052a82735bb8340da (diff) | |
download | llvm-918f8e4ab0fe645d26baface7958d3673437bc04.tar.gz llvm-918f8e4ab0fe645d26baface7958d3673437bc04.tar.bz2 llvm-918f8e4ab0fe645d26baface7958d3673437bc04.tar.xz |
Add the last of the SemaChecking-gen code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105929 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/NeonEmitter.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index bf5c175335..bdcfbc5a86 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -946,6 +946,28 @@ void NeonEmitter::run(raw_ostream &OS) { OS << "#endif /* __ARM_NEON_H */\n"; } +static unsigned RangeFromType(StringRef typestr) { + // base type to get the type string for. + bool quad = false, dummy = false; + char type = ClassifyType(typestr, quad, dummy, dummy); + + switch (type) { + case 'c': + return (8 << quad) - 1; + case 'h': + case 's': + return (4 << quad) - 1; + case 'f': + case 'i': + return (2 << quad) - 1; + case 'l': + return (1 << quad) - 1; + default: + throw "unhandled type!"; + break; + } +} + /// runHeader - generate one of three different tables which are used by clang /// to support ARM NEON codegen. By default, this will produce the contents of /// BuiltinsARM.def's NEON section. You may also enable the genSemaTypes or @@ -1020,11 +1042,32 @@ void NeonEmitter::runHeader(raw_ostream &OS) { } if (genSemaRange) { - if (Proto.find('s') == std::string::npos) + std::string namestr, shiftstr, rangestr; + + // Builtins which are overloaded by type will need to have their upper + // bound computed at Sema time based on the type constant. + if (Proto.find('s') == std::string::npos) { ck = ClassB; + if (R->getValueAsBit("isShift")) { + shiftstr = ", true"; + + // Right shifts have an 'r' in the name, left shifts do not. + if (name.find('r') != std::string::npos) + rangestr = "l = 1; "; + } + rangestr += "u = RFT(TV" + shiftstr + ")"; + } else { + rangestr = "u = " + utostr(RangeFromType(TypeVec[ti])); + } + // Make sure cases appear only once. + namestr = MangleName(name, TypeVec[ti], ck); + if (EmittedMap.count(namestr)) + continue; + EmittedMap[namestr] = OpNone; OS << "case ARM::BI__builtin_neon_" - << MangleName(name, TypeVec[ti], ck) << "\n"; + << MangleName(name, TypeVec[ti], ck) << ": i = " << Proto.find('i')-1 + << "; " << rangestr << "; break;\n"; continue; } |