summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/FileCheck/CMakeLists.txt6
-rw-r--r--utils/FileCheck/FileCheck.cpp61
-rw-r--r--utils/FileCheck/Makefile4
-rw-r--r--utils/FileUpdate/CMakeLists.txt6
-rw-r--r--utils/FileUpdate/FileUpdate.cpp7
-rw-r--r--utils/TableGen/Android.mk1
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp56
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp50
-rw-r--r--utils/TableGen/AsmWriterInst.cpp35
-rw-r--r--utils/TableGen/AsmWriterInst.h1
-rw-r--r--utils/TableGen/CMakeLists.txt1
-rw-r--r--utils/TableGen/CTagsEmitter.cpp1
-rw-r--r--utils/TableGen/CallingConvEmitter.cpp45
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp97
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp308
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h6
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp49
-rw-r--r--utils/TableGen/CodeGenInstruction.h66
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h5
-rw-r--r--utils/TableGen/CodeGenMapTable.cpp4
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp36
-rw-r--r--utils/TableGen/CodeGenRegisters.h9
-rw-r--r--utils/TableGen/CodeGenSchedule.cpp20
-rw-r--r--utils/TableGen/CodeGenSchedule.h4
-rw-r--r--utils/TableGen/CodeGenTarget.cpp114
-rw-r--r--utils/TableGen/CodeGenTarget.h4
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp3
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp26
-rw-r--r--utils/TableGen/DAGISelMatcher.h336
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp26
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp13
-rw-r--r--utils/TableGen/DAGISelMatcherOpt.cpp47
-rw-r--r--utils/TableGen/DisassemblerEmitter.cpp7
-rw-r--r--utils/TableGen/FastISelEmitter.cpp4
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp189
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp10
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp63
-rw-r--r--utils/TableGen/OptParserEmitter.cpp2
-rw-r--r--utils/TableGen/PseudoLoweringEmitter.cpp2
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp31
-rw-r--r--utils/TableGen/SetTheory.cpp51
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp2
-rw-r--r--utils/TableGen/TGValueTypes.cpp128
-rw-r--r--utils/TableGen/TableGen.cpp9
-rw-r--r--utils/TableGen/X86DisassemblerShared.h4
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp174
-rw-r--r--utils/TableGen/X86DisassemblerTables.h13
-rw-r--r--utils/TableGen/X86ModRMFilters.cpp4
-rw-r--r--utils/TableGen/X86ModRMFilters.h98
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp959
-rw-r--r--utils/TableGen/X86RecognizableInstr.h118
-rwxr-xr-xutils/buildit/build_llvm23
-rw-r--r--utils/count/Makefile4
-rw-r--r--utils/kate/llvm.xml2
-rw-r--r--utils/lit/MANIFEST.in2
-rw-r--r--utils/lit/README.txt8
-rw-r--r--utils/lit/lit/Test.py8
-rw-r--r--utils/lit/lit/TestingConfig.py24
-rw-r--r--utils/lit/lit/__init__.py2
-rw-r--r--utils/lit/lit/formats/googletest.py2
-rwxr-xr-xutils/lit/lit/main.py32
-rwxr-xr-xutils/lit/utils/check-sdist1
-rw-r--r--utils/llvm-build/llvmbuild/main.py45
-rw-r--r--utils/llvm-lit/CMakeLists.txt25
-rw-r--r--utils/llvm-lit/Makefile9
-rwxr-xr-xutils/llvm-lit/llvm-lit.in16
-rwxr-xr-xutils/llvm-native-gcc249
-rw-r--r--utils/llvm.grm2
-rw-r--r--utils/llvm.natvis112
-rw-r--r--utils/not/CMakeLists.txt6
-rw-r--r--utils/not/Makefile4
-rwxr-xr-xutils/release/test-release.sh2
-rwxr-xr-xutils/test_debuginfo.pl2
-rw-r--r--utils/unittest/CMakeLists.txt7
-rw-r--r--utils/unittest/UnitTestMain/CMakeLists.txt7
-rw-r--r--utils/unittest/googletest/README.LLVM1
-rw-r--r--utils/unittest/googletest/include/gtest/gtest-typed-test.h3
-rw-r--r--utils/unittest/googletest/include/gtest/internal/gtest-port.h9
-rw-r--r--utils/vim/llvm.vim3
-rwxr-xr-xutils/wciia.py2
-rw-r--r--utils/yaml-bench/YAMLBench.cpp4
81 files changed, 1759 insertions, 2172 deletions
diff --git a/utils/FileCheck/CMakeLists.txt b/utils/FileCheck/CMakeLists.txt
index d691ceb..999320f 100644
--- a/utils/FileCheck/CMakeLists.txt
+++ b/utils/FileCheck/CMakeLists.txt
@@ -3,9 +3,3 @@ add_llvm_utility(FileCheck
)
target_link_libraries(FileCheck LLVMSupport)
-if( MINGW )
- target_link_libraries(FileCheck imagehlp psapi shell32)
-endif( MINGW )
-if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
- target_link_libraries(FileCheck pthread)
-endif()
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp
index f2510d7..a1f4be9 100644
--- a/utils/FileCheck/FileCheck.cpp
+++ b/utils/FileCheck/FileCheck.cpp
@@ -16,7 +16,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
@@ -136,7 +135,6 @@ public:
Check::CheckType getCheckTy() const { return CheckTy; }
private:
- static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
void AddBackrefToRegEx(unsigned BackrefNum);
@@ -155,7 +153,7 @@ private:
/// (right after the opening sequence).
/// \return offset of the closing sequence within Str, or npos if it was not
/// found.
- size_t FindRegexVarEnd(StringRef Str);
+ size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
};
@@ -228,7 +226,7 @@ bool Pattern::ParsePattern(StringRef PatternStr,
if (PatternStr.startswith("[[")) {
// Find the closing bracket pair ending the match. End is going to be an
// offset relative to the beginning of the match string.
- size_t End = FindRegexVarEnd(PatternStr.substr(2));
+ size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
if (End == StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
@@ -314,40 +312,13 @@ bool Pattern::ParsePattern(StringRef PatternStr,
// Find the end, which is the start of the next regex.
size_t FixedMatchEnd = PatternStr.find("{{");
FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
- AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
+ RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
PatternStr = PatternStr.substr(FixedMatchEnd);
}
return false;
}
-void Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) {
- // Add the characters from FixedStr to the regex, escaping as needed. This
- // avoids "leaning toothpicks" in common patterns.
- for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) {
- switch (FixedStr[i]) {
- // These are the special characters matched in "p_ere_exp".
- case '(':
- case ')':
- case '^':
- case '$':
- case '|':
- case '*':
- case '+':
- case '?':
- case '.':
- case '[':
- case '\\':
- case '{':
- TheStr += '\\';
- // FALL THROUGH.
- default:
- TheStr += FixedStr[i];
- break;
- }
- }
-}
-
bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
SourceMgr &SM) {
Regex R(RS);
@@ -428,8 +399,8 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
if (it == VariableTable.end())
return StringRef::npos;
- // Look up the value and escape it so that we can plop it into the regex.
- AddFixedStringToRegEx(it->second, Value);
+ // Look up the value and escape it so that we can put it into the regex.
+ Value += Regex::escape(it->second);
}
// Plop it into the regex at the adjusted offset.
@@ -560,7 +531,7 @@ void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
}
}
-size_t Pattern::FindRegexVarEnd(StringRef Str) {
+size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
// Offset keeps track of the current offset within the input Str
size_t Offset = 0;
// [...] Nesting depth
@@ -581,7 +552,12 @@ size_t Pattern::FindRegexVarEnd(StringRef Str) {
BracketDepth++;
break;
case ']':
- assert(BracketDepth > 0 && "Invalid regex");
+ if (BracketDepth == 0) {
+ SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
+ SourceMgr::DK_Error,
+ "missing closing \"]\" for regex variable");
+ exit(1);
+ }
BracketDepth--;
break;
}
@@ -795,10 +771,11 @@ static StringRef FindFirstCandidateMatch(StringRef &Buffer,
// it. This should also prevent matching the wrong prefix when one is a
// substring of another.
if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
- continue;
+ FirstTy = Check::CheckNone;
+ else
+ FirstTy = FindCheckType(Rest, Prefix);
FirstLoc = PrefixLoc;
- FirstTy = FindCheckType(Rest, Prefix);
FirstPrefix = Prefix;
}
@@ -843,7 +820,7 @@ static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
/// Returns true in case of an error, false otherwise.
static bool ReadCheckFile(SourceMgr &SM,
std::vector<CheckString> &CheckStrings) {
- OwningPtr<MemoryBuffer> File;
+ std::unique_ptr<MemoryBuffer> File;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(CheckFilename, File)) {
errs() << "Could not open check file '" << CheckFilename << "': "
@@ -854,7 +831,7 @@ static bool ReadCheckFile(SourceMgr &SM,
// If we want to canonicalize whitespace, strip excess whitespace from the
// buffer containing the CHECK lines. Remove DOS style line endings.
MemoryBuffer *F =
- CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace);
+ CanonicalizeInputFile(File.release(), NoCanonicalizeWhiteSpace);
SM.AddNewSourceBuffer(F, SMLoc());
@@ -1240,7 +1217,7 @@ int main(int argc, char **argv) {
return 2;
// Open the file to check and add it to SourceMgr.
- OwningPtr<MemoryBuffer> File;
+ std::unique_ptr<MemoryBuffer> File;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(InputFilename, File)) {
errs() << "Could not open input file '" << InputFilename << "': "
@@ -1256,7 +1233,7 @@ int main(int argc, char **argv) {
// Remove duplicate spaces in the input file if requested.
// Remove DOS style line endings.
MemoryBuffer *F =
- CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace);
+ CanonicalizeInputFile(File.release(), NoCanonicalizeWhiteSpace);
SM.AddNewSourceBuffer(F, SMLoc());
diff --git a/utils/FileCheck/Makefile b/utils/FileCheck/Makefile
index 268b7bc..b876236 100644
--- a/utils/FileCheck/Makefile
+++ b/utils/FileCheck/Makefile
@@ -14,8 +14,8 @@ USEDLIBS = LLVMSupport.a
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-# Don't install this utility
-NO_INSTALL = 1
+# FIXME: Don't install this utility
+#NO_INSTALL = 1
include $(LEVEL)/Makefile.common
diff --git a/utils/FileUpdate/CMakeLists.txt b/utils/FileUpdate/CMakeLists.txt
index 0114e50..ce7478f 100644
--- a/utils/FileUpdate/CMakeLists.txt
+++ b/utils/FileUpdate/CMakeLists.txt
@@ -3,9 +3,3 @@ add_llvm_utility(FileUpdate
)
target_link_libraries(FileUpdate LLVMSupport)
-if( MINGW )
- target_link_libraries(FileUpdate imagehlp psapi shell32)
-endif( MINGW )
-if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
- target_link_libraries(FileUpdate pthread)
-endif()
diff --git a/utils/FileUpdate/FileUpdate.cpp b/utils/FileUpdate/FileUpdate.cpp
index fbcd927..5ccf3f3 100644
--- a/utils/FileUpdate/FileUpdate.cpp
+++ b/utils/FileUpdate/FileUpdate.cpp
@@ -13,7 +13,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -44,7 +43,7 @@ int main(int argc, char **argv) {
}
// Get the input data.
- OwningPtr<MemoryBuffer> In;
+ std::unique_ptr<MemoryBuffer> In;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, In)) {
errs() << argv[0] << ": error: Unable to get input '"
<< InputFilename << "': " << ec.message() << '\n';
@@ -52,7 +51,7 @@ int main(int argc, char **argv) {
}
// Get the output data.
- OwningPtr<MemoryBuffer> Out;
+ std::unique_ptr<MemoryBuffer> Out;
MemoryBuffer::getFile(OutputFilename.c_str(), Out);
// If the output exists and the contents match, we are done.
@@ -71,7 +70,7 @@ int main(int argc, char **argv) {
<< "', contents changed.\n";
std::string ErrorStr;
tool_output_file OutStream(OutputFilename.c_str(), ErrorStr,
- sys::fs::F_Binary);
+ sys::fs::F_None);
if (!ErrorStr.empty()) {
errs() << argv[0] << ": Unable to write output '"
<< OutputFilename << "': " << ErrorStr << '\n';
diff --git a/utils/TableGen/Android.mk b/utils/TableGen/Android.mk
index e476cd7..8117672 100644
--- a/utils/TableGen/Android.mk
+++ b/utils/TableGen/Android.mk
@@ -29,7 +29,6 @@ tablegen_SRC_FILES := \
RegisterInfoEmitter.cpp \
SetTheory.cpp \
SubtargetEmitter.cpp \
- TGValueTypes.cpp \
TableGen.cpp \
X86DisassemblerTables.cpp \
X86ModRMFilters.cpp \
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index de24cde..4169f8d 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -97,7 +97,6 @@
//===----------------------------------------------------------------------===//
#include "CodeGenTarget.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -288,15 +287,6 @@ public:
}
};
-namespace {
-/// Sort ClassInfo pointers independently of pointer value.
-struct LessClassInfoPtr {
- bool operator()(const ClassInfo *LHS, const ClassInfo *RHS) const {
- return *LHS < *RHS;
- }
-};
-}
-
/// MatchableInfo - Helper class for storing the necessary information for an
/// instruction or alias which is capable of being matched.
struct MatchableInfo {
@@ -729,12 +719,12 @@ void MatchableInfo::formTwoOperandAlias(StringRef Constraint) {
int DstAsmOperand = findAsmOperandNamed(Ops.second);
if (SrcAsmOperand == -1)
PrintFatalError(TheDef->getLoc(),
- "unknown source two-operand alias operand '" +
- Ops.first.str() + "'.");
+ "unknown source two-operand alias operand '" + Ops.first +
+ "'.");
if (DstAsmOperand == -1)
PrintFatalError(TheDef->getLoc(),
- "unknown destination two-operand alias operand '" +
- Ops.second.str() + "'.");
+ "unknown destination two-operand alias operand '" +
+ Ops.second + "'.");
// Find the ResOperand that refers to the operand we're aliasing away
// and update it to refer to the combined operand instead.
@@ -882,7 +872,7 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
// FIXME : Check and raise an error if it is a register.
if (Mnemonic[0] == '$')
PrintFatalError(TheDef->getLoc(),
- "Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
+ "Invalid instruction mnemonic '" + Mnemonic + "'!");
// Remove the first operand, it is tracked in the mnemonic field.
AsmOperands.erase(AsmOperands.begin());
@@ -919,22 +909,22 @@ bool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const {
StringRef Tok = AsmOperands[i].Token;
if (Tok[0] == '$' && Tok.find(':') != StringRef::npos)
PrintFatalError(TheDef->getLoc(),
- "matchable with operand modifier '" + Tok.str() +
- "' not supported by asm matcher. Mark isCodeGenOnly!");
+ "matchable with operand modifier '" + Tok +
+ "' not supported by asm matcher. Mark isCodeGenOnly!");
// Verify that any operand is only mentioned once.
// We reject aliases and ignore instructions for now.
if (Tok[0] == '$' && !OperandNames.insert(Tok).second) {
if (!Hack)
PrintFatalError(TheDef->getLoc(),
- "ERROR: matchable with tied operand '" + Tok.str() +
- "' can never be matched!");
+ "ERROR: matchable with tied operand '" + Tok +
+ "' can never be matched!");
// FIXME: Should reject these. The ARM backend hits this with $lane in a
// bunch of instructions. It is unclear what the right answer is.
DEBUG({
errs() << "warning: '" << TheDef->getName() << "': "
<< "ignoring instruction with tied operand '"
- << Tok.str() << "'\n";
+ << Tok << "'\n";
});
return false;
}
@@ -1288,7 +1278,7 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
/// Map containing a mask with all operands indices that can be found for
/// that class inside a instruction.
- typedef std::map<ClassInfo*, unsigned, LessClassInfoPtr> OpClassMaskTy;
+ typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy;
OpClassMaskTy OpClassMask;
for (std::vector<MatchableInfo*>::const_iterator it =
@@ -1359,7 +1349,7 @@ void AsmMatcherInfo::buildInfo() {
if (CGI.TheDef->getValueAsBit("isCodeGenOnly"))
continue;
- OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
+ std::unique_ptr<MatchableInfo> II(new MatchableInfo(CGI));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
@@ -1375,7 +1365,7 @@ void AsmMatcherInfo::buildInfo() {
StringRef(II->TheDef->getName()).endswith("_Int"))
continue;
- Matchables.push_back(II.take());
+ Matchables.push_back(II.release());
}
// Parse all of the InstAlias definitions and stick them in the list of
@@ -1392,14 +1382,14 @@ void AsmMatcherInfo::buildInfo() {
.startswith( MatchPrefix))
continue;
- OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
+ std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
// Validate the alias definitions.
II->validate(CommentDelimiter, false);
- Matchables.push_back(II.take());
+ Matchables.push_back(II.release());
}
}
@@ -1464,13 +1454,13 @@ void AsmMatcherInfo::buildInfo() {
II->TheDef->getValueAsString("TwoOperandAliasConstraint");
if (Constraint != "") {
// Start by making a copy of the original matchable.
- OwningPtr<MatchableInfo> AliasII(new MatchableInfo(*II));
+ std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II));
// Adjust it to be a two-operand alias.
AliasII->formTwoOperandAlias(Constraint);
// Add the alias to the matchables list.
- NewMatchables.push_back(AliasII.take());
+ NewMatchables.push_back(AliasII.release());
}
} else
II->buildAliasResultOperands();
@@ -1510,8 +1500,8 @@ buildInstructionOperandReference(MatchableInfo *II,
// Map this token to an operand.
unsigned Idx;
if (!Operands.hasOperandNamed(OperandName, Idx))
- PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
- OperandName.str() + "'");
+ PrintFatalError(II->TheDef->getLoc(),
+ "error: unable to find operand: '" + OperandName + "'");
// If the instruction operand has multiple suboperands, but the parser
// match class for the asm operand is still the default "ImmAsmOperand",
@@ -1583,8 +1573,8 @@ void AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
return;
}
- PrintFatalError(II->TheDef->getLoc(), "error: unable to find operand: '" +
- OperandName.str() + "'");
+ PrintFatalError(II->TheDef->getLoc(),
+ "error: unable to find operand: '" + OperandName + "'");
}
void MatchableInfo::buildInstructionResultOperands() {
@@ -2691,8 +2681,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< " const SmallVectorImpl<MCParsedAsmOperand*> "
<< "&Operands);\n";
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
- OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands);\n";
- OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
+ OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands) override;\n";
+ OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
OS << " unsigned MatchInstructionImpl(\n";
OS.indent(27);
OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index a18b6b5..f9e1990 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -34,7 +34,7 @@ class AsmWriterEmitter {
RecordKeeper &Records;
CodeGenTarget Target;
std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap;
- std::vector<const CodeGenInstruction*> NumberedInstructions;
+ const std::vector<const CodeGenInstruction*> *NumberedInstructions;
std::vector<AsmWriterInst> Instructions;
public:
AsmWriterEmitter(RecordKeeper &R);
@@ -47,9 +47,9 @@ private:
void EmitPrintAliasInstruction(raw_ostream &O);
AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
- assert(ID < NumberedInstructions.size());
+ assert(ID < NumberedInstructions->size());
std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I =
- CGIAWIMap.find(NumberedInstructions[ID]);
+ CGIAWIMap.find(NumberedInstructions->at(ID));
assert(I != CGIAWIMap.end() && "Didn't find inst!");
return I->second;
}
@@ -141,7 +141,7 @@ void AsmWriterEmitter::
FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
std::vector<unsigned> &InstIdxs,
std::vector<unsigned> &InstOpsUsed) const {
- InstIdxs.assign(NumberedInstructions.size(), ~0U);
+ InstIdxs.assign(NumberedInstructions->size(), ~0U);
// This vector parallels UniqueOperandCommands, keeping track of which
// instructions each case are used for. It is a comma separated string of
@@ -150,9 +150,10 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
InstrsForCase.resize(UniqueOperandCommands.size());
InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
const AsmWriterInst *Inst = getAsmWriterInstByID(i);
- if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc.
+ if (Inst == 0)
+ continue; // PHI, INLINEASM, CFI_INSTRUCTION, etc.
std::string Command;
if (Inst->Operands.empty())
@@ -280,15 +281,12 @@ static void UnescapeString(std::string &Str) {
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
Record *AsmWriter = Target.getAsmWriter();
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
- bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter");
- const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr";
O <<
"/// printInstruction - This method is automatically generated by tablegen\n"
"/// from the instruction set description.\n"
"void " << Target.getName() << ClassName
- << "::printInstruction(const " << MachineInstrClassName
- << " *MI, raw_ostream &O) {\n";
+ << "::printInstruction(const MCInst *MI, raw_ostream &O) {\n";
// Build an aggregate string, and build a table of offsets into it.
SequenceToOffsetTable<std::string> StringTable;
@@ -301,8 +299,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
// Add all strings to the string table upfront so it can generate an optimized
// representation.
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
- AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
+ AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions->at(i)];
if (AWI != 0 &&
AWI->Operands[0].OperandType ==
AsmWriterOperand::isLiteralTextOperand &&
@@ -316,8 +314,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
StringTable.layout();
unsigned MaxStringIdx = 0;
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
- AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
+ AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions->at(i)];
unsigned Idx;
if (AWI == 0) {
// Something not handled by the asmwriter printer.
@@ -379,7 +377,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
BitsLeft -= NumBits;
// Remove the info about this operand.
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
if (!Inst->Operands.empty()) {
unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
@@ -398,9 +396,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
// We always emit at least one 32-bit table. A second table is emitted if
// more bits are needed.
O<<" static const uint32_t OpInfo[] = {\n";
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
O << " " << (OpcodeInfo[i] & 0xffffffff) << "U,\t// "
- << NumberedInstructions[i]->TheDef->getName() << "\n";
+ << NumberedInstructions->at(i)->TheDef->getName() << "\n";
}
// Add a dummy entry so the array init doesn't end with a comma.
O << " 0U\n";
@@ -412,9 +410,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
O << " static const uint"
<< ((BitsLeft < 16) ? "32" : (BitsLeft < 24) ? "16" : "8")
<< "_t OpInfo2[] = {\n";
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ for (unsigned i = 0, e = NumberedInstructions->size(); i != e; ++i) {
O << " " << (OpcodeInfo[i] >> 32) << "U,\t// "
- << NumberedInstructions[i]->TheDef->getName() << "\n";
+ << NumberedInstructions->at(i)->TheDef->getName() << "\n";
}
// Add a dummy entry so the array init doesn't end with a comma.
O << " 0U\n";
@@ -549,8 +547,8 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
Reg.TheDef->getValueAsListOfStrings("AltNames");
if (AltNames.size() <= Idx)
PrintFatalError(Reg.TheDef->getLoc(),
- (Twine("Register definition missing alt name for '") +
- AltName + "'.").str());
+ "Register definition missing alt name for '" +
+ AltName + "'.");
AsmName = AltNames[Idx];
}
}
@@ -605,8 +603,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
<< " switch(AltIdx) {\n"
<< " default: llvm_unreachable(\"Invalid register alt name index!\");\n";
for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
- StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace");
- StringRef AltName(AltNameIndices[i]->getName());
+ std::string Namespace = AltNameIndices[1]->getValueAsString("Namespace");
+ std::string AltName(AltNameIndices[i]->getName());
O << " case " << Namespace << "::" << AltName
<< ":\n"
<< " AsmStrs = AsmStrs" << AltName << ";\n"
@@ -764,9 +762,6 @@ static unsigned CountResultNumOperands(StringRef AsmString) {
void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
Record *AsmWriter = Target.getAsmWriter();
- if (!AsmWriter->getValueAsBit("isMCAsmWriter"))
- return;
-
O << "\n#ifdef PRINT_ALIAS_INSTR\n";
O << "#undef PRINT_ALIAS_INSTR\n\n";
@@ -987,11 +982,10 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
if (!(*I)->AsmString.empty() && (*I)->TheDef->getName() != "PHI")
Instructions.push_back(
AsmWriterInst(**I, AsmWriter->getValueAsInt("Variant"),
- AsmWriter->getValueAsInt("FirstOperandColumn"),
AsmWriter->getValueAsInt("OperandSpacing")));
// Get the instruction numbering.
- NumberedInstructions = Target.getInstructionsByEnumValue();
+ NumberedInstructions = &Target.getInstructionsByEnumValue();
// Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not
// all machine instructions are necessarily being printed, so there may be
diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
index 1c2004f..5d9ead1 100644
--- a/utils/TableGen/AsmWriterInst.cpp
+++ b/utils/TableGen/AsmWriterInst.cpp
@@ -50,14 +50,9 @@ std::string AsmWriterOperand::getCode() const {
///
AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
unsigned Variant,
- int FirstOperandColumn,
int OperandSpacing) {
this->CGI = &CGI;
- // This is the number of tabs we've seen if we're doing columnar layout.
- unsigned CurColumn = 0;
-
-
// NOTE: Any extensions to this code need to be mirrored in the
// AsmPrinter::printInlineAsm code that executes as compile time (assuming
// that inline asm strings should also get the new feature)!
@@ -76,20 +71,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
AddLiteralString("\\n");
break;
case '\t':
- // If the asm writer is not using a columnar layout, \t is not
- // magic.
- if (FirstOperandColumn == -1 || OperandSpacing == -1) {
- AddLiteralString("\\t");
- } else {
- // We recognize a tab as an operand delimeter.
- unsigned DestColumn = FirstOperandColumn +
- CurColumn++ * OperandSpacing;
- Operands.push_back(
- AsmWriterOperand(
- "O.PadToColumn(" +
- utostr(DestColumn) + ");\n",
- AsmWriterOperand::isLiteralStatementOperand));
- }
+ AddLiteralString("\\t");
break;
case '"':
AddLiteralString("\\\"");
@@ -106,20 +88,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
if (AsmString[DollarPos+1] == 'n') {
AddLiteralString("\\n");
} else if (AsmString[DollarPos+1] == 't') {
- // If the asm writer is not using a columnar layout, \t is not
- // magic.
- if (FirstOperandColumn == -1 || OperandSpacing == -1) {
- AddLiteralString("\\t");
- break;
- }
-
- // We recognize a tab as an operand delimeter.
- unsigned DestColumn = FirstOperandColumn +
- CurColumn++ * OperandSpacing;
- Operands.push_back(
- AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
- AsmWriterOperand::isLiteralStatementOperand));
- break;
+ AddLiteralString("\\t");
} else if (std::string("${|}\\").find(AsmString[DollarPos+1])
!= std::string::npos) {
AddLiteralString(std::string(1, AsmString[DollarPos+1]));
diff --git a/utils/TableGen/AsmWriterInst.h b/utils/TableGen/AsmWriterInst.h
index ec7d8eb..4cee352 100644
--- a/utils/TableGen/AsmWriterInst.h
+++ b/utils/TableGen/AsmWriterInst.h
@@ -89,7 +89,6 @@ namespace llvm {
AsmWriterInst(const CodeGenInstruction &CGI,
unsigned Variant,
- int FirstOperandColumn,
int OperandSpacing);
/// MatchesAllButOneOp - If this instruction is exactly identical to the
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index 3ee1974..f277608 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -28,7 +28,6 @@ add_tablegen(llvm-tblgen LLVM
RegisterInfoEmitter.cpp
SetTheory.cpp
SubtargetEmitter.cpp
- TGValueTypes.cpp
TableGen.cpp
X86DisassemblerTables.cpp
X86ModRMFilters.cpp
diff --git a/utils/TableGen/CTagsEmitter.cpp b/utils/TableGen/CTagsEmitter.cpp
index 8bf7778..1d240fa 100644
--- a/utils/TableGen/CTagsEmitter.cpp
+++ b/utils/TableGen/CTagsEmitter.cpp
@@ -19,7 +19,6 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <string>
#include <vector>
diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp
index 94f3c65..96bd336 100644
--- a/utils/TableGen/CallingConvEmitter.cpp
+++ b/utils/TableGen/CallingConvEmitter.cpp
@@ -185,21 +185,48 @@ void CallingConvEmitter::EmitAction(Record *Action,
else
O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
"->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
- if (Action->isSubClassOf("CCAssignToStackWithShadow"))
- O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
O << ");\n" << IndentStr
<< "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
<< Counter << ", LocVT, LocInfo));\n";
O << IndentStr << "return false;\n";
+ } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
+ int Size = Action->getValueAsInt("Size");
+ int Align = Action->getValueAsInt("Align");
+ ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
+
+ unsigned ShadowRegListNumber = ++Counter;
+
+ O << IndentStr << "static const uint16_t ShadowRegList"
+ << ShadowRegListNumber << "[] = {\n";
+ O << IndentStr << " ";
+ for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
+ if (i != 0) O << ", ";
+ O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
+ }
+ O << "\n" << IndentStr << "};\n";
+
+ O << IndentStr << "unsigned Offset" << ++Counter
+ << " = State.AllocateStack("
+ << Size << ", " << Align << ", "
+ << "ShadowRegList" << ShadowRegListNumber << ", "
+ << ShadowRegList->getSize() << ");\n";
+ O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
+ << Counter << ", LocVT, LocInfo));\n";
+ O << IndentStr << "return false;\n";
} else if (Action->isSubClassOf("CCPromoteToType")) {
Record *DestTy = Action->getValueAsDef("DestTy");
- O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
- O << IndentStr << "if (ArgFlags.isSExt())\n"
- << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
- << IndentStr << "else if (ArgFlags.isZExt())\n"
- << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
- << IndentStr << "else\n"
- << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
+ MVT::SimpleValueType DestVT = getValueType(DestTy);
+ O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
+ if (MVT(DestVT).isFloatingPoint()) {
+ O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
+ } else {
+ O << IndentStr << "if (ArgFlags.isSExt())\n"
+ << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
+ << IndentStr << "else if (ArgFlags.isZExt())\n"
+ << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
+ << IndentStr << "else\n"
+ << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
+ }
} else if (Action->isSubClassOf("CCBitConvertToType")) {
Record *DestTy = Action->getValueAsDef("DestTy");
O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index e99a171..4d0c0ca 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -41,52 +41,16 @@ public:
void run(raw_ostream &o);
private:
- void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace);
- void emitGetValueBit(raw_ostream &o, const std::string &Namespace);
- void reverseBits(std::vector<Record*> &Insts);
int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
std::string getInstructionCase(Record *R, CodeGenTarget &Target);
void AddCodeToMergeInOperand(Record *R, BitsInit *BI,
const std::string &VarName,
unsigned &NumberedOp,
+ std::set<unsigned> &NamedOpIndices,
std::string &Case, CodeGenTarget &Target);
};
-void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
- for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
- I != E; ++I) {
- Record *R = *I;
- if (R->getValueAsString("Namespace") == "TargetOpcode" ||
- R->getValueAsBit("isPseudo"))
- continue;
-
- BitsInit *BI = R->getValueAsBitsInit("Inst");
-
- unsigned numBits = BI->getNumBits();
-
- SmallVector<Init *, 16> NewBits(numBits);
-
- for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
- unsigned bitSwapIdx = numBits - bit - 1;
- Init *OrigBit = BI->getBit(bit);
- Init *BitSwap = BI->getBit(bitSwapIdx);
- NewBits[bit] = BitSwap;
- NewBits[bitSwapIdx] = OrigBit;
- }
- if (numBits % 2) {
- unsigned middle = (numBits + 1) / 2;
- NewBits[middle] = BI->getBit(middle);
- }
-
- BitsInit *NewBI = BitsInit::get(NewBits);
-
- // Update the bits in reversed order so that emitInstrOpBits will get the
- // correct endianness.
- R->getValue("Inst")->setValue(NewBI);
- }
-}
-
// If the VarBitInit at position 'bit' matches the specified variable then
// return the variable bit position. Otherwise return -1.
int CodeEmitterGen::getVariableBit(const std::string &VarName,
@@ -106,6 +70,7 @@ int CodeEmitterGen::getVariableBit(const std::string &VarName,
void CodeEmitterGen::
AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
unsigned &NumberedOp,
+ std::set<unsigned> &NamedOpIndices,
std::string &Case, CodeGenTarget &Target) {
CodeGenInstruction &CGI = Target.getInstruction(R);
@@ -138,9 +103,22 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
/// If this operand is not supposed to be emitted by the
/// generated emitter, skip it.
while (NumberedOp < NumberOps &&
- CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
+ (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
+ (NamedOpIndices.size() && NamedOpIndices.count(
+ CGI.Operands.getSubOperandNumber(NumberedOp).first)))) {
++NumberedOp;
+ if (NumberedOp >= CGI.Operands.back().MIOperandNo +
+ CGI.Operands.back().MINumOperands) {
+ errs() << "Too few operands in record " << R->getName() <<
+ " (no match for variable " << VarName << "):\n";
+ errs() << *R;
+ errs() << '\n';
+
+ return;
+ }
+ }
+
OpIdx = NumberedOp++;
}
@@ -157,14 +135,14 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
Case += " // op: " + VarName + "\n" +
" op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
if (MCEmitter)
- Case += ", Fixups";
+ Case += ", Fixups, STI";
Case += ");\n";
}
} else {
Case += " // op: " + VarName + "\n" +
" op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
if (MCEmitter)
- Case += ", Fixups";
+ Case += ", Fixups, STI";
Case += ");\n";
}
@@ -215,6 +193,21 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
const std::vector<RecordVal> &Vals = R->getValues();
unsigned NumberedOp = 0;
+ std::set<unsigned> NamedOpIndices;
+ // Collect the set of operand indices that might correspond to named
+ // operand, and skip these when assigning operands based on position.
+ if (Target.getInstructionSet()->
+ getValueAsBit("noNamedPositionallyEncodedOperands")) {
+ CodeGenInstruction &CGI = Target.getInstruction(R);
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ unsigned OpIdx;
+ if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
+ continue;
+
+ NamedOpIndices.insert(OpIdx);
+ }
+ }
+
// Loop over all of the fields in the instruction, determining which are the
// operands to the instruction.
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
@@ -223,12 +216,17 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
continue;
- AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target);
+ AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp,
+ NamedOpIndices, Case, Target);
}
std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
- if (!PostEmitter.empty())
- Case += " Value = " + PostEmitter + "(MI, Value);\n";
+ if (!PostEmitter.empty()) {
+ Case += " Value = " + PostEmitter + "(MI, Value";
+ if (MCEmitter)
+ Case += ", STI";
+ Case += ");\n";
+ }
return Case;
}
@@ -238,8 +236,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
// For little-endian instruction bit encodings, reverse the bit order
- if (Target.isLittleEndianEncoding()) reverseBits(Insts);
-
+ Target.reverseBitsForLittleEndianEncoding();
const std::vector<const CodeGenInstruction*> &NumberedInstructions =
Target.getInstructionsByEnumValue();
@@ -248,7 +245,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
o << "uint64_t " << Target.getName();
if (MCEmitter)
o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
- << " SmallVectorImpl<MCFixup> &Fixups) const {\n";
+ << " SmallVectorImpl<MCFixup> &Fixups,\n"
+ << " const MCSubtargetInfo &STI) const {\n";
else
o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
@@ -287,14 +285,11 @@ void CodeEmitterGen::run(raw_ostream &o) {
IC != EC; ++IC) {
Record *R = *IC;
if (R->getValueAsString("Namespace") == "TargetOpcode" ||
- (R->getValueAsBit("isPseudo") && MCEmitter))
+ R->getValueAsBit("isPseudo"))
continue;
const std::string &InstName = R->getValueAsString("Namespace") + "::"
+ R->getName();
- std::string Case;
- if (!R->getValueAsBit("isPseudo")) {
- Case = getInstructionCase(R, Target);
- }
+ std::string Case = getInstructionCase(R, Target);
CaseMap[Case].push_back(InstName);
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 717090a..0af7e3d 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -120,6 +120,14 @@ bool EEVT::TypeSet::hasFloatingPointTypes() const {
return false;
}
+/// hasScalarTypes - Return true if this TypeSet contains a scalar value type.
+bool EEVT::TypeSet::hasScalarTypes() const {
+ for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
+ if (isScalar(TypeVec[i]))
+ return true;
+ return false;
+}
+
/// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector
/// value type.
bool EEVT::TypeSet::hasVectorTypes() const {
@@ -339,8 +347,9 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) {
-/// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update
-/// this an other based on this information.
+/// EnforceSmallerThan - 'this' must be a smaller VT than Other. For vectors
+/// this shoud be based on the element type. Update this and other based on
+/// this information.
bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
if (TP.hasError())
return false;
@@ -371,159 +380,100 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) {
// If one contains vectors but the other doesn't pull vectors out.
if (!hasVectorTypes())
MadeChange |= Other.EnforceScalar(TP);
- if (!hasVectorTypes())
+ else if (!hasScalarTypes())
+ MadeChange |= Other.EnforceVector(TP);
+ if (!Other.hasVectorTypes())
MadeChange |= EnforceScalar(TP);
+ else if (!Other.hasScalarTypes())
+ MadeChange |= EnforceVector(TP);
- if (TypeVec.size() == 1 && Other.TypeVec.size() == 1) {
- // If we are down to concrete types, this code does not currently
- // handle nodes which have multiple types, where some types are
- // integer, and some are fp. Assert that this is not the case.
- assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
- !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
- "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
-
- // Otherwise, if these are both vector types, either this vector
- // must have a larger bitsize than the other, or this element type
- // must be larger than the other.
- MVT Type(TypeVec[0]);
- MVT OtherType(Other.TypeVec[0]);
-
- if (hasVectorTypes() && Other.hasVectorTypes()) {
- if (Type.getSizeInBits() >= OtherType.getSizeInBits())
- if (Type.getVectorElementType().getSizeInBits()
- >= OtherType.getVectorElementType().getSizeInBits()) {
- TP.error("Type inference contradiction found, '" +
- getName() + "' element type not smaller than '" +
- Other.getName() +"'!");
- return false;
- }
- } else
- // For scalar types, the bitsize of this type must be larger
- // than that of the other.
- if (Type.getSizeInBits() >= OtherType.getSizeInBits()) {
- TP.error("Type inference contradiction found, '" +
- getName() + "' is not smaller than '" +
- Other.getName() +"'!");
- return false;
- }
- }
-
-
- // Handle int and fp as disjoint sets. This won't work for patterns
- // that have mixed fp/int types but those are likely rare and would
- // not have been accepted by this code previously.
+ // For vectors we need to ensure that smaller size doesn't produce larger
+ // vector and vice versa.
+ if (isConcrete() && isVector(getConcrete())) {
+ MVT IVT = getConcrete();
+ unsigned Size = IVT.getSizeInBits();
- // Okay, find the smallest type from the current set and remove it from the
- // largest set.
- MVT::SimpleValueType SmallestInt = MVT::LAST_VALUETYPE;
- for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
- if (isInteger(TypeVec[i])) {
- SmallestInt = TypeVec[i];
- break;
- }
- for (unsigned i = 1, e = TypeVec.size(); i != e; ++i)
- if (isInteger(TypeVec[i]) && TypeVec[i] < SmallestInt)
- SmallestInt = TypeVec[i];
+ // Only keep types that have at least as many bits.
+ TypeSet InputSet(Other);
- MVT::SimpleValueType SmallestFP = MVT::LAST_VALUETYPE;
- for (unsigned i = 0, e = TypeVec.size(); i != e; ++i)
- if (isFloatingPoint(TypeVec[i])) {
- SmallestFP = TypeVec[i];
- break;
- }
- for (unsigned i = 1, e = TypeVec.size(); i != e; ++i)
- if (isFloatingPoint(TypeVec[i]) && TypeVec[i] < SmallestFP)
- SmallestFP = TypeVec[i];
-
- int OtherIntSize = 0;
- int OtherFPSize = 0;
- for (SmallVectorImpl<MVT::SimpleValueType>::iterator TVI =
- Other.TypeVec.begin();
- TVI != Other.TypeVec.end();
- /* NULL */) {
- if (isInteger(*TVI)) {
- ++OtherIntSize;
- if (*TVI == SmallestInt) {
- TVI = Other.TypeVec.erase(TVI);
- --OtherIntSize;
+ for (unsigned i = 0; i != Other.TypeVec.size(); ++i) {
+ assert(isVector(Other.TypeVec[i]) && "EnforceVector didn't work");
+ if (MVT(Other.TypeVec[i]).getSizeInBits() < Size) {
+ Other.TypeVec.erase(Other.TypeVec.begin()+i--);
MadeChange = true;
- continue;
}
- } else if (isFloatingPoint(*TVI)) {
- ++OtherFPSize;
- if (*TVI == SmallestFP) {
- TVI = Other.TypeVec.erase(TVI);
- --OtherFPSize;
+ }
+
+ if (Other.TypeVec.empty()) { // FIXME: Really want an SMLoc here!
+ TP.error("Type inference contradiction found, forcing '" +
+ InputSet.getName() + "' to have at least as many bits as " +
+ getName() + "'");
+ return false;
+ }
+ } else if (Other.isConcrete() && isVector(Other.getConcrete())) {
+ MVT IVT = Other.getConcrete();
+ unsigned Size = IVT.getSizeInBits();
+
+ // Only keep types with the same or fewer total bits
+ TypeSet InputSet(*this);
+
+ for (unsigned i = 0; i != TypeVec.size(); ++i) {
+ assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
+ if (MVT(TypeVec[i]).getSizeInBits() > Size) {
+ TypeVec.erase(TypeVec.begin()+i--);
MadeChange = true;
- continue;
}
}
- ++TVI;
+
+ if (TypeVec.empty()) { // FIXME: Really want an SMLoc here!
+ TP.error("Type inference contradiction found, forcing '" +
+ InputSet.getName() + "' to have the same or fewer bits than " +
+ Other.getName() + "'");
+ return false;
+ }
}
- // If this is the only type in the large set, the constraint can never be
- // satisfied.
- if ((Other.hasIntegerTypes() && OtherIntSize == 0) ||
- (Other.hasFloatingPointTypes() && OtherFPSize == 0)) {
- TP.error("Type inference contradiction found, '" +
- Other.getName() + "' has nothing larger than '" + getName() +"'!");
+ // This code does not currently handle nodes which have multiple types,
+ // where some types are integer, and some are fp. Assert that this is not
+ // the case.
+ assert(!(hasIntegerTypes() && hasFloatingPointTypes()) &&
+ !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) &&
+ "SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
+
+ if (TP.hasError())
return false;
+
+ // Okay, find the smallest scalar type from the other set and remove
+ // anything the same or smaller from the current set.
+ TypeSet InputSet(Other);
+ MVT::SimpleValueType Smallest = TypeVec[0];
+ for (unsigned i = 0; i != Other.TypeVec.size(); ++i) {
+ if (Other.TypeVec[i] <= Smallest) {
+ Other.TypeVec.erase(Other.TypeVec.begin()+i--);
+ MadeChange = true;
+ }
}
- // Okay, find the largest type in the Other set and remove it from the
- // current set.
- MVT::SimpleValueType LargestInt = MVT::Other;
- for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i)
- if (isInteger(Other.TypeVec[i])) {
- LargestInt = Other.TypeVec[i];
- break;
- }
- for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
- if (isInteger(Other.TypeVec[i]) && Other.TypeVec[i] > LargestInt)
- LargestInt = Other.TypeVec[i];
-
- MVT::SimpleValueType LargestFP = MVT::Other;
- for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i)
- if (isFloatingPoint(Other.TypeVec[i])) {
- LargestFP = Other.TypeVec[i];
- break;
- }
- for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
- if (isFloatingPoint(Other.TypeVec[i]) && Other.TypeVec[i] > LargestFP)
- LargestFP = Other.TypeVec[i];
-
- int IntSize = 0;
- int FPSize = 0;
- for (SmallVectorImpl<MVT::SimpleValueType>::iterator TVI =
- TypeVec.begin();
- TVI != TypeVec.end();
- /* NULL */) {
- if (isInteger(*TVI)) {
- ++IntSize;
- if (*TVI == LargestInt) {
- TVI = TypeVec.erase(TVI);
- --IntSize;
- MadeChange = true;
- continue;
- }
- } else if (isFloatingPoint(*TVI)) {
- ++FPSize;
- if (*TVI == LargestFP) {
- TVI = TypeVec.erase(TVI);
- --FPSize;
- MadeChange = true;
- continue;
- }
+ if (Other.TypeVec.empty()) {
+ TP.error("Type inference contradiction found, '" + InputSet.getName() +
+ "' has nothing larger than '" + getName() +"'!");
+ return false;
+ }
+
+ // Okay, find the largest scalar type from the other set and remove
+ // anything the same or larger from the current set.
+ InputSet = TypeSet(*this);
+ MVT::SimpleValueType Largest = Other.TypeVec[Other.TypeVec.size()-1];
+ for (unsigned i = 0; i != TypeVec.size(); ++i) {
+ if (TypeVec[i] >= Largest) {
+ TypeVec.erase(TypeVec.begin()+i--);
+ MadeChange = true;
}
- ++TVI;
}
- // If this is the only type in the small set, the constraint can never be
- // satisfied.
- if ((hasIntegerTypes() && IntSize == 0) ||
- (hasFloatingPointTypes() && FPSize == 0)) {
- TP.error("Type inference contradiction found, '" +
- getName() + "' has nothing smaller than '" + Other.getName()+"'!");
+ if (TypeVec.empty()) {
+ TP.error("Type inference contradiction found, '" + InputSet.getName() +
+ "' has nothing smaller than '" + Other.getName() +"'!");
return false;
}
@@ -580,27 +530,78 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand,
/// vector type specified by VTOperand.
bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand,
TreePattern &TP) {
+ if (TP.hasError())
+ return false;
+
// "This" must be a vector and "VTOperand" must be a vector.
bool MadeChange = false;
MadeChange |= EnforceVector(TP);
MadeChange |= VTOperand.EnforceVector(TP);
- // "This" must be larger than "VTOperand."
- MadeChange |= VTOperand.EnforceSmallerThan(*this, TP);
+ // If one side is known to be integer or known to be FP but the other side has
+ // no information, get at least the type integrality info in there.
+ if (!hasFloatingPointTypes())
+ MadeChange |= VTOperand.EnforceInteger(TP);
+ else if (!hasIntegerTypes())
+ MadeChange |= VTOperand.EnforceFloatingPoint(TP);
+ if (!VTOperand.hasFloatingPointTypes())
+ MadeChange |= EnforceInteger(TP);
+ else if (!VTOperand.hasIntegerTypes())
+ MadeChange |= EnforceFloatingPoint(TP);
+
+ assert(!isCompletelyUnknown() && !VTOperand.isCompletelyUnknown() &&
+ "Should have a type list now");
// If we know the vector type, it forces the scalar types to agree.
+ // Also force one vector to have more elements than the other.
if (isConcrete()) {
MVT IVT = getConcrete();
+ unsigned NumElems = IVT.getVectorNumElements();
IVT = IVT.getVectorElementType();
EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP);
MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP);
+
+ // Only keep types that have less elements than VTOperand.
+ TypeSet InputSet(VTOperand);
+
+ for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) {
+ assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work");
+ if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() >= NumElems) {
+ VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--);
+ MadeChange = true;
+ }
+ }
+ if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here!
+ TP.error("Type inference contradiction found, forcing '" +
+ InputSet.getName() + "' to have less vector elements than '" +
+ getName() + "'");
+ return false;
+ }
} else if (VTOperand.isConcrete()) {
MVT IVT = VTOperand.getConcrete();
+ unsigned NumElems = IVT.getVectorNumElements();
IVT = IVT.getVectorElementType();
EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP);
MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP);
+
+ // Only keep types that have more elements than 'this'.
+ TypeSet InputSet(*this);
+
+ for (unsigned i = 0; i != TypeVec.size(); ++i) {
+ assert(isVector(TypeVec[i]) && "EnforceVector didn't work");
+ if (MVT(TypeVec[i]).getVectorNumElements() <= NumElems) {
+ TypeVec.erase(TypeVec.begin()+i--);
+ MadeChange = true;
+ }
+ }
+ if (TypeVec.empty()) { // FIXME: Really want an SMLoc here!
+ TP.error("Type inference contradiction found, forcing '" +
+ InputSet.getName() + "' to have more vector elements than '" +
+ VTOperand.getName() + "'");
+ return false;
+ }
}
return MadeChange;
@@ -1116,6 +1117,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
if (Operator->isSubClassOf("SDNodeXForm"))
return 1; // FIXME: Generalize SDNodeXForm
+ if (Operator->isSubClassOf("ValueType"))
+ return 1; // A type-cast of one result.
+
Operator->dump();
errs() << "Unhandled node in GetNumNodeResults\n";
exit(1);
@@ -1228,8 +1232,10 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
TreePatternNode *Child = getChild(i);
if (Child->isLeaf()) {
Init *Val = Child->getLeafValue();
- if (isa<DefInit>(Val) &&
- cast<DefInit>(Val)->getDef()->getName() == "node") {
+ // Note that, when substituting into an output pattern, Val might be an
+ // UnsetInit.
+ if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) &&
+ cast<DefInit>(Val)->getDef()->getName() == "node")) {
// We found a use of a formal argument, replace it with its value.
TreePatternNode *NewChild = ArgMap[Child->getName()];
assert(NewChild && "Couldn't find formal argument!");
@@ -2131,6 +2137,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) :
ParsePatternFragments();
ParseDefaultOperands();
ParseInstructions();
+ ParsePatternFragments(/*OutFrags*/true);
ParsePatterns();
// Generate variants. For example, commutative patterns can match
@@ -2204,13 +2211,18 @@ void CodeGenDAGPatterns::ParseComplexPatterns() {
/// inline fragments together as necessary, so that there are no references left
/// inside a pattern fragment to a pattern fragment.
///
-void CodeGenDAGPatterns::ParsePatternFragments() {
+void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) {
std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
// First step, parse all of the fragments.
for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+ if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag"))
+ continue;
+
DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
- TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this);
+ TreePattern *P =
+ new TreePattern(Fragments[i], Tree,
+ !Fragments[i]->isSubClassOf("OutPatFrag"), *this);
PatternFragments[Fragments[i]] = P;
// Validate the argument list, converting it to set, to discard duplicates.
@@ -2266,6 +2278,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
// Now that we've parsed all of the tree fragments, do a closure on them so
// that there are not references to PatFrags left inside of them.
for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+ if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag"))
+ continue;
+
TreePattern *ThePat = PatternFragments[Fragments[i]];
ThePat->InlinePatternFragments();
@@ -2312,8 +2327,9 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
/* Resolve all types */;
if (TPN->ContainsUnresolvedType()) {
- PrintFatalError("Value #" + utostr(i) + " of OperandWithDefaultOps '" +
- DefaultOps[i]->getName() +"' doesn't have a concrete type!");
+ PrintFatalError("Value #" + Twine(i) + " of OperandWithDefaultOps '" +
+ DefaultOps[i]->getName() +
+ "' doesn't have a concrete type!");
}
DefaultOpInfo.DefaultOps.push_back(TPN);
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 6fbdd4f..d995329 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -96,6 +96,10 @@ namespace EEVT {
/// a floating point value type.
bool hasFloatingPointTypes() const;
+ /// hasScalarTypes - Return true if this TypeSet contains a scalar value
+ /// type.
+ bool hasScalarTypes() const;
+
/// hasVectorTypes - Return true if this TypeSet contains a vector value
/// type.
bool hasVectorTypes() const;
@@ -805,7 +809,7 @@ private:
void ParseNodeInfo();
void ParseNodeTransforms();
void ParseComplexPatterns();
- void ParsePatternFragments();
+ void ParsePatternFragments(bool OutFrags = false);
void ParseDefaultOperands();
void ParseInstructions();
void ParsePatterns();
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 576388b..5eebb91 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -106,11 +106,11 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
// Check that the operand has a name and that it's unique.
if (ArgName.empty())
- PrintFatalError("In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has no name!");
+ PrintFatalError("In instruction '" + R->getName() + "', operand #" +
+ Twine(i) + " has no name!");
if (!OperandNames.insert(ArgName).second)
- PrintFatalError("In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has the same name as a previous operand!");
+ PrintFatalError("In instruction '" + R->getName() + "', operand #" +
+ Twine(i) + " has the same name as a previous operand!");
OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
OperandType, MIOperandNo, NumOps,
@@ -133,8 +133,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
unsigned OpIdx;
if (hasOperandNamed(Name, OpIdx)) return OpIdx;
- PrintFatalError("'" + TheDef->getName() + "' does not have an operand named '$" +
- Name.str() + "'!");
+ PrintFatalError("'" + TheDef->getName() +
+ "' does not have an operand named '$" + Name + "'!");
}
/// hasOperandNamed - Query whether the instruction has an operand of the
@@ -315,10 +315,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
- mayLoad = R->getValueAsBitOrUnset("mayLoad", mayLoad_Unset);
- mayStore = R->getValueAsBitOrUnset("mayStore", mayStore_Unset);
- hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects",
- hasSideEffects_Unset);
+ bool Unset;
+ mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
+ mayLoad_Unset = Unset;
+ mayStore = R->getValueAsBitOrUnset("mayStore", Unset);
+ mayStore_Unset = Unset;
+ hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset);
+ hasSideEffects_Unset = Unset;
neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
@@ -433,26 +436,33 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
ResultOperand &ResOp) {
Init *Arg = Result->getArg(AliasOpNo);
DefInit *ADI = dyn_cast<DefInit>(Arg);
+ Record *ResultRecord = ADI ? ADI->getDef() : 0;
if (ADI && ADI->getDef() == InstOpRec) {
// If the operand is a record, it must have a name, and the record type
// must match up with the instruction's argument type.
if (Result->getArgName(AliasOpNo).empty())
- PrintFatalError(Loc, "result argument #" + utostr(AliasOpNo) +
- " must have a name!");
- ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef());
+ PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
+ " must have a name!");
+ ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord);
return true;
}
// For register operands, the source register class can be a subclass
// of the instruction register class, not just an exact match.
+ if (InstOpRec->isSubClassOf("RegisterOperand"))
+ InstOpRec = InstOpRec->getValueAsDef("RegClass");
+
+ if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
+ ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
+
if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
if (!InstOpRec->isSubClassOf("RegisterClass"))
return false;
if (!T.getRegisterClass(InstOpRec)
.hasSubClass(&T.getRegisterClass(ADI->getDef())))
return false;
- ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef());
+ ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord);
return true;
}
@@ -465,9 +475,6 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
}
- if (InstOpRec->isSubClassOf("RegisterOperand"))
- InstOpRec = InstOpRec->getValueAsDef("RegClass");
-
if (!InstOpRec->isSubClassOf("RegisterClass"))
return false;
@@ -481,7 +488,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
PrintFatalError(Loc, "result fixed register argument must "
"not have a name!");
- ResOp = ResultOperand(ADI->getDef());
+ ResOp = ResultOperand(ResultRecord);
return true;
}
@@ -507,7 +514,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
return false;
// Integer arguments can't have names.
if (!Result->getArgName(AliasOpNo).empty())
- PrintFatalError(Loc, "result argument #" + utostr(AliasOpNo) +
+ PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
" must not have a name!");
ResOp = ResultOperand(II->getValue());
return true;
@@ -620,14 +627,14 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
ResultInstOperandIndex.push_back(std::make_pair(i, SubOp));
++AliasOpNo;
} else {
- PrintFatalError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+ PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
" does not match instruction operand class " +
(SubOp == 0 ? InstOpRec->getName() :SubRec->getName()));
}
}
continue;
}
- PrintFatalError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+ PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) +
" does not match instruction operand class " +
InstOpRec->getName());
}
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index 6004f66..00d89bf 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -15,7 +15,7 @@
#define CODEGEN_INSTRUCTION_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/SourceMgr.h"
#include <string>
#include <utility>
@@ -215,38 +215,38 @@ namespace llvm {
std::vector<Record*> ImplicitDefs, ImplicitUses;
// Various boolean values we track for the instruction.
- bool isReturn;
- bool isBranch;
- bool isIndirectBranch;
- bool isCompare;
- bool isMoveImm;
- bool isBitcast;
- bool isSelect;
- bool isBarrier;
- bool isCall;
- bool canFoldAsLoad;
- bool mayLoad;
- bool mayLoad_Unset;
- bool mayStore;
- bool mayStore_Unset;
- bool isPredicable;
- bool isConvertibleToThreeAddress;
- bool isCommutable;
- bool isTerminator;
- bool isReMaterializable;
- bool hasDelaySlot;
- bool usesCustomInserter;
- bool hasPostISelHook;
- bool hasCtrlDep;
- bool isNotDuplicable;
- bool hasSideEffects;
- bool hasSideEffects_Unset;
- bool neverHasSideEffects;
- bool isAsCheapAsAMove;
- bool hasExtraSrcRegAllocReq;
- bool hasExtraDefRegAllocReq;
- bool isCodeGenOnly;
- bool isPseudo;
+ bool isReturn : 1;
+ bool isBranch : 1;
+ bool isIndirectBranch : 1;
+ bool isCompare : 1;
+ bool isMoveImm : 1;
+ bool isBitcast : 1;
+ bool isSelect : 1;
+ bool isBarrier : 1;
+ bool isCall : 1;
+ bool canFoldAsLoad : 1;
+ bool mayLoad : 1;
+ bool mayLoad_Unset : 1;
+ bool mayStore : 1;
+ bool mayStore_Unset : 1;
+ bool isPredicable : 1;
+ bool isConvertibleToThreeAddress : 1;
+ bool isCommutable : 1;
+ bool isTerminator : 1;
+ bool isReMaterializable : 1;
+ bool hasDelaySlot : 1;
+ bool usesCustomInserter : 1;
+ bool hasPostISelHook : 1;
+ bool hasCtrlDep : 1;
+ bool isNotDuplicable : 1;
+ bool hasSideEffects : 1;
+ bool hasSideEffects_Unset : 1;
+ bool neverHasSideEffects : 1;
+ bool isAsCheapAsAMove : 1;
+ bool hasExtraSrcRegAllocReq : 1;
+ bool hasExtraDefRegAllocReq : 1;
+ bool isCodeGenOnly : 1;
+ bool isPseudo : 1;
std::string DeprecatedReason;
bool HasComplexDeprecationPredicate;
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index ababfa4..06daa97 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -14,7 +14,7 @@
#ifndef CODEGEN_INTRINSIC_H
#define CODEGEN_INTRINSIC_H
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include <string>
#include <vector>
@@ -73,6 +73,9 @@ namespace llvm {
/// canThrow - True if the intrinsic can throw.
bool canThrow;
+ /// isNoDuplicate - True if the intrinsic is marked as noduplicate.
+ bool isNoDuplicate;
+
/// isNoReturn - True if the intrinsic is no-return.
bool isNoReturn;
diff --git a/utils/TableGen/CodeGenMapTable.cpp b/utils/TableGen/CodeGenMapTable.cpp
index cb7ec3e..b97126b 100644
--- a/utils/TableGen/CodeGenMapTable.cpp
+++ b/utils/TableGen/CodeGenMapTable.cpp
@@ -116,7 +116,7 @@ public:
ColFields = MapRec->getValueAsListInit("ColFields");
// Values for the fields/attributes listed in 'ColFields'.
- // Ex: KeyCol = 'noPred' -- key instruction is non predicated
+ // Ex: KeyCol = 'noPred' -- key instruction is non-predicated
KeyCol = MapRec->getValueAsListInit("KeyCol");
// List of values for the fields/attributes listed in 'ColFields', one for
@@ -384,7 +384,7 @@ unsigned MapTableEmitter::emitBinSearchTable(raw_ostream &OS) {
OutStr += TargetName;
OutStr += "::";
OutStr += ColInstrs[j]->getName();
- } else { OutStr += ", -1";}
+ } else { OutStr += ", (uint16_t)-1U";}
}
if (RelExists) {
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index f2eef4f..e0e0b62 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -550,7 +550,7 @@ unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const {
// registers.
namespace {
struct TupleExpander : SetTheory::Expander {
- void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) {
+ void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) override {
std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices");
unsigned Dim = Indices.size();
ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
@@ -712,7 +712,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
unsigned Size = R->getValueAsInt("Size");
Namespace = R->getValueAsString("Namespace");
- SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
+ SpillSize = Size ? Size : MVT(VTs[0]).getSizeInBits();
SpillAlignment = R->getValueAsInt("Alignment");
CopyCost = R->getValueAsInt("CopyCost");
Allocatable = R->getValueAsBit("isAllocatable");
@@ -782,11 +782,8 @@ namespace llvm {
bool CodeGenRegisterClass::Key::
operator<(const CodeGenRegisterClass::Key &B) const {
assert(Members && B.Members);
- if (*Members != *B.Members)
- return *Members < *B.Members;
- if (SpillSize != B.SpillSize)
- return SpillSize < B.SpillSize;
- return SpillAlignment < B.SpillAlignment;
+ return std::tie(*Members, SpillSize, SpillAlignment) <
+ std::tie(*B.Members, B.SpillSize, B.SpillAlignment);
}
// Returns true if RC is a strict subclass.
@@ -996,7 +993,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) {
// Read in register class definitions.
std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass");
if (RCs.empty())
- PrintFatalError(std::string("No 'RegisterClass' subclasses defined!"));
+ PrintFatalError("No 'RegisterClass' subclasses defined!");
// Allocate user-defined register classes.
RegClasses.reserve(RCs.size());
@@ -1271,7 +1268,7 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
assert(USetID && "register number 0 is invalid");
AllocatableRegs.insert((*Regs.begin())->EnumValue);
- for (CodeGenRegister::Set::const_iterator I = llvm::next(Regs.begin()),
+ for (CodeGenRegister::Set::const_iterator I = std::next(Regs.begin()),
E = Regs.end(); I != E; ++I) {
AllocatableRegs.insert((*I)->EnumValue);
UberSetIDs.join(USetID, (*I)->EnumValue);
@@ -1311,7 +1308,7 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
static void computeUberWeights(std::vector<UberRegSet> &UberSets,
CodeGenRegBank &RegBank) {
// Skip the first unallocatable set.
- for (std::vector<UberRegSet>::iterator I = llvm::next(UberSets.begin()),
+ for (std::vector<UberRegSet>::iterator I = std::next(UberSets.begin()),
E = UberSets.end(); I != E; ++I) {
// Initialize all unit weights in this set, and remember the max units/reg.
@@ -1552,7 +1549,7 @@ void CodeGenRegBank::computeRegUnitSets() {
// Find an existing RegUnitSet.
std::vector<RegUnitSet>::const_iterator SetI =
findRegUnitSet(RegUnitSets, RegUnitSets.back());
- if (SetI != llvm::prior(RegUnitSets.end()))
+ if (SetI != std::prev(RegUnitSets.end()))
RegUnitSets.pop_back();
}
@@ -1617,7 +1614,7 @@ void CodeGenRegBank::computeRegUnitSets() {
// Find an existing RegUnitSet, or add the union to the unique sets.
std::vector<RegUnitSet>::const_iterator SetI =
findRegUnitSet(RegUnitSets, RegUnitSets.back());
- if (SetI != llvm::prior(RegUnitSets.end()))
+ if (SetI != std::prev(RegUnitSets.end()))
RegUnitSets.pop_back();
else {
DEBUG(dbgs() << "UnitSet " << RegUnitSets.size()-1
@@ -1705,16 +1702,6 @@ void CodeGenRegBank::computeRegUnitSets() {
}
}
-struct LessUnits {
- const CodeGenRegBank &RegBank;
- LessUnits(const CodeGenRegBank &RB): RegBank(RB) {}
-
- bool operator()(unsigned ID1, unsigned ID2) {
- return RegBank.getRegPressureSet(ID1).Units.size()
- < RegBank.getRegPressureSet(ID2).Units.size();
- }
-};
-
void CodeGenRegBank::computeDerivedInfo() {
computeComposites();
computeSubRegIndexLaneMasks();
@@ -1737,7 +1724,10 @@ void CodeGenRegBank::computeDerivedInfo() {
RegUnitSetOrder.push_back(Idx);
std::stable_sort(RegUnitSetOrder.begin(), RegUnitSetOrder.end(),
- LessUnits(*this));
+ [this](unsigned ID1, unsigned ID2) {
+ return getRegPressureSet(ID1).Units.size() <
+ getRegPressureSet(ID2).Units.size();
+ });
for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
RegUnitSets[RegUnitSetOrder[Idx]].Order = Idx;
}
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 37f75b4..03ffb43 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -20,7 +20,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Record.h"
#include <cstdlib>
@@ -335,7 +335,7 @@ namespace llvm {
// getSubClasses - Returns a constant BitVector of subclasses indexed by
// EnumValue.
- // The SubClasses vector includs an entry for this class.
+ // The SubClasses vector includes an entry for this class.
const BitVector &getSubClasses() const { return SubClasses; }
// getSuperClasses - Returns a list of super classes ordered by EnumValue.
@@ -374,11 +374,6 @@ namespace llvm {
unsigned SpillSize;
unsigned SpillAlignment;
- Key(const Key &O)
- : Members(O.Members),
- SpillSize(O.SpillSize),
- SpillAlignment(O.SpillAlignment) {}
-
Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0)
: Members(M), SpillSize(S), SpillAlignment(A) {}
diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp
index dd06433..a07524d 100644
--- a/utils/TableGen/CodeGenSchedule.cpp
+++ b/utils/TableGen/CodeGenSchedule.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines structures to encapsulate the machine model as decribed in
+// This file defines structures to encapsulate the machine model as described in
// the target description.
//
//===----------------------------------------------------------------------===//
@@ -39,8 +39,8 @@ static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
namespace {
// (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp.
struct InstrsOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
}
};
@@ -58,7 +58,7 @@ struct InstRegexOp : public SetTheory::Operator {
InstRegexOp(const CodeGenTarget &t): Target(t) {}
void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ ArrayRef<SMLoc> Loc) override {
SmallVector<Regex*, 4> RegexList;
for (DagInit::const_arg_iterator
AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) {
@@ -1473,11 +1473,23 @@ void CodeGenSchedModels::collectProcResources() {
Record *ModelDef = (*WRI)->getValueAsDef("SchedModel");
addWriteRes(*WRI, getProcModel(ModelDef).Index);
}
+ RecVec SWRDefs = Records.getAllDerivedDefinitions("SchedWriteRes");
+ for (RecIter WRI = SWRDefs.begin(), WRE = SWRDefs.end(); WRI != WRE; ++WRI) {
+ Record *ModelDef = (*WRI)->getValueAsDef("SchedModel");
+ addWriteRes(*WRI, getProcModel(ModelDef).Index);
+ }
RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance");
for (RecIter RAI = RADefs.begin(), RAE = RADefs.end(); RAI != RAE; ++RAI) {
Record *ModelDef = (*RAI)->getValueAsDef("SchedModel");
addReadAdvance(*RAI, getProcModel(ModelDef).Index);
}
+ RecVec SRADefs = Records.getAllDerivedDefinitions("SchedReadAdvance");
+ for (RecIter RAI = SRADefs.begin(), RAE = SRADefs.end(); RAI != RAE; ++RAI) {
+ if ((*RAI)->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = (*RAI)->getValueAsDef("SchedModel");
+ addReadAdvance(*RAI, getProcModel(ModelDef).Index);
+ }
+ }
// Add ProcResGroups that are defined within this processor model, which may
// not be directly referenced but may directly specify a buffer size.
RecVec ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h
index fa964cf..5ce679a 100644
--- a/utils/TableGen/CodeGenSchedule.h
+++ b/utils/TableGen/CodeGenSchedule.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines structures to encapsulate the machine model as decribed in
+// This file defines structures to encapsulate the machine model as described in
// the target description.
//
//===----------------------------------------------------------------------===//
@@ -162,7 +162,7 @@ struct CodeGenSchedClass {
// ModelName is a unique name used to name an instantiation of MCSchedModel.
//
// ModelDef is NULL for inferred Models. This happens when a processor defines
-// an itinerary but no machine model. If the processer defines neither a machine
+// an itinerary but no machine model. If the processor defines neither a machine
// model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has
// the special "NoModel" field set to true.
//
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index dd17059..dd9c23c 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -143,6 +143,7 @@ CodeGenTarget::CodeGenTarget(RecordKeeper &records)
}
CodeGenTarget::~CodeGenTarget() {
+ DeleteContainerSeconds(Instructions);
delete RegBank;
delete SchedModels;
}
@@ -172,7 +173,8 @@ Record *CodeGenTarget::getInstructionSet() const {
Record *CodeGenTarget::getAsmParser() const {
std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
if (AsmParserNum >= LI.size())
- PrintFatalError("Target does not have an AsmParser #" + utostr(AsmParserNum) + "!");
+ PrintFatalError("Target does not have an AsmParser #" +
+ Twine(AsmParserNum) + "!");
return LI[AsmParserNum];
}
@@ -183,7 +185,8 @@ Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
std::vector<Record*> LI =
TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
if (i >= LI.size())
- PrintFatalError("Target does not have an AsmParserVariant #" + utostr(i) + "!");
+ PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
+ "!");
return LI[i];
}
@@ -201,7 +204,8 @@ unsigned CodeGenTarget::getAsmParserVariantCount() const {
Record *CodeGenTarget::getAsmWriter() const {
std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
if (AsmWriterNum >= LI.size())
- PrintFatalError("Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!");
+ PrintFatalError("Target does not have an AsmWriter #" +
+ Twine(AsmWriterNum) + "!");
return LI[AsmWriterNum];
}
@@ -284,47 +288,20 @@ GetInstByName(const char *Name,
DenseMap<const Record*, CodeGenInstruction*>::const_iterator
I = Insts.find(Rec);
if (Rec == 0 || I == Insts.end())
- PrintFatalError(std::string("Could not find '") + Name + "' instruction!");
+ PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
return I->second;
}
-namespace {
-/// SortInstByName - Sorting predicate to sort instructions by name.
-///
-struct SortInstByName {
- bool operator()(const CodeGenInstruction *Rec1,
- const CodeGenInstruction *Rec2) const {
- return Rec1->TheDef->getName() < Rec2->TheDef->getName();
- }
-};
-}
-
-/// getInstructionsByEnumValue - Return all of the instructions defined by the
-/// target, ordered by their enum value.
+/// \brief Return all of the instructions defined by the target, ordered by
+/// their enum value.
void CodeGenTarget::ComputeInstrsByEnum() const {
// The ordering here must match the ordering in TargetOpcodes.h.
static const char *const FixedInstrs[] = {
- "PHI",
- "INLINEASM",
- "PROLOG_LABEL",
- "EH_LABEL",
- "GC_LABEL",
- "KILL",
- "EXTRACT_SUBREG",
- "INSERT_SUBREG",
- "IMPLICIT_DEF",
- "SUBREG_TO_REG",
- "COPY_TO_REGCLASS",
- "DBG_VALUE",
- "REG_SEQUENCE",
- "COPY",
- "BUNDLE",
- "LIFETIME_START",
- "LIFETIME_END",
- "STACKMAP",
- "PATCHPOINT",
- 0
- };
+ "PHI", "INLINEASM", "CFI_INSTRUCTION", "EH_LABEL",
+ "GC_LABEL", "KILL", "EXTRACT_SUBREG", "INSERT_SUBREG",
+ "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
+ "REG_SEQUENCE", "COPY", "BUNDLE", "LIFETIME_START",
+ "LIFETIME_END", "STACKMAP", "PATCHPOINT", 0};
const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
for (const char *const *p = FixedInstrs; *p; ++p) {
const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
@@ -345,8 +322,10 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
// All of the instructions are now in random order based on the map iteration.
// Sort them by name.
- std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
- SortInstByName());
+ std::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
+ [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
+ return Rec1->TheDef->getName() < Rec2->TheDef->getName();
+ });
}
@@ -357,6 +336,46 @@ bool CodeGenTarget::isLittleEndianEncoding() const {
return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
}
+/// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
+/// encodings, reverse the bit order of all instructions.
+void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
+ if (!isLittleEndianEncoding())
+ return;
+
+ std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
+ for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
+ I != E; ++I) {
+ Record *R = *I;
+ if (R->getValueAsString("Namespace") == "TargetOpcode" ||
+ R->getValueAsBit("isPseudo"))
+ continue;
+
+ BitsInit *BI = R->getValueAsBitsInit("Inst");
+
+ unsigned numBits = BI->getNumBits();
+
+ SmallVector<Init *, 16> NewBits(numBits);
+
+ for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
+ unsigned bitSwapIdx = numBits - bit - 1;
+ Init *OrigBit = BI->getBit(bit);
+ Init *BitSwap = BI->getBit(bitSwapIdx);
+ NewBits[bit] = BitSwap;
+ NewBits[bitSwapIdx] = OrigBit;
+ }
+ if (numBits % 2) {
+ unsigned middle = (numBits + 1) / 2;
+ NewBits[middle] = BI->getBit(middle);
+ }
+
+ BitsInit *NewBI = BitsInit::get(NewBits);
+
+ // Update the bits in reversed order so that emitInstrOpBits will get the
+ // correct endianness.
+ R->getValue("Inst")->setValue(NewBI);
+ }
+}
+
/// guessInstructionProperties - Return true if it's OK to guess instruction
/// properties instead of raising an error.
///
@@ -430,6 +449,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
isCommutative = false;
canThrow = false;
isNoReturn = false;
+ isNoDuplicate = false;
if (DefName.size() <= 4 ||
std::string(DefName.begin(), DefName.begin() + 4) != "int_")
@@ -481,14 +501,14 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
- assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
- !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else {
VT = getValueType(TyEl->getValueAsDef("VT"));
}
- if (EVT(VT).isOverloaded()) {
+ if (MVT(VT).isOverloaded()) {
OverloadedVTs.push_back(VT);
isOverloaded = true;
}
@@ -515,14 +535,14 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
// It only makes sense to use the extended and truncated vector element
// variants with iAny types; otherwise, if the intrinsic is not
// overloaded, all the types can be specified directly.
- assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
- !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedType")) ||
VT == MVT::iAny || VT == MVT::vAny) &&
"Expected iAny or vAny type");
} else
VT = getValueType(TyEl->getValueAsDef("VT"));
- if (EVT(VT).isOverloaded()) {
+ if (MVT(VT).isOverloaded()) {
OverloadedVTs.push_back(VT);
isOverloaded = true;
}
@@ -554,6 +574,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
isCommutative = true;
else if (Property->getName() == "Throws")
canThrow = true;
+ else if (Property->getName() == "IntrNoDuplicate")
+ isNoDuplicate = true;
else if (Property->getName() == "IntrNoReturn")
isNoReturn = true;
else if (Property->isSubClassOf("NoCapture")) {
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index 6271443..d6458f4 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -177,6 +177,10 @@ public:
///
bool isLittleEndianEncoding() const;
+ /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
+ /// encodings, reverse the bit order of all instructions.
+ void reverseBitsForLittleEndianEncoding();
+
/// guessInstructionProperties - should we just guess unset instruction
/// properties?
bool guessInstructionProperties() const;
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index a76ea32..9294cd5 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -155,8 +155,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
}
}
- Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
- PatternMatchers.size());
+ Matcher *TheMatcher = new ScopeMatcher(PatternMatchers);
TheMatcher = OptimizeMatcher(TheMatcher, CGP);
//Matcher->dump();
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index 5d6a11a..2557bb6 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -84,6 +84,15 @@ ScopeMatcher::~ScopeMatcher() {
delete Children[i];
}
+SwitchOpcodeMatcher::~SwitchOpcodeMatcher() {
+ for (unsigned i = 0, e = Cases.size(); i != e; ++i)
+ delete Cases[i].second;
+}
+
+SwitchTypeMatcher::~SwitchTypeMatcher() {
+ for (unsigned i = 0, e = Cases.size(); i != e; ++i)
+ delete Cases[i].second;
+}
CheckPredicateMatcher::CheckPredicateMatcher(const TreePredicateFn &pred)
: Matcher(CheckPredicate), Pred(pred.getOrigPatFragRecord()) {}
@@ -185,6 +194,11 @@ void CheckIntegerMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckInteger " << Value << '\n';
}
+void CheckChildIntegerMatcher::printImpl(raw_ostream &OS,
+ unsigned indent) const {
+ OS.indent(indent) << "CheckChildInteger " << ChildNo << " " << Value << '\n';
+}
+
void CheckCondCodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
}
@@ -411,6 +425,18 @@ bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
return false;
}
+bool CheckChildIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const CheckChildIntegerMatcher *CCIM = dyn_cast<CheckChildIntegerMatcher>(M)) {
+ // If the two checks are about different nodes, we don't know if they
+ // conflict!
+ if (CCIM->getChildNo() != getChildNo())
+ return false;
+
+ return CCIM->getValue() != getValue();
+ }
+ return false;
+}
+
bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
return CVT->getTypeName() != getTypeName();
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index 70031fa..56a571f 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -10,10 +10,10 @@
#ifndef TBLGEN_DAGISELMATCHER_H
#define TBLGEN_DAGISELMATCHER_H
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/Casting.h"
namespace llvm {
@@ -40,7 +40,7 @@ void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
class Matcher {
// The next matcher node that is executed after this one. Null if this is the
// last stage of a match.
- OwningPtr<Matcher> Next;
+ std::unique_ptr<Matcher> Next;
virtual void anchor();
public:
enum KindTy {
@@ -64,6 +64,7 @@ public:
SwitchType, // Dispatch based on type.
CheckChildType, // Fail if child has wrong type.
CheckInteger, // Fail if wrong val.
+ CheckChildInteger, // Fail if child is wrong val.
CheckCondCode, // Fail if not condcode.
CheckValueType,
CheckComplexPat,
@@ -96,9 +97,9 @@ public:
Matcher *getNext() { return Next.get(); }
const Matcher *getNext() const { return Next.get(); }
void setNext(Matcher *C) { Next.reset(C); }
- Matcher *takeNext() { return Next.take(); }
+ Matcher *takeNext() { return Next.release(); }
- OwningPtr<Matcher> &getNextPtr() { return Next; }
+ std::unique_ptr<Matcher> &getNextPtr() { return Next; }
bool isEqual(const Matcher *M) const {
if (getKind() != M->getKind()) return false;
@@ -130,6 +131,7 @@ public:
case CheckType:
case CheckChildType:
case CheckInteger:
+ case CheckChildInteger:
case CheckCondCode:
case CheckValueType:
case CheckAndImm:
@@ -188,8 +190,8 @@ protected:
class ScopeMatcher : public Matcher {
SmallVector<Matcher*, 4> Children;
public:
- ScopeMatcher(Matcher *const *children, unsigned numchildren)
- : Matcher(Scope), Children(children, children+numchildren) {
+ ScopeMatcher(ArrayRef<Matcher *> children)
+ : Matcher(Scope), Children(children.begin(), children.end()) {
}
virtual ~ScopeMatcher();
@@ -223,9 +225,9 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return false; }
- virtual unsigned getHashImpl() const { return 12312; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return false; }
+ unsigned getHashImpl() const override { return 12312; }
};
/// RecordMatcher - Save the current node in the operand list.
@@ -248,11 +250,11 @@ public:
return N->getKind() == RecordNode;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return true; }
- virtual unsigned getHashImpl() const { return 0; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return true; }
+ unsigned getHashImpl() const override { return 0; }
};
/// RecordChildMatcher - Save a numbered child of the current node, or fail
@@ -282,14 +284,14 @@ public:
return N->getKind() == RecordChild;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo();
}
- virtual unsigned getHashImpl() const { return getChildNo(); }
+ unsigned getHashImpl() const override { return getChildNo(); }
};
/// RecordMemRefMatcher - Save the current node's memref.
@@ -301,12 +303,12 @@ public:
return N->getKind() == RecordMemRef;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return true; }
- virtual unsigned getHashImpl() const { return 0; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return true; }
+ unsigned getHashImpl() const override { return 0; }
};
@@ -320,12 +322,12 @@ public:
return N->getKind() == CaptureGlueInput;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return true; }
- virtual unsigned getHashImpl() const { return 0; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return true; }
+ unsigned getHashImpl() const override { return 0; }
};
/// MoveChildMatcher - This tells the interpreter to move into the
@@ -341,14 +343,14 @@ public:
return N->getKind() == MoveChild;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo();
}
- virtual unsigned getHashImpl() const { return getChildNo(); }
+ unsigned getHashImpl() const override { return getChildNo(); }
};
/// MoveParentMatcher - This tells the interpreter to move to the parent
@@ -361,12 +363,12 @@ public:
return N->getKind() == MoveParent;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return true; }
- virtual unsigned getHashImpl() const { return 0; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return true; }
+ unsigned getHashImpl() const override { return 0; }
};
/// CheckSameMatcher - This checks to see if this node is exactly the same
@@ -384,14 +386,14 @@ public:
return N->getKind() == CheckSame;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber();
}
- virtual unsigned getHashImpl() const { return getMatchNumber(); }
+ unsigned getHashImpl() const override { return getMatchNumber(); }
};
/// CheckChildSameMatcher - This checks to see if child node is exactly the same
@@ -411,15 +413,15 @@ public:
return N->getKind() == CheckChildSame;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckChildSameMatcher>(M)->ChildNo == ChildNo &&
cast<CheckChildSameMatcher>(M)->MatchNumber == MatchNumber;
}
- virtual unsigned getHashImpl() const { return (MatchNumber << 2) | ChildNo; }
+ unsigned getHashImpl() const override { return (MatchNumber << 2) | ChildNo; }
};
/// CheckPatternPredicateMatcher - This checks the target-specific predicate
@@ -437,14 +439,14 @@ public:
return N->getKind() == CheckPatternPredicate;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
/// CheckPredicateMatcher - This checks the target-specific predicate to
@@ -464,11 +466,11 @@ public:
//virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckPredicateMatcher>(M)->Pred == Pred;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
@@ -486,13 +488,13 @@ public:
return N->getKind() == CheckOpcode;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const;
- virtual unsigned getHashImpl() const;
- virtual bool isContradictoryImpl(const Matcher *M) const;
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override;
+ unsigned getHashImpl() const override;
+ bool isContradictoryImpl(const Matcher *M) const override;
};
/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
@@ -502,9 +504,9 @@ private:
class SwitchOpcodeMatcher : public Matcher {
SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
public:
- SwitchOpcodeMatcher(const std::pair<const SDNodeInfo*, Matcher*> *cases,
- unsigned numcases)
- : Matcher(SwitchOpcode), Cases(cases, cases+numcases) {}
+ SwitchOpcodeMatcher(ArrayRef<std::pair<const SDNodeInfo*, Matcher*> > cases)
+ : Matcher(SwitchOpcode), Cases(cases.begin(), cases.end()) {}
+ virtual ~SwitchOpcodeMatcher();
static inline bool classof(const Matcher *N) {
return N->getKind() == SwitchOpcode;
@@ -517,9 +519,9 @@ public:
const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return false; }
- virtual unsigned getHashImpl() const { return 4123; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return false; }
+ unsigned getHashImpl() const override { return 4123; }
};
/// CheckTypeMatcher - This checks to see if the current node has the
@@ -538,15 +540,15 @@ public:
return N->getKind() == CheckType;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckTypeMatcher>(M)->Type == Type;
}
- virtual unsigned getHashImpl() const { return Type; }
- virtual bool isContradictoryImpl(const Matcher *M) const;
+ unsigned getHashImpl() const override { return Type; }
+ bool isContradictoryImpl(const Matcher *M) const override;
};
/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
@@ -556,9 +558,9 @@ private:
class SwitchTypeMatcher : public Matcher {
SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
public:
- SwitchTypeMatcher(const std::pair<MVT::SimpleValueType, Matcher*> *cases,
- unsigned numcases)
- : Matcher(SwitchType), Cases(cases, cases+numcases) {}
+ SwitchTypeMatcher(ArrayRef<std::pair<MVT::SimpleValueType, Matcher*> > cases)
+ : Matcher(SwitchType), Cases(cases.begin(), cases.end()) {}
+ virtual ~SwitchTypeMatcher();
static inline bool classof(const Matcher *N) {
return N->getKind() == SwitchType;
@@ -571,9 +573,9 @@ public:
const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return false; }
- virtual unsigned getHashImpl() const { return 4123; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return false; }
+ unsigned getHashImpl() const override { return 4123; }
};
@@ -593,16 +595,16 @@ public:
return N->getKind() == CheckChildType;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo &&
cast<CheckChildTypeMatcher>(M)->Type == Type;
}
- virtual unsigned getHashImpl() const { return (Type << 3) | ChildNo; }
- virtual bool isContradictoryImpl(const Matcher *M) const;
+ unsigned getHashImpl() const override { return (Type << 3) | ChildNo; }
+ bool isContradictoryImpl(const Matcher *M) const override;
};
@@ -620,15 +622,43 @@ public:
return N->getKind() == CheckInteger;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckIntegerMatcher>(M)->Value == Value;
}
- virtual unsigned getHashImpl() const { return Value; }
- virtual bool isContradictoryImpl(const Matcher *M) const;
+ unsigned getHashImpl() const override { return Value; }
+ bool isContradictoryImpl(const Matcher *M) const override;
+};
+
+/// CheckChildIntegerMatcher - This checks to see if the child node is a
+/// ConstantSDNode with a specified integer value, if not it fails to match.
+class CheckChildIntegerMatcher : public Matcher {
+ unsigned ChildNo;
+ int64_t Value;
+public:
+ CheckChildIntegerMatcher(unsigned childno, int64_t value)
+ : Matcher(CheckChildInteger), ChildNo(childno), Value(value) {}
+
+ unsigned getChildNo() const { return ChildNo; }
+ int64_t getValue() const { return Value; }
+
+ static inline bool classof(const Matcher *N) {
+ return N->getKind() == CheckChildInteger;
+ }
+
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
+
+private:
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
+ return cast<CheckChildIntegerMatcher>(M)->ChildNo == ChildNo &&
+ cast<CheckChildIntegerMatcher>(M)->Value == Value;
+ }
+ unsigned getHashImpl() const override { return (Value << 3) | ChildNo; }
+ bool isContradictoryImpl(const Matcher *M) const override;
};
/// CheckCondCodeMatcher - This checks to see if the current node is a
@@ -645,14 +675,14 @@ public:
return N->getKind() == CheckCondCode;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
/// CheckValueTypeMatcher - This checks to see if the current node is a
@@ -669,15 +699,15 @@ public:
return N->getKind() == CheckValueType;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName;
}
- virtual unsigned getHashImpl() const;
- bool isContradictoryImpl(const Matcher *M) const;
+ unsigned getHashImpl() const override;
+ bool isContradictoryImpl(const Matcher *M) const override;
};
@@ -714,15 +744,15 @@ public:
}
// Not safe to move a pattern predicate past a complex pattern.
- virtual bool isSafeToReorderWithPatternPredicate() const { return false; }
+ bool isSafeToReorderWithPatternPredicate() const override { return false; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
}
- virtual unsigned getHashImpl() const {
+ unsigned getHashImpl() const override {
return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
}
};
@@ -741,14 +771,14 @@ public:
return N->getKind() == CheckAndImm;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckAndImmMatcher>(M)->Value == Value;
}
- virtual unsigned getHashImpl() const { return Value; }
+ unsigned getHashImpl() const override { return Value; }
};
/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
@@ -765,14 +795,14 @@ public:
return N->getKind() == CheckOrImm;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CheckOrImmMatcher>(M)->Value == Value;
}
- virtual unsigned getHashImpl() const { return Value; }
+ unsigned getHashImpl() const override { return Value; }
};
/// CheckFoldableChainNodeMatcher - This checks to see if the current node
@@ -786,12 +816,12 @@ public:
return N->getKind() == CheckFoldableChainNode;
}
- virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
+ bool isSafeToReorderWithPatternPredicate() const override { return true; }
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const { return true; }
- virtual unsigned getHashImpl() const { return 0; }
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override { return true; }
+ unsigned getHashImpl() const override { return 0; }
};
/// EmitIntegerMatcher - This creates a new TargetConstant.
@@ -810,12 +840,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitIntegerMatcher>(M)->Val == Val &&
cast<EmitIntegerMatcher>(M)->VT == VT;
}
- virtual unsigned getHashImpl() const { return (Val << 4) | VT; }
+ unsigned getHashImpl() const override { return (Val << 4) | VT; }
};
/// EmitStringIntegerMatcher - A target constant whose value is represented
@@ -835,12 +865,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitStringIntegerMatcher>(M)->Val == Val &&
cast<EmitStringIntegerMatcher>(M)->VT == VT;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
/// EmitRegisterMatcher - This creates a new TargetConstant.
@@ -861,12 +891,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitRegisterMatcher>(M)->Reg == Reg &&
cast<EmitRegisterMatcher>(M)->VT == VT;
}
- virtual unsigned getHashImpl() const {
+ unsigned getHashImpl() const override {
return ((unsigned)(intptr_t)Reg) << 4 | VT;
}
};
@@ -887,11 +917,11 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot;
}
- virtual unsigned getHashImpl() const { return Slot; }
+ unsigned getHashImpl() const override { return Slot; }
};
/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
@@ -901,8 +931,8 @@ private:
class EmitMergeInputChainsMatcher : public Matcher {
SmallVector<unsigned, 3> ChainNodes;
public:
- EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes)
- : Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
+ EmitMergeInputChainsMatcher(ArrayRef<unsigned> nodes)
+ : Matcher(EmitMergeInputChains), ChainNodes(nodes.begin(), nodes.end()) {}
unsigned getNumNodes() const { return ChainNodes.size(); }
@@ -916,11 +946,11 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
@@ -941,12 +971,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot &&
cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg;
}
- virtual unsigned getHashImpl() const {
+ unsigned getHashImpl() const override {
return SrcSlot ^ ((unsigned)(intptr_t)DestPhysReg << 4);
}
};
@@ -970,12 +1000,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<EmitNodeXFormMatcher>(M)->Slot == Slot &&
cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm;
}
- virtual unsigned getHashImpl() const {
+ unsigned getHashImpl() const override {
return Slot ^ ((unsigned)(intptr_t)NodeXForm << 4);
}
};
@@ -994,13 +1024,13 @@ class EmitNodeMatcherCommon : public Matcher {
int NumFixedArityOperands;
public:
EmitNodeMatcherCommon(const std::string &opcodeName,
- const MVT::SimpleValueType *vts, unsigned numvts,
- const unsigned *operands, unsigned numops,
+ ArrayRef<MVT::SimpleValueType> vts,
+ ArrayRef<unsigned> operands,
bool hasChain, bool hasInGlue, bool hasOutGlue,
bool hasmemrefs,
int numfixedarityoperands, bool isMorphNodeTo)
: Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName),
- VTs(vts, vts+numvts), Operands(operands, operands+numops),
+ VTs(vts.begin(), vts.end()), Operands(operands.begin(), operands.end()),
HasChain(hasChain), HasInGlue(hasInGlue), HasOutGlue(hasOutGlue),
HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}
@@ -1033,23 +1063,23 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const;
- virtual unsigned getHashImpl() const;
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override;
+ unsigned getHashImpl() const override;
};
/// EmitNodeMatcher - This signals a successful match and generates a node.
class EmitNodeMatcher : public EmitNodeMatcherCommon {
- virtual void anchor();
+ void anchor() override;
unsigned FirstResultSlot;
public:
EmitNodeMatcher(const std::string &opcodeName,
- const MVT::SimpleValueType *vts, unsigned numvts,
- const unsigned *operands, unsigned numops,
+ ArrayRef<MVT::SimpleValueType> vts,
+ ArrayRef<unsigned> operands,
bool hasChain, bool hasInFlag, bool hasOutFlag,
bool hasmemrefs,
int numfixedarityoperands, unsigned firstresultslot)
- : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+ : EmitNodeMatcherCommon(opcodeName, vts, operands, hasChain,
hasInFlag, hasOutFlag, hasmemrefs,
numfixedarityoperands, false),
FirstResultSlot(firstresultslot) {}
@@ -1063,16 +1093,16 @@ public:
};
class MorphNodeToMatcher : public EmitNodeMatcherCommon {
- virtual void anchor();
+ void anchor() override;
const PatternToMatch &Pattern;
public:
MorphNodeToMatcher(const std::string &opcodeName,
- const MVT::SimpleValueType *vts, unsigned numvts,
- const unsigned *operands, unsigned numops,
+ ArrayRef<MVT::SimpleValueType> vts,
+ ArrayRef<unsigned> operands,
bool hasChain, bool hasInFlag, bool hasOutFlag,
bool hasmemrefs,
int numfixedarityoperands, const PatternToMatch &pattern)
- : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
+ : EmitNodeMatcherCommon(opcodeName, vts, operands, hasChain,
hasInFlag, hasOutFlag, hasmemrefs,
numfixedarityoperands, true),
Pattern(pattern) {
@@ -1091,8 +1121,8 @@ public:
class MarkGlueResultsMatcher : public Matcher {
SmallVector<unsigned, 3> GlueResultNodes;
public:
- MarkGlueResultsMatcher(const unsigned *nodes, unsigned NumNodes)
- : Matcher(MarkGlueResults), GlueResultNodes(nodes, nodes+NumNodes) {}
+ MarkGlueResultsMatcher(ArrayRef<unsigned> nodes)
+ : Matcher(MarkGlueResults), GlueResultNodes(nodes.begin(), nodes.end()) {}
unsigned getNumNodes() const { return GlueResultNodes.size(); }
@@ -1106,11 +1136,11 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<MarkGlueResultsMatcher>(M)->GlueResultNodes == GlueResultNodes;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
/// CompleteMatchMatcher - Complete a match by replacing the results of the
@@ -1120,9 +1150,9 @@ class CompleteMatchMatcher : public Matcher {
SmallVector<unsigned, 2> Results;
const PatternToMatch &Pattern;
public:
- CompleteMatchMatcher(const unsigned *results, unsigned numresults,
+ CompleteMatchMatcher(ArrayRef<unsigned> results,
const PatternToMatch &pattern)
- : Matcher(CompleteMatch), Results(results, results+numresults),
+ : Matcher(CompleteMatch), Results(results.begin(), results.end()),
Pattern(pattern) {}
unsigned getNumResults() const { return Results.size(); }
@@ -1134,12 +1164,12 @@ public:
}
private:
- virtual void printImpl(raw_ostream &OS, unsigned indent) const;
- virtual bool isEqualImpl(const Matcher *M) const {
+ void printImpl(raw_ostream &OS, unsigned indent) const override;
+ bool isEqualImpl(const Matcher *M) const override {
return cast<CompleteMatchMatcher>(M)->Results == Results &&
&cast<CompleteMatchMatcher>(M)->Pattern == &Pattern;
}
- virtual unsigned getHashImpl() const;
+ unsigned getHashImpl() const override;
};
} // end namespace llvm
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 04fe0d1..416e8e3 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -332,7 +332,6 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
// Emit the VBR.
CurrentIdx += EmitVBRValue(ChildSize, OS);
- OS << ' ';
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
else
@@ -379,6 +378,14 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
OS << '\n';
return Bytes;
}
+ case Matcher::CheckChildInteger: {
+ OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
+ << "Integer, ";
+ unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
+ OS);
+ OS << '\n';
+ return Bytes;
+ }
case Matcher::CheckCondCode:
OS << "OPC_CheckCondCode, ISD::"
<< cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
@@ -608,7 +615,7 @@ EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
// Emit pattern predicates.
if (!PatternPredicates.empty()) {
- OS << "virtual bool CheckPatternPredicate(unsigned PredNo) const {\n";
+ OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n";
OS << " switch (PredNo) {\n";
OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
@@ -626,8 +633,8 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
PFsByName[I->first->getName()] = I->second;
if (!NodePredicates.empty()) {
- OS << "virtual bool CheckNodePredicate(SDNode *Node,\n";
- OS << " unsigned PredNo) const {\n";
+ OS << "bool CheckNodePredicate(SDNode *Node,\n";
+ OS << " unsigned PredNo) const override {\n";
OS << " switch (PredNo) {\n";
OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
@@ -646,9 +653,9 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
// Emit CompletePattern matchers.
// FIXME: This should be const.
if (!ComplexPatterns.empty()) {
- OS << "virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
- OS << " SDValue N, unsigned PatternNo,\n";
- OS << " SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {\n";
+ OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
+ OS << " SDValue N, unsigned PatternNo,\n";
+ OS << " SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\n";
OS << " unsigned NextRes = Result.size();\n";
OS << " switch (PatternNo) {\n";
OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
@@ -687,7 +694,7 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
// Emit SDNodeXForm handlers.
// FIXME: This should be const.
if (!NodeXForms.empty()) {
- OS << "virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {\n";
+ OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n";
OS << " switch (XFormNo) {\n";
OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n";
@@ -769,6 +776,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M,
case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
+ case Matcher::CheckChildInteger: OS << "OPC_CheckChildInteger"; break;
case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
@@ -809,7 +817,7 @@ void llvm::EmitMatcherTable(const Matcher *TheMatcher,
OS << " // this.\n";
OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
OS << " static const unsigned char MatcherTable[] = {\n";
- unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS);
+ unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 6, 0, OS);
OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
MatcherEmitter.EmitHistogram(TheMatcher, OS);
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index ed41631..8ae7444 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -419,7 +419,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
void MatcherGen::EmitMatchCode(const TreePatternNode *N,
TreePatternNode *NodeNoTypes) {
// If N and NodeNoTypes don't agree on a type, then this is a case where we
- // need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
+ // need to do a type check. Emit the check, apply the type to NodeNoTypes and
// reinfer any correlated types.
SmallVector<unsigned, 2> ResultsToTypeCheck;
@@ -850,8 +850,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
"Node has no result");
AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
- ResultVTs.data(), ResultVTs.size(),
- InstOps.data(), InstOps.size(),
+ ResultVTs, InstOps,
NodeHasChain, TreeHasInGlue, TreeHasOutGlue,
NodeHasMemRefs, NumFixedArityOperands,
NextRecordedOperandNo));
@@ -907,8 +906,7 @@ void MatcherGen::EmitResultCode() {
// merge them together into a token factor. This informs the generated code
// what all the chained nodes are.
if (!MatchedChainNodes.empty())
- AddMatcher(new EmitMergeInputChainsMatcher
- (MatchedChainNodes.data(), MatchedChainNodes.size()));
+ AddMatcher(new EmitMergeInputChainsMatcher(MatchedChainNodes));
// Codegen the root of the result pattern, capturing the resulting values.
SmallVector<unsigned, 8> Ops;
@@ -949,10 +947,9 @@ void MatcherGen::EmitResultCode() {
// If the matched pattern covers nodes which define a glue result, emit a node
// that tells the matcher about them so that it can update their results.
if (!MatchedGlueResultNodes.empty())
- AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes.data(),
- MatchedGlueResultNodes.size()));
+ AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes));
- AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
+ AddMatcher(new CompleteMatchMatcher(Ops, Pattern));
}
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp
index 82e5d63..b7f3b6c 100644
--- a/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -22,7 +22,7 @@ using namespace llvm;
/// ContractNodes - Turn multiple matcher node patterns like 'MoveChild+Record'
/// into single compound nodes like RecordChild.
-static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
+static void ContractNodes(std::unique_ptr<Matcher> &MatcherPtr,
const CodeGenDAGPatterns &CGP) {
// If we reached the end of the chain, we're done.
Matcher *N = MatcherPtr.get();
@@ -31,9 +31,9 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
// If we have a scope node, walk down all of the children.
if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
- OwningPtr<Matcher> Child(Scope->takeChild(i));
+ std::unique_ptr<Matcher> Child(Scope->takeChild(i));
ContractNodes(Child, CGP);
- Scope->resetChild(i, Child.take());
+ Scope->resetChild(i, Child.release());
}
return;
}
@@ -46,7 +46,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
if (MC->getChildNo() < 8) // Only have RecordChild0...7
New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
RM->getResultNo());
-
+
if (CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(MC->getNext()))
if (MC->getChildNo() < 8 && // Only have CheckChildType0...7
CT->getResNo() == 0) // CheckChildType checks res #0
@@ -56,9 +56,13 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
if (MC->getChildNo() < 4) // Only have CheckChildSame0...3
New = new CheckChildSameMatcher(MC->getChildNo(), CS->getMatchNumber());
+ if (CheckIntegerMatcher *CS = dyn_cast<CheckIntegerMatcher>(MC->getNext()))
+ if (MC->getChildNo() < 5) // Only have CheckChildInteger0...4
+ New = new CheckChildIntegerMatcher(MC->getChildNo(), CS->getValue());
+
if (New) {
// Insert the new node.
- New->setNext(MatcherPtr.take());
+ New->setNext(MatcherPtr.release());
MatcherPtr.reset(New);
// Remove the old one.
MC->setNext(MC->getNext()->takeNext());
@@ -81,7 +85,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
if (isa<EmitNodeMatcher>(N) && isa<MarkGlueResultsMatcher>(N->getNext()) &&
isa<CompleteMatchMatcher>(N->getNext()->getNext())) {
// Unlink the two nodes from the list.
- Matcher *EmitNode = MatcherPtr.take();
+ Matcher *EmitNode = MatcherPtr.release();
Matcher *MFR = EmitNode->takeNext();
Matcher *Tail = MFR->takeNext();
@@ -136,8 +140,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
const SmallVectorImpl<MVT::SimpleValueType> &VTs = EN->getVTList();
const SmallVectorImpl<unsigned> &Operands = EN->getOperandList();
MatcherPtr.reset(new MorphNodeToMatcher(EN->getOpcodeName(),
- VTs.data(), VTs.size(),
- Operands.data(),Operands.size(),
+ VTs, Operands,
EN->hasChain(), EN->hasInFlag(),
EN->hasOutFlag(),
EN->hasMemRefs(),
@@ -161,7 +164,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
isa<RecordMatcher>(N)) &&
isa<CheckOpcodeMatcher>(N->getNext())) {
// Unlink the two nodes from the list.
- Matcher *CheckType = MatcherPtr.take();
+ Matcher *CheckType = MatcherPtr.release();
Matcher *CheckOpcode = CheckType->takeNext();
Matcher *Tail = CheckOpcode->takeNext();
@@ -184,7 +187,7 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
/// run a the complex pattern if the pattern predicate will fail. For this
/// reason, we refuse to sink the pattern predicate past a ComplexPattern.
///
-static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
+static void SinkPatternPredicates(std::unique_ptr<Matcher> &MatcherPtr) {
// Recursively scan for a PatternPredicate.
// If we reached the end of the chain, we're done.
Matcher *N = MatcherPtr.get();
@@ -193,9 +196,9 @@ static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
// Walk down all members of a scope node.
if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
- OwningPtr<Matcher> Child(Scope->takeChild(i));
+ std::unique_ptr<Matcher> Child(Scope->takeChild(i));
SinkPatternPredicates(Child);
- Scope->resetChild(i, Child.take());
+ Scope->resetChild(i, Child.release());
}
return;
}
@@ -214,7 +217,7 @@ static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
// Okay, we know we can sink it past at least one node. Unlink it from the
// chain and scan for the new insertion point.
- MatcherPtr.take(); // Don't delete CPPM.
+ MatcherPtr.release(); // Don't delete CPPM.
MatcherPtr.reset(CPPM->takeNext());
N = MatcherPtr.get();
@@ -249,7 +252,7 @@ static Matcher *FindNodeWithKind(Matcher *M, Matcher::KindTy Kind) {
/// ABC
/// XYZ
///
-static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
+static void FactorNodes(std::unique_ptr<Matcher> &MatcherPtr) {
// If we reached the end of the chain, we're done.
Matcher *N = MatcherPtr.get();
if (N == 0) return;
@@ -266,10 +269,10 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
// Factor the subexpression.
- OwningPtr<Matcher> Child(Scope->takeChild(i));
+ std::unique_ptr<Matcher> Child(Scope->takeChild(i));
FactorNodes(Child);
- if (Matcher *N = Child.take())
+ if (Matcher *N = Child.release())
OptionsToMatch.push_back(N);
}
@@ -380,7 +383,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
EqualMatchers[i] = Tmp;
}
- Shared->setNext(new ScopeMatcher(&EqualMatchers[0], EqualMatchers.size()));
+ Shared->setNext(new ScopeMatcher(EqualMatchers));
// Recursively factor the newly created node.
FactorNodes(Shared->getNextPtr());
@@ -455,7 +458,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
Cases.push_back(std::make_pair(&COM->getOpcode(), COM->getNext()));
}
- MatcherPtr.reset(new SwitchOpcodeMatcher(&Cases[0], Cases.size()));
+ MatcherPtr.reset(new SwitchOpcodeMatcher(Cases));
return;
}
@@ -482,7 +485,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
}
Matcher *Entries[2] = { PrevMatcher, MatcherWithoutCTM };
- Cases[Entry-1].second = new ScopeMatcher(Entries, 2);
+ Cases[Entry-1].second = new ScopeMatcher(Entries);
continue;
}
@@ -491,7 +494,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
}
if (Cases.size() != 1) {
- MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
+ MatcherPtr.reset(new SwitchTypeMatcher(Cases));
} else {
// If we factored and ended up with one case, create it now.
MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first, 0));
@@ -509,9 +512,9 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher,
const CodeGenDAGPatterns &CGP) {
- OwningPtr<Matcher> MatcherPtr(TheMatcher);
+ std::unique_ptr<Matcher> MatcherPtr(TheMatcher);
ContractNodes(MatcherPtr, CGP);
SinkPatternPredicates(MatcherPtr);
FactorNodes(MatcherPtr);
- return MatcherPtr.take();
+ return MatcherPtr.release();
}
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
index 5a2a41b..0020de6 100644
--- a/utils/TableGen/DisassemblerEmitter.cpp
+++ b/utils/TableGen/DisassemblerEmitter.cpp
@@ -117,9 +117,10 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i)
RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i);
- if (Tables.hasConflicts())
- PrintFatalError(Target.getTargetRecord()->getLoc(),
- "Primary decode conflict");
+ if (Tables.hasConflicts()) {
+ PrintError(Target.getTargetRecord()->getLoc(), "Primary decode conflict");
+ return;
+ }
Tables.emit(OS);
return;
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index e35cf0f..3a3f836 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -638,7 +638,7 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) {
if ((*Memo.PhysRegs)[i] != "")
- OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, "
+ OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, "
<< "TII.get(TargetOpcode::COPY), "
<< (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n";
}
@@ -729,7 +729,7 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) {
if ((*Memo.PhysRegs)[i] != "")
- OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, "
+ OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, "
<< "TII.get(TargetOpcode::COPY), "
<< (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n";
}
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index 87d18cd..e249a94 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -28,7 +28,6 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenBackend.h"
#include <map>
#include <string>
#include <vector>
@@ -1698,19 +1697,13 @@ void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
}
}
-static bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc,
+static bool populateInstruction(CodeGenTarget &Target,
+ const CodeGenInstruction &CGI, unsigned Opc,
std::map<unsigned, std::vector<OperandInfo> > &Operands){
const Record &Def = *CGI.TheDef;
// If all the bit positions are not specified; do not decode this instruction.
// We are bound to fail! For proper disassembly, the well-known encoding bits
// of the instruction must be fully specified.
- //
- // This also removes pseudo instructions from considerations of disassembly,
- // which is a better design and less fragile than the name matchings.
- // Ignore "asm parser only" instructions.
- if (Def.getValueAsBit("isAsmParserOnly") ||
- Def.getValueAsBit("isCodeGenOnly"))
- return false;
BitsInit &Bits = getBitsField(Def, "Inst");
if (Bits.allInComplete()) return false;
@@ -1747,14 +1740,180 @@ static bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc,
for (unsigned i = 0; i < CGI.Operands.size(); ++i) {
int tiedTo = CGI.Operands[i].getTiedRegister();
if (tiedTo != -1) {
- TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second;
- TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second;
+ std::pair<unsigned, unsigned> SO =
+ CGI.Operands.getSubOperandNumber(tiedTo);
+ TiedNames[InOutOperands[i].second] = InOutOperands[SO.first].second;
+ TiedNames[InOutOperands[SO.first].second] = InOutOperands[i].second;
+ }
+ }
+
+ std::map<std::string, std::vector<OperandInfo> > NumberedInsnOperands;
+ std::set<std::string> NumberedInsnOperandsNoTie;
+ if (Target.getInstructionSet()->
+ getValueAsBit("decodePositionallyEncodedOperands")) {
+ const std::vector<RecordVal> &Vals = Def.getValues();
+ unsigned NumberedOp = 0;
+
+ std::set<unsigned> NamedOpIndices;
+ if (Target.getInstructionSet()->
+ getValueAsBit("noNamedPositionallyEncodedOperands"))
+ // Collect the set of operand indices that might correspond to named
+ // operand, and skip these when assigning operands based on position.
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ unsigned OpIdx;
+ if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
+ continue;
+
+ NamedOpIndices.insert(OpIdx);
+ }
+
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ // Ignore fixed fields in the record, we're looking for values like:
+ // bits<5> RST = { ?, ?, ?, ?, ? };
+ if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
+ continue;
+
+ // Determine if Vals[i] actually contributes to the Inst encoding.
+ unsigned bi = 0;
+ for (; bi < Bits.getNumBits(); ++bi) {
+ VarInit *Var = 0;
+ VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
+ if (BI)
+ Var = dyn_cast<VarInit>(BI->getBitVar());
+ else
+ Var = dyn_cast<VarInit>(Bits.getBit(bi));
+
+ if (Var && Var->getName() == Vals[i].getName())
+ break;
+ }
+
+ if (bi == Bits.getNumBits())
+ continue;
+
+ // Skip variables that correspond to explicitly-named operands.
+ unsigned OpIdx;
+ if (CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
+ continue;
+
+ // Get the bit range for this operand:
+ unsigned bitStart = bi++, bitWidth = 1;
+ for (; bi < Bits.getNumBits(); ++bi) {
+ VarInit *Var = 0;
+ VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi));
+ if (BI)
+ Var = dyn_cast<VarInit>(BI->getBitVar());
+ else
+ Var = dyn_cast<VarInit>(Bits.getBit(bi));
+
+ if (!Var)
+ break;
+
+ if (Var->getName() != Vals[i].getName())
+ break;
+
+ ++bitWidth;
+ }
+
+ unsigned NumberOps = CGI.Operands.size();
+ while (NumberedOp < NumberOps &&
+ (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
+ (NamedOpIndices.size() && NamedOpIndices.count(
+ CGI.Operands.getSubOperandNumber(NumberedOp).first))))
+ ++NumberedOp;
+
+ OpIdx = NumberedOp++;
+
+ // OpIdx now holds the ordered operand number of Vals[i].
+ std::pair<unsigned, unsigned> SO =
+ CGI.Operands.getSubOperandNumber(OpIdx);
+ const std::string &Name = CGI.Operands[SO.first].Name;
+
+ DEBUG(dbgs() << "Numbered operand mapping for " << Def.getName() << ": " <<
+ Name << "(" << SO.first << ", " << SO.second << ") => " <<
+ Vals[i].getName() << "\n");
+
+ std::string Decoder = "";
+ Record *TypeRecord = CGI.Operands[SO.first].Rec;
+
+ RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
+ StringInit *String = DecoderString ?
+ dyn_cast<StringInit>(DecoderString->getValue()) : 0;
+ if (String && String->getValue() != "")
+ Decoder = String->getValue();
+
+ if (Decoder == "" &&
+ CGI.Operands[SO.first].MIOperandInfo &&
+ CGI.Operands[SO.first].MIOperandInfo->getNumArgs()) {
+ Init *Arg = CGI.Operands[SO.first].MIOperandInfo->
+ getArg(SO.second);
+ if (TypedInit *TI = cast<TypedInit>(Arg)) {
+ RecordRecTy *Type = cast<RecordRecTy>(TI->getType());
+ TypeRecord = Type->getRecord();
+ }
+ }
+
+ bool isReg = false;
+ if (TypeRecord->isSubClassOf("RegisterOperand"))
+ TypeRecord = TypeRecord->getValueAsDef("RegClass");
+ if (TypeRecord->isSubClassOf("RegisterClass")) {
+ Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
+ isReg = true;
+ } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) {
+ Decoder = "DecodePointerLikeRegClass" +
+ utostr(TypeRecord->getValueAsInt("RegClassKind"));
+ isReg = true;
+ }
+
+ DecoderString = TypeRecord->getValue("DecoderMethod");
+ String = DecoderString ?
+ dyn_cast<StringInit>(DecoderString->getValue()) : 0;
+ if (!isReg && String && String->getValue() != "")
+ Decoder = String->getValue();
+
+ OperandInfo OpInfo(Decoder);
+ OpInfo.addField(bitStart, bitWidth, 0);
+
+ NumberedInsnOperands[Name].push_back(OpInfo);
+
+ // FIXME: For complex operands with custom decoders we can't handle tied
+ // sub-operands automatically. Skip those here and assume that this is
+ // fixed up elsewhere.
+ if (CGI.Operands[SO.first].MIOperandInfo &&
+ CGI.Operands[SO.first].MIOperandInfo->getNumArgs() > 1 &&
+ String && String->getValue() != "")
+ NumberedInsnOperandsNoTie.insert(Name);
}
}
// For each operand, see if we can figure out where it is encoded.
for (std::vector<std::pair<Init*, std::string> >::const_iterator
NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) {
+ if (!NumberedInsnOperands[NI->second].empty()) {
+ InsnOperands.insert(InsnOperands.end(),
+ NumberedInsnOperands[NI->second].begin(),
+ NumberedInsnOperands[NI->second].end());
+ continue;
+ } else if (!NumberedInsnOperands[TiedNames[NI->second]].empty()) {
+ if (!NumberedInsnOperandsNoTie.count(TiedNames[NI->second])) {
+ // Figure out to which (sub)operand we're tied.
+ unsigned i = CGI.Operands.getOperandNamed(TiedNames[NI->second]);
+ int tiedTo = CGI.Operands[i].getTiedRegister();
+ if (tiedTo == -1) {
+ i = CGI.Operands.getOperandNamed(NI->second);
+ tiedTo = CGI.Operands[i].getTiedRegister();
+ }
+
+ if (tiedTo != -1) {
+ std::pair<unsigned, unsigned> SO =
+ CGI.Operands.getSubOperandNumber(tiedTo);
+
+ InsnOperands.push_back(NumberedInsnOperands[TiedNames[NI->second]]
+ [SO.second]);
+ }
+ }
+ continue;
+ }
+
std::string Decoder = "";
// At this point, we can locate the field, but we need to know how to
@@ -1771,6 +1930,10 @@ static bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc,
if (TypeRecord->isSubClassOf("RegisterClass")) {
Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
isReg = true;
+ } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) {
+ Decoder = "DecodePointerLikeRegClass" +
+ utostr(TypeRecord->getValueAsInt("RegClassKind"));
+ isReg = true;
}
RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
@@ -2012,6 +2175,8 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
emitFieldFromInstruction(OS);
+ Target.reverseBitsForLittleEndianEncoding();
+
// Parameterize the decoders based on namespace and instruction width.
NumberedInstructions = &Target.getInstructionsByEnumValue();
std::map<std::pair<std::string, unsigned>,
@@ -2031,7 +2196,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace");
if (Size) {
- if (populateInstruction(*Inst, i, Operands)) {
+ if (populateInstruction(Target, *Inst, i, Operands)) {
OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i);
}
}
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index d3d9cc1..7aa0f40 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -59,10 +59,10 @@ private:
raw_ostream &OS);
void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target);
void initOperandMapData(
- const std::vector<const CodeGenInstruction *> NumberedInstructions,
- const std::string &Namespace,
- std::map<std::string, unsigned> &Operands,
- OpNameMapTy &OperandMap);
+ const std::vector<const CodeGenInstruction *> &NumberedInstructions,
+ const std::string &Namespace,
+ std::map<std::string, unsigned> &Operands,
+ OpNameMapTy &OperandMap);
void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
const std::vector<const CodeGenInstruction*> &NumberedInstructions);
@@ -200,7 +200,7 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
/// each instructions. This is used to generate the OperandMap table as
/// well as the getNamedOperandIdx() function.
void InstrInfoEmitter::initOperandMapData(
- const std::vector<const CodeGenInstruction *> NumberedInstructions,
+ const std::vector<const CodeGenInstruction *> &NumberedInstructions,
const std::string &Namespace,
std::map<std::string, unsigned> &Operands,
OpNameMapTy &OperandMap) {
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index 8f137f8..7b0a2b6 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -131,20 +131,6 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
OS << "#endif\n\n";
}
-struct IntrinsicNameSorter {
- IntrinsicNameSorter(const std::vector<CodeGenIntrinsic> &I)
- : Ints(I) {}
-
- // Sort in reverse order of intrinsic name so "abc.def" appears after
- // "abd.def.ghi" in the overridden name matcher
- bool operator()(unsigned i, unsigned j) {
- return Ints[i].Name > Ints[j].Name;
- }
-
-private:
- const std::vector<CodeGenIntrinsic> &Ints;
-};
-
void IntrinsicEmitter::
EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS) {
@@ -158,15 +144,17 @@ EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n";
OS << " switch (Name[5]) { // Dispatch on first letter.\n";
OS << " default: break;\n";
- IntrinsicNameSorter Sorter(Ints);
// Emit the intrinsic matching stuff by first letter.
for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
E = IntMapping.end(); I != E; ++I) {
OS << " case '" << I->first << "':\n";
std::vector<unsigned> &IntList = I->second;
- // Sort intrinsics in reverse order of their names
- std::sort(IntList.begin(), IntList.end(), Sorter);
+ // Sort in reverse order of intrinsic name so "abc.def" appears after
+ // "abd.def.ghi" in the overridden name matcher
+ std::sort(IntList.begin(), IntList.end(), [&](unsigned i, unsigned j) {
+ return Ints[i].Name > Ints[j].Name;
+ });
// Emit all the overloaded intrinsics first, build a table of the
// non-overloaded ones.
@@ -258,18 +246,19 @@ enum IIT_Info {
IIT_STRUCT3 = 20,
IIT_STRUCT4 = 21,
IIT_STRUCT5 = 22,
- IIT_EXTEND_VEC_ARG = 23,
- IIT_TRUNC_VEC_ARG = 24,
+ IIT_EXTEND_ARG = 23,
+ IIT_TRUNC_ARG = 24,
IIT_ANYPTR = 25,
IIT_V1 = 26,
- IIT_VARARG = 27
+ IIT_VARARG = 27,
+ IIT_HALF_VEC_ARG = 28
};
static void EncodeFixedValueType(MVT::SimpleValueType VT,
std::vector<unsigned char> &Sig) {
- if (EVT(VT).isInteger()) {
- unsigned BitWidth = EVT(VT).getSizeInBits();
+ if (MVT(VT).isInteger()) {
+ unsigned BitWidth = MVT(VT).getSizeInBits();
switch (BitWidth) {
default: PrintFatalError("unhandled integer type width in intrinsic!");
case 1: return Sig.push_back(IIT_I1);
@@ -304,10 +293,12 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
if (R->isSubClassOf("LLVMMatchType")) {
unsigned Number = R->getValueAsInt("Number");
assert(Number < ArgCodes.size() && "Invalid matching number!");
- if (R->isSubClassOf("LLVMExtendedElementVectorType"))
- Sig.push_back(IIT_EXTEND_VEC_ARG);
- else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
- Sig.push_back(IIT_TRUNC_VEC_ARG);
+ if (R->isSubClassOf("LLVMExtendedType"))
+ Sig.push_back(IIT_EXTEND_ARG);
+ else if (R->isSubClassOf("LLVMTruncatedType"))
+ Sig.push_back(IIT_TRUNC_ARG);
+ else if (R->isSubClassOf("LLVMHalfElementsVectorType"))
+ Sig.push_back(IIT_HALF_VEC_ARG);
else
Sig.push_back(IIT_ARG);
return Sig.push_back((Number << 2) | ArgCodes[Number]);
@@ -350,8 +341,8 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
}
}
- if (EVT(VT).isVector()) {
- EVT VVT = VT;
+ if (MVT(VT).isVector()) {
+ MVT VVT = VT;
switch (VVT.getVectorNumElements()) {
default: PrintFatalError("unhandled vector type width in intrinsic!");
case 1: Sig.push_back(IIT_V1); break;
@@ -362,8 +353,7 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
case 32: Sig.push_back(IIT_V32); break;
}
- return EncodeFixedValueType(VVT.getVectorElementType().
- getSimpleVT().SimpleTy, Sig);
+ return EncodeFixedValueType(VVT.getVectorElementType().SimpleTy, Sig);
}
EncodeFixedValueType(VT, Sig);
@@ -515,6 +505,9 @@ struct AttributeComparator {
if (L->canThrow != R->canThrow)
return R->canThrow;
+ if (L->isNoDuplicate != R->isNoDuplicate)
+ return R->isNoDuplicate;
+
if (L->isNoReturn != R->isNoReturn)
return R->isNoReturn;
@@ -629,7 +622,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
ModRefKind modRef = getModRefKind(intrinsic);
- if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
+ if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn ||
+ intrinsic.isNoDuplicate) {
OS << " const Attribute::AttrKind Atts[] = {";
bool addComma = false;
if (!intrinsic.canThrow) {
@@ -642,6 +636,12 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << "Attribute::NoReturn";
addComma = true;
}
+ if (intrinsic.isNoDuplicate) {
+ if (addComma)
+ OS << ",";
+ OS << "Attribute::NoDuplicate";
+ addComma = true;
+ }
switch (modRef) {
case MRK_none: break;
@@ -667,6 +667,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << " }\n";
} else {
OS << " return AttributeSet();\n";
+ OS << " }\n";
}
}
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp
index 9c4daaf..c5fd7ee 100644
--- a/utils/TableGen/OptParserEmitter.cpp
+++ b/utils/TableGen/OptParserEmitter.cpp
@@ -13,8 +13,8 @@
#include "llvm/ADT/Twine.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
-#include <cstring>
#include <cctype>
+#include <cstring>
#include <map>
using namespace llvm;
diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp
index 1ea6f79..100338c 100644
--- a/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -259,7 +259,7 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
<< " if (lowerOperand(MI->getOperand(i), MCOp))\n"
<< " TmpInst.addOperand(MCOp);\n";
}
- o << " OutStreamer.EmitInstruction(TmpInst);\n"
+ o << " EmitToStreamer(OutStreamer, TmpInst);\n"
<< " break;\n"
<< " }\n";
}
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index cc08df9..61ae262 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -917,7 +917,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
uint64_t Value = 0;
for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
- Value |= (uint64_t)B->getValue() << b;
+ Value |= (uint64_t)B->getValue() << b;
}
OS << " " << Value << ",\n";
}
@@ -965,23 +965,24 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
<< "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
- << " virtual bool needsStackRealignment(const MachineFunction &) const\n"
+ << " bool needsStackRealignment(const MachineFunction &) const override\n"
<< " { return false; }\n";
if (!RegBank.getSubRegIndices().empty()) {
- OS << " virtual unsigned composeSubRegIndicesImpl"
- << "(unsigned, unsigned) const;\n"
- << " virtual const TargetRegisterClass *"
- "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
+ OS << " unsigned composeSubRegIndicesImpl"
+ << "(unsigned, unsigned) const override;\n"
+ << " const TargetRegisterClass *getSubClassWithSubReg"
+ << "(const TargetRegisterClass*, unsigned) const override;\n";
}
- OS << " virtual const RegClassWeight &getRegClassWeight("
- << "const TargetRegisterClass *RC) const;\n"
- << " virtual unsigned getRegUnitWeight(unsigned RegUnit) const;\n"
- << " virtual unsigned getNumRegPressureSets() const;\n"
- << " virtual const char *getRegPressureSetName(unsigned Idx) const;\n"
- << " virtual unsigned getRegPressureSetLimit(unsigned Idx) const;\n"
- << " virtual const int *getRegClassPressureSets("
- << "const TargetRegisterClass *RC) const;\n"
- << " virtual const int *getRegUnitPressureSets(unsigned RegUnit) const;\n"
+ OS << " const RegClassWeight &getRegClassWeight("
+ << "const TargetRegisterClass *RC) const override;\n"
+ << " unsigned getRegUnitWeight(unsigned RegUnit) const override;\n"
+ << " unsigned getNumRegPressureSets() const override;\n"
+ << " const char *getRegPressureSetName(unsigned Idx) const override;\n"
+ << " unsigned getRegPressureSetLimit(unsigned Idx) const override;\n"
+ << " const int *getRegClassPressureSets("
+ << "const TargetRegisterClass *RC) const override;\n"
+ << " const int *getRegUnitPressureSets("
+ << "unsigned RegUnit) const override;\n"
<< "};\n\n";
ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
index ad3d7c7..d952e68 100644
--- a/utils/TableGen/SetTheory.cpp
+++ b/utils/TableGen/SetTheory.cpp
@@ -27,16 +27,16 @@ typedef SetTheory::RecVec RecVec;
// (add a, b, ...) Evaluate and union all arguments.
struct AddOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
}
};
// (sub Add, Sub, ...) Set difference.
struct SubOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
if (Expr->arg_size() < 2)
PrintFatalError(Loc, "Set difference needs at least two arguments: " +
Expr->getAsString());
@@ -51,8 +51,8 @@ struct SubOp : public SetTheory::Operator {
// (and S1, S2) Set intersection.
struct AndOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
if (Expr->arg_size() != 2)
PrintFatalError(Loc, "Set intersection requires two arguments: " +
Expr->getAsString());
@@ -67,12 +67,11 @@ struct AndOp : public SetTheory::Operator {
// SetIntBinOp - Abstract base class for (Op S, N) operators.
struct SetIntBinOp : public SetTheory::Operator {
- virtual void apply2(SetTheory &ST, DagInit *Expr,
- RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) =0;
+ virtual void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) = 0;
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
if (Expr->arg_size() != 2)
PrintFatalError(Loc, "Operator requires (Op Set, Int) arguments: " +
Expr->getAsString());
@@ -88,9 +87,8 @@ struct SetIntBinOp : public SetTheory::Operator {
// (shl S, N) Shift left, remove the first N elements.
struct ShlOp : public SetIntBinOp {
- virtual void apply2(SetTheory &ST, DagInit *Expr,
- RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
if (N < 0)
PrintFatalError(Loc, "Positive shift required: " +
Expr->getAsString());
@@ -101,9 +99,8 @@ struct ShlOp : public SetIntBinOp {
// (trunc S, N) Truncate after the first N elements.
struct TruncOp : public SetIntBinOp {
- virtual void apply2(SetTheory &ST, DagInit *Expr,
- RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
if (N < 0)
PrintFatalError(Loc, "Positive length required: " +
Expr->getAsString());
@@ -119,9 +116,8 @@ struct RotOp : public SetIntBinOp {
RotOp(bool Rev) : Reverse(Rev) {}
- virtual void apply2(SetTheory &ST, DagInit *Expr,
- RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
if (Reverse)
N = -N;
// N > 0 -> rotate left, N < 0 -> rotate right.
@@ -138,9 +134,8 @@ struct RotOp : public SetIntBinOp {
// (decimate S, N) Pick every N'th element of S.
struct DecimateOp : public SetIntBinOp {
- virtual void apply2(SetTheory &ST, DagInit *Expr,
- RecSet &Set, int64_t N,
- RecSet &Elts, ArrayRef<SMLoc> Loc) {
+ void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
+ RecSet &Elts, ArrayRef<SMLoc> Loc) override {
if (N <= 0)
PrintFatalError(Loc, "Positive stride required: " +
Expr->getAsString());
@@ -151,8 +146,8 @@ struct DecimateOp : public SetIntBinOp {
// (interleave S1, S2, ...) Interleave elements of the arguments.
struct InterleaveOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
// Evaluate the arguments individually.
SmallVector<RecSet, 4> Args(Expr->getNumArgs());
unsigned MaxSize = 0;
@@ -170,8 +165,8 @@ struct InterleaveOp : public SetTheory::Operator {
// (sequence "Format", From, To) Generate a sequence of records by name.
struct SequenceOp : public SetTheory::Operator {
- virtual void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
- ArrayRef<SMLoc> Loc) {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts,
+ ArrayRef<SMLoc> Loc) override {
int Step = 1;
if (Expr->arg_size() > 4)
PrintFatalError(Loc, "Bad args to (sequence \"Format\", From, To): " +
@@ -238,7 +233,7 @@ struct FieldExpander : public SetTheory::Expander {
FieldExpander(StringRef fn) : FieldName(fn) {}
- virtual void expand(SetTheory &ST, Record *Def, RecSet &Elts) {
+ void expand(SetTheory &ST, Record *Def, RecSet &Elts) override {
ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc());
}
};
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index b9f9d06..71301aa 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -1498,7 +1498,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< "StringRef FS);\n"
<< "public:\n"
<< " unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *DefMI,"
- << " const TargetSchedModel *SchedModel) const;\n"
+ << " const TargetSchedModel *SchedModel) const override;\n"
<< " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
<< " const;\n"
<< "};\n";
diff --git a/utils/TableGen/TGValueTypes.cpp b/utils/TableGen/TGValueTypes.cpp
deleted file mode 100644
index f4893f5..0000000
--- a/utils/TableGen/TGValueTypes.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-//===- ValueTypes.cpp - Tablegen extended ValueType implementation --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The EVT type is used by tablegen as well as in LLVM. In order to handle
-// extended types, the EVT type uses support functions that call into
-// LLVM's type system code. These aren't accessible in tablegen, so this
-// file provides simple replacements.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/Casting.h"
-#include <map>
-using namespace llvm;
-
-namespace llvm {
-
-class Type {
-protected:
- enum TypeKind {
- TK_ExtendedIntegerType,
- TK_ExtendedVectorType
- };
-private:
- TypeKind Kind;
-public:
- TypeKind getKind() const {
- return Kind;
- }
- Type(TypeKind K) : Kind(K) {}
- virtual unsigned getSizeInBits() const = 0;
- virtual ~Type();
-};
-
-// Provide out-of-line definition to prevent weak vtable.
-Type::~Type() {}
-
-}
-
-namespace {
-class ExtendedIntegerType : public Type {
- unsigned BitWidth;
-public:
- explicit ExtendedIntegerType(unsigned bits)
- : Type(TK_ExtendedIntegerType), BitWidth(bits) {}
- static bool classof(const Type *T) {
- return T->getKind() == TK_ExtendedIntegerType;
- }
- virtual unsigned getSizeInBits() const {
- return getBitWidth();
- }
- unsigned getBitWidth() const {
- return BitWidth;
- }
-};
-
-class ExtendedVectorType : public Type {
- EVT ElementType;
- unsigned NumElements;
-public:
- ExtendedVectorType(EVT elty, unsigned num)
- : Type(TK_ExtendedVectorType), ElementType(elty), NumElements(num) {}
- static bool classof(const Type *T) {
- return T->getKind() == TK_ExtendedVectorType;
- }
- virtual unsigned getSizeInBits() const {
- return getNumElements() * getElementType().getSizeInBits();
- }
- EVT getElementType() const {
- return ElementType;
- }
- unsigned getNumElements() const {
- return NumElements;
- }
-};
-} // end anonymous namespace
-
-static std::map<unsigned, const Type *>
- ExtendedIntegerTypeMap;
-static std::map<std::pair<uintptr_t, uintptr_t>, const Type *>
- ExtendedVectorTypeMap;
-
-bool EVT::isExtendedFloatingPoint() const {
- assert(isExtended() && "Type is not extended!");
- // Extended floating-point types are not supported yet.
- return false;
-}
-
-bool EVT::isExtendedInteger() const {
- assert(isExtended() && "Type is not extended!");
- return isa<ExtendedIntegerType>(LLVMTy);
-}
-
-bool EVT::isExtendedVector() const {
- assert(isExtended() && "Type is not extended!");
- return isa<ExtendedVectorType>(LLVMTy);
-}
-
-bool EVT::isExtended64BitVector() const {
- assert(isExtended() && "Type is not extended!");
- return isExtendedVector() && getSizeInBits() == 64;
-}
-
-bool EVT::isExtended128BitVector() const {
- assert(isExtended() && "Type is not extended!");
- return isExtendedVector() && getSizeInBits() == 128;
-}
-
-EVT EVT::getExtendedVectorElementType() const {
- assert(isExtendedVector() && "Type is not an extended vector!");
- return static_cast<const ExtendedVectorType *>(LLVMTy)->getElementType();
-}
-
-unsigned EVT::getExtendedVectorNumElements() const {
- assert(isExtendedVector() && "Type is not an extended vector!");
- return static_cast<const ExtendedVectorType *>(LLVMTy)->getNumElements();
-}
-
-unsigned EVT::getExtendedSizeInBits() const {
- assert(isExtended() && "Type is not extended!");
- return LLVMTy->getSizeInBits();
-}
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index b5c3ca7..00c3a6f 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -180,3 +180,12 @@ int main(int argc, char **argv) {
return TableGenMain(argv[0], &LLVMTableGenMain);
}
+
+#ifdef __has_feature
+#if __has_feature(address_sanitizer)
+#include <sanitizer/lsan_interface.h>
+// Disable LeakSanitizer for this binary as it has too many leaks that are not
+// very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
+int __lsan_is_turned_off() { return 1; }
+#endif // __has_feature(address_sanitizer)
+#endif // defined(__has_feature)
diff --git a/utils/TableGen/X86DisassemblerShared.h b/utils/TableGen/X86DisassemblerShared.h
index 3ff922b..036e924 100644
--- a/utils/TableGen/X86DisassemblerShared.h
+++ b/utils/TableGen/X86DisassemblerShared.h
@@ -15,16 +15,12 @@
#define INSTRUCTION_SPECIFIER_FIELDS \
struct OperandSpecifier operands[X86_MAX_OPERANDS]; \
- bool filtered; \
InstructionContext insnContext; \
std::string name; \
\
InstructionSpecifier() { \
- filtered = false; \
insnContext = IC; \
name = ""; \
- modifierType = MODIFIER_NONE; \
- modifierBase = 0; \
memset(operands, 0, sizeof(operands)); \
}
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp
index bdb4793..fbcc6f2 100644
--- a/utils/TableGen/X86DisassemblerTables.cpp
+++ b/utils/TableGen/X86DisassemblerTables.cpp
@@ -19,12 +19,54 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
-#include "llvm/TableGen/TableGenBackend.h"
#include <map>
using namespace llvm;
using namespace X86Disassembler;
+/// stringForContext - Returns a string containing the name of a particular
+/// InstructionContext, usually for diagnostic purposes.
+///
+/// @param insnContext - The instruction class to transform to a string.
+/// @return - A statically-allocated string constant that contains the
+/// name of the instruction class.
+static inline const char* stringForContext(InstructionContext insnContext) {
+ switch (insnContext) {
+ default:
+ llvm_unreachable("Unhandled instruction class");
+#define ENUM_ENTRY(n, r, d) case n: return #n; break;
+#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\
+ ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\
+ ENUM_ENTRY(n##_KZ_B, r, d)
+ INSTRUCTION_CONTEXTS
+#undef ENUM_ENTRY
+#undef ENUM_ENTRY_K_B
+ }
+}
+
+/// stringForOperandType - Like stringForContext, but for OperandTypes.
+static inline const char* stringForOperandType(OperandType type) {
+ switch (type) {
+ default:
+ llvm_unreachable("Unhandled type");
+#define ENUM_ENTRY(i, d) case i: return #i;
+ TYPES
+#undef ENUM_ENTRY
+ }
+}
+
+/// stringForOperandEncoding - like stringForContext, but for
+/// OperandEncodings.
+static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
+ switch (encoding) {
+ default:
+ llvm_unreachable("Unhandled encoding");
+#define ENUM_ENTRY(i, d) case i: return #i;
+ ENCODINGS
+#undef ENUM_ENTRY
+ }
+}
+
/// inheritsFrom - Indicates whether all instructions in one class also belong
/// to another class.
///
@@ -164,12 +206,13 @@ static inline bool inheritsFrom(InstructionContext child,
return inheritsFrom(child, IC_EVEX_W_XD_K) ||
inheritsFrom(child, IC_EVEX_L_W_XD_K);
case IC_EVEX_OPSIZE_K:
- return inheritsFrom(child, IC_EVEX_W_OPSIZE_K) ||
- inheritsFrom(child, IC_EVEX_W_OPSIZE_K);
+ case IC_EVEX_OPSIZE_B:
+ return false;
case IC_EVEX_W_K:
case IC_EVEX_W_XS_K:
case IC_EVEX_W_XD_K:
case IC_EVEX_W_OPSIZE_K:
+ case IC_EVEX_W_OPSIZE_B:
return false;
case IC_EVEX_L_K:
case IC_EVEX_L_XS_K:
@@ -197,7 +240,11 @@ static inline bool inheritsFrom(InstructionContext child,
return false;
case IC_EVEX_L2_K:
case IC_EVEX_L2_B:
+ case IC_EVEX_L2_K_B:
+ case IC_EVEX_L2_KZ_B:
case IC_EVEX_L2_XS_K:
+ case IC_EVEX_L2_XS_B:
+ case IC_EVEX_L2_XD_B:
case IC_EVEX_L2_XD_K:
case IC_EVEX_L2_OPSIZE_K:
case IC_EVEX_L2_OPSIZE_B:
@@ -212,6 +259,7 @@ static inline bool inheritsFrom(InstructionContext child,
case IC_EVEX_L2_W_B:
case IC_EVEX_L2_W_XS_K:
case IC_EVEX_L2_W_XD_K:
+ case IC_EVEX_L2_W_XD_B:
case IC_EVEX_L2_W_OPSIZE_K:
case IC_EVEX_L2_W_OPSIZE_B:
case IC_EVEX_L2_W_OPSIZE_K_B:
@@ -222,6 +270,8 @@ static inline bool inheritsFrom(InstructionContext child,
case IC_EVEX_L2_W_OPSIZE_KZ_B:
return false;
default:
+ errs() << "Unknown instruction class: " <<
+ stringForContext((InstructionContext)parent) << "\n";
llvm_unreachable("Unknown instruction class");
}
}
@@ -251,49 +301,6 @@ static inline bool outranks(InstructionContext upper,
return (ranks[upper] > ranks[lower]);
}
-/// stringForContext - Returns a string containing the name of a particular
-/// InstructionContext, usually for diagnostic purposes.
-///
-/// @param insnContext - The instruction class to transform to a string.
-/// @return - A statically-allocated string constant that contains the
-/// name of the instruction class.
-static inline const char* stringForContext(InstructionContext insnContext) {
- switch (insnContext) {
- default:
- llvm_unreachable("Unhandled instruction class");
-#define ENUM_ENTRY(n, r, d) case n: return #n; break;
-#define ENUM_ENTRY_K_B(n, r, d) ENUM_ENTRY(n, r, d) ENUM_ENTRY(n##_K_B, r, d)\
- ENUM_ENTRY(n##_KZ, r, d) ENUM_ENTRY(n##_K, r, d) ENUM_ENTRY(n##_B, r, d)\
- ENUM_ENTRY(n##_KZ_B, r, d)
- INSTRUCTION_CONTEXTS
-#undef ENUM_ENTRY
-#undef ENUM_ENTRY_K_B
- }
-}
-
-/// stringForOperandType - Like stringForContext, but for OperandTypes.
-static inline const char* stringForOperandType(OperandType type) {
- switch (type) {
- default:
- llvm_unreachable("Unhandled type");
-#define ENUM_ENTRY(i, d) case i: return #i;
- TYPES
-#undef ENUM_ENTRY
- }
-}
-
-/// stringForOperandEncoding - like stringForContext, but for
-/// OperandEncodings.
-static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
- switch (encoding) {
- default:
- llvm_unreachable("Unhandled encoding");
-#define ENUM_ENTRY(i, d) case i: return #i;
- ENCODINGS
-#undef ENUM_ENTRY
- }
-}
-
/// getDecisionType - Determines whether a ModRM decision with 255 entries can
/// be compacted by eliminating redundant information.
///
@@ -357,22 +364,6 @@ static const char* stringForDecisionType(ModRMDecisionType dt) {
#undef ENUM_ENTRY
}
-/// stringForModifierType - Returns a statically-allocated string corresponding
-/// to an opcode modifier type.
-///
-/// @param mt - The modifier type.
-/// @return - A pointer to the statically-allocated string (e.g.,
-/// "MODIFIER_NONE" for MODIFIER_NONE).
-static const char* stringForModifierType(ModifierType mt) {
-#define ENUM_ENTRY(n) case n: return #n;
- switch(mt) {
- default:
- llvm_unreachable("Unknown modifier type");
- MODIFIER_TYPES
- };
-#undef ENUM_ENTRY
-}
-
DisassemblerTables::DisassemblerTables() {
unsigned i;
@@ -598,14 +589,6 @@ void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
o.indent(i * 2) << "{ /* " << index << " */" << "\n";
i++;
- o.indent(i * 2) << stringForModifierType(
- (ModifierType)InstructionSpecifiers[index].modifierType);
- o << ",\n";
-
- o.indent(i * 2) << "0x";
- o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase);
- o << ",\n";
-
OperandListTy OperandList;
for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
++OperandIndex) {
@@ -636,14 +619,36 @@ void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
}
void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
+ const unsigned int tableSize = 16384;
o.indent(i * 2) << "static const uint8_t " CONTEXTS_STR
- "[256] = {\n";
+ "[" << tableSize << "] = {\n";
i++;
- for (unsigned index = 0; index < 256; ++index) {
+ for (unsigned index = 0; index < tableSize; ++index) {
o.indent(i * 2);
- if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
+ if (index & ATTR_EVEX) {
+ o << "IC_EVEX";
+ if (index & ATTR_EVEXL2)
+ o << "_L2";
+ else if (index & ATTR_EVEXL)
+ o << "_L";
+ if (index & ATTR_REXW)
+ o << "_W";
+ if (index & ATTR_OPSIZE)
+ o << "_OPSIZE";
+ else if (index & ATTR_XD)
+ o << "_XD";
+ else if (index & ATTR_XS)
+ o << "_XS";
+ if (index & ATTR_EVEXKZ)
+ o << "_KZ";
+ else if (index & ATTR_EVEXK)
+ o << "_K";
+ if (index & ATTR_EVEXB)
+ o << "_B";
+ }
+ else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_OPSIZE))
o << "IC_VEX_L_W_OPSIZE";
else if ((index & ATTR_VEXL) && (index & ATTR_REXW) && (index & ATTR_XD))
o << "IC_VEX_L_W_XD";
@@ -713,7 +718,7 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
else
o << "IC";
- if (index < 255)
+ if (index < tableSize - 1)
o << ",";
else
o << " ";
@@ -734,11 +739,9 @@ void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR);
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR);
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR);
- emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], THREEBYTEA6_STR);
- emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], THREEBYTEA7_STR);
- emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOP8_MAP_STR);
- emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], XOP9_MAP_STR);
- emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], XOPA_MAP_STR);
+ emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], XOP8_MAP_STR);
+ emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], XOP9_MAP_STR);
+ emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[6], XOPA_MAP_STR);
}
void DisassemblerTables::emit(raw_ostream &o) const {
@@ -793,8 +796,14 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision,
InstructionSpecifier &previousInfo =
InstructionSpecifiers[decision.instructionIDs[index]];
- if(newInfo.filtered)
- continue; // filtered instructions get lowest priority
+ // Instructions such as MOV8ao8 and MOV8ao8_16 differ only in the
+ // presence of the AdSize prefix. However, the disassembler doesn't
+ // care about that difference in the instruction definition; it
+ // handles 16-bit vs. 32-bit addressing for itself based purely
+ // on the 0x67 prefix and the CPU mode. So there's no need to
+ // disambiguate between them; just let them conflict/coexist.
+ if (previousInfo.name + "_16" == newInfo.name)
+ continue;
if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" ||
newInfo.name == "XCHG32ar" ||
@@ -805,8 +814,7 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision,
if (outranks(previousInfo.insnContext, newInfo.insnContext))
continue;
- if (previousInfo.insnContext == newInfo.insnContext &&
- !previousInfo.filtered) {
+ if (previousInfo.insnContext == newInfo.insnContext) {
errs() << "Error: Primary decode conflict: ";
errs() << newInfo.name << " would overwrite " << previousInfo.name;
errs() << "\n";
diff --git a/utils/TableGen/X86DisassemblerTables.h b/utils/TableGen/X86DisassemblerTables.h
index bf8b127..1327375 100644
--- a/utils/TableGen/X86DisassemblerTables.h
+++ b/utils/TableGen/X86DisassemblerTables.h
@@ -38,12 +38,10 @@ private:
/// [1] two-byte opcodes of the form 0f __
/// [2] three-byte opcodes of the form 0f 38 __
/// [3] three-byte opcodes of the form 0f 3a __
- /// [4] three-byte opcodes of the form 0f a6 __
- /// [5] three-byte opcodes of the form 0f a7 __
- /// [6] XOP8 map opcode
- /// [7] XOP9 map opcode
- /// [8] XOPA map opcode
- ContextDecision* Tables[9];
+ /// [4] XOP8 map opcode
+ /// [5] XOP9 map opcode
+ /// [6] XOPA map opcode
+ ContextDecision* Tables[7];
// Table of ModRM encodings.
typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;
@@ -132,8 +130,7 @@ private:
/// }
///
/// NAME is the name of the ContextDecision (typically one of the four names
- /// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM,
- /// THREEBYTEA6_SYM, and THREEBYTEA7_SYM from
+ /// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from
/// X86DisassemblerDecoderCommon.h).
/// IC is one of the contexts in InstructionContext. There is an opcode
/// decision for each possible context.
diff --git a/utils/TableGen/X86ModRMFilters.cpp b/utils/TableGen/X86ModRMFilters.cpp
index 7166fe0..1641613 100644
--- a/utils/TableGen/X86ModRMFilters.cpp
+++ b/utils/TableGen/X86ModRMFilters.cpp
@@ -17,10 +17,6 @@ void DumbFilter::anchor() { }
void ModFilter::anchor() { }
-void EscapeFilter::anchor() { }
-
-void AddRegEscapeFilter::anchor() { }
-
void ExtendedFilter::anchor() { }
void ExactFilter::anchor() { }
diff --git a/utils/TableGen/X86ModRMFilters.h b/utils/TableGen/X86ModRMFilters.h
index 2cbaf79..fac3838 100644
--- a/utils/TableGen/X86ModRMFilters.h
+++ b/utils/TableGen/X86ModRMFilters.h
@@ -50,13 +50,13 @@ public:
/// require a ModR/M byte or instructions where the entire ModR/M byte is used
/// for operands.
class DumbFilter : public ModRMFilter {
- virtual void anchor();
+ void anchor() override;
public:
- bool isDumb() const {
+ bool isDumb() const override {
return true;
}
-
- bool accepts(uint8_t modRM) const {
+
+ bool accepts(uint8_t modRM) const override {
return true;
}
};
@@ -65,7 +65,7 @@ public:
/// Some instructions are classified based on whether they are 11 or anything
/// else. This filter performs that classification.
class ModFilter : public ModRMFilter {
- virtual void anchor();
+ void anchor() override;
bool R;
public:
/// Constructor
@@ -78,74 +78,16 @@ public:
ModRMFilter(),
R(r) {
}
-
- bool accepts(uint8_t modRM) const {
- if (R == ((modRM & 0xc0) == 0xc0))
- return true;
- else
- return false;
- }
-};
-/// EscapeFilter - Filters escape opcodes, which are classified in two ways. If
-/// the ModR/M byte is between 0xc0 and 0xff, then there is one slot for each
-/// possible value. Otherwise, there is one instruction for each value of the
-/// nnn field [bits 5-3], known elsewhere as the reg field.
-class EscapeFilter : public ModRMFilter {
- virtual void anchor();
- bool C0_FF;
- uint8_t NNN_or_ModRM;
-public:
- /// Constructor
- ///
- /// \param c0_ff True if the ModR/M byte must fall between 0xc0 and 0xff;
- /// false otherwise.
- ///
- /// \param nnn_or_modRM If c0_ff is true, the required value of the entire
- /// ModR/M byte. If c0_ff is false, the required value
- /// of the nnn field.
- EscapeFilter(bool c0_ff, uint8_t nnn_or_modRM) :
- ModRMFilter(),
- C0_FF(c0_ff),
- NNN_or_ModRM(nnn_or_modRM) {
- }
-
- bool accepts(uint8_t modRM) const {
- if ((C0_FF && modRM >= 0xc0 && (modRM == NNN_or_ModRM)) ||
- (!C0_FF && modRM < 0xc0 && ((modRM & 0x38) >> 3) == NNN_or_ModRM))
- return true;
- else
- return false;
- }
-};
-
-/// AddRegEscapeFilter - Some escape opcodes have one of the register operands
-/// added to the ModR/M byte, meaning that a range of eight ModR/M values
-/// maps to a single instruction. Such instructions require the ModR/M byte
-/// to fall between 0xc0 and 0xff.
-class AddRegEscapeFilter : public ModRMFilter {
- virtual void anchor();
- uint8_t ModRM;
-public:
- /// Constructor
- ///
- /// \param modRM The value of the ModR/M byte when the register operand
- /// refers to the first register in the register set.
- AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) {
- }
-
- bool accepts(uint8_t modRM) const {
- if (modRM >= ModRM && modRM < ModRM + 8)
- return true;
- else
- return false;
+ bool accepts(uint8_t modRM) const override {
+ return (R == ((modRM & 0xc0) == 0xc0));
}
};
/// ExtendedFilter - Extended opcodes are classified based on the value of the
/// mod field [bits 7-6] and the value of the nnn field [bits 5-3].
class ExtendedFilter : public ModRMFilter {
- virtual void anchor();
+ void anchor() override;
bool R;
uint8_t NNN;
public:
@@ -159,21 +101,18 @@ public:
R(r),
NNN(nnn) {
}
-
- bool accepts(uint8_t modRM) const {
- if (((R && ((modRM & 0xc0) == 0xc0)) ||
- (!R && ((modRM & 0xc0) != 0xc0))) &&
- (((modRM & 0x38) >> 3) == NNN))
- return true;
- else
- return false;
+
+ bool accepts(uint8_t modRM) const override {
+ return (((R && ((modRM & 0xc0) == 0xc0)) ||
+ (!R && ((modRM & 0xc0) != 0xc0))) &&
+ (((modRM & 0x38) >> 3) == NNN));
}
};
/// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR)
/// requires the ModR/M byte to have a specific value.
class ExactFilter : public ModRMFilter {
- virtual void anchor();
+ void anchor() override;
uint8_t ModRM;
public:
/// Constructor
@@ -183,12 +122,9 @@ public:
ModRMFilter(),
ModRM(modRM) {
}
-
- bool accepts(uint8_t modRM) const {
- if (ModRM == modRM)
- return true;
- else
- return false;
+
+ bool accepts(uint8_t modRM) const override {
+ return (ModRM == modRM);
}
};
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 708e72d..95651f6 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -23,6 +23,7 @@
using namespace llvm;
#define MRM_MAPPING \
+ MAP(C0, 32) \
MAP(C1, 33) \
MAP(C2, 34) \
MAP(C3, 35) \
@@ -31,23 +32,48 @@ using namespace llvm;
MAP(C9, 38) \
MAP(CA, 39) \
MAP(CB, 40) \
- MAP(E8, 41) \
- MAP(F0, 42) \
- MAP(F8, 45) \
- MAP(F9, 46) \
- MAP(D0, 47) \
- MAP(D1, 48) \
- MAP(D4, 49) \
- MAP(D5, 50) \
- MAP(D6, 51) \
- MAP(D8, 52) \
- MAP(D9, 53) \
- MAP(DA, 54) \
- MAP(DB, 55) \
- MAP(DC, 56) \
- MAP(DD, 57) \
- MAP(DE, 58) \
- MAP(DF, 59)
+ MAP(D0, 41) \
+ MAP(D1, 42) \
+ MAP(D4, 43) \
+ MAP(D5, 44) \
+ MAP(D6, 45) \
+ MAP(D8, 46) \
+ MAP(D9, 47) \
+ MAP(DA, 48) \
+ MAP(DB, 49) \
+ MAP(DC, 50) \
+ MAP(DD, 51) \
+ MAP(DE, 52) \
+ MAP(DF, 53) \
+ MAP(E0, 54) \
+ MAP(E1, 55) \
+ MAP(E2, 56) \
+ MAP(E3, 57) \
+ MAP(E4, 58) \
+ MAP(E5, 59) \
+ MAP(E8, 60) \
+ MAP(E9, 61) \
+ MAP(EA, 62) \
+ MAP(EB, 63) \
+ MAP(EC, 64) \
+ MAP(ED, 65) \
+ MAP(EE, 66) \
+ MAP(F0, 67) \
+ MAP(F1, 68) \
+ MAP(F2, 69) \
+ MAP(F3, 70) \
+ MAP(F4, 71) \
+ MAP(F5, 72) \
+ MAP(F6, 73) \
+ MAP(F7, 74) \
+ MAP(F8, 75) \
+ MAP(F9, 76) \
+ MAP(FA, 77) \
+ MAP(FB, 78) \
+ MAP(FC, 79) \
+ MAP(FD, 80) \
+ MAP(FE, 81) \
+ MAP(FF, 82)
// A clone of X86 since we can't depend on something that is generated.
namespace X86Local {
@@ -59,13 +85,17 @@ namespace X86Local {
MRMDestMem = 4,
MRMSrcReg = 5,
MRMSrcMem = 6,
+ RawFrmMemOffs = 7,
+ RawFrmSrc = 8,
+ RawFrmDst = 9,
+ RawFrmDstSrc = 10,
+ RawFrmImm8 = 11,
+ RawFrmImm16 = 12,
+ MRMXr = 14, MRMXm = 15,
MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
- MRMInitReg = 32,
- RawFrmImm8 = 43,
- RawFrmImm16 = 44,
#define MAP(from, to) MRM_##from = to,
MRM_MAPPING
#undef MAP
@@ -73,94 +103,24 @@ namespace X86Local {
};
enum {
- TB = 1,
- REP = 2,
- D8 = 3, D9 = 4, DA = 5, DB = 6,
- DC = 7, DD = 8, DE = 9, DF = 10,
- XD = 11, XS = 12,
- T8 = 13, P_TA = 14,
- A6 = 15, A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19,
- XOP8 = 20, XOP9 = 21, XOPA = 22
+ OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6
};
-}
-// If rows are added to the opcode extension tables, then corresponding entries
-// must be added here.
-//
-// If the row corresponds to a single byte (i.e., 8f), then add an entry for
-// that byte to ONE_BYTE_EXTENSION_TABLES.
-//
-// If the row corresponds to two bytes where the first is 0f, add an entry for
-// the second byte to TWO_BYTE_EXTENSION_TABLES.
-//
-// If the row corresponds to some other set of bytes, you will need to modify
-// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
-// to the X86 TD files, except in two cases: if the first two bytes of such a
-// new combination are 0f 38 or 0f 3a, you just have to add maps called
-// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
-// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
-// in RecognizableInstr::emitDecodePath().
-
-#define ONE_BYTE_EXTENSION_TABLES \
- EXTENSION_TABLE(80) \
- EXTENSION_TABLE(81) \
- EXTENSION_TABLE(82) \
- EXTENSION_TABLE(83) \
- EXTENSION_TABLE(8f) \
- EXTENSION_TABLE(c0) \
- EXTENSION_TABLE(c1) \
- EXTENSION_TABLE(c6) \
- EXTENSION_TABLE(c7) \
- EXTENSION_TABLE(d0) \
- EXTENSION_TABLE(d1) \
- EXTENSION_TABLE(d2) \
- EXTENSION_TABLE(d3) \
- EXTENSION_TABLE(f6) \
- EXTENSION_TABLE(f7) \
- EXTENSION_TABLE(fe) \
- EXTENSION_TABLE(ff)
-
-#define TWO_BYTE_EXTENSION_TABLES \
- EXTENSION_TABLE(00) \
- EXTENSION_TABLE(01) \
- EXTENSION_TABLE(0d) \
- EXTENSION_TABLE(18) \
- EXTENSION_TABLE(71) \
- EXTENSION_TABLE(72) \
- EXTENSION_TABLE(73) \
- EXTENSION_TABLE(ae) \
- EXTENSION_TABLE(ba) \
- EXTENSION_TABLE(c7)
-
-#define THREE_BYTE_38_EXTENSION_TABLES \
- EXTENSION_TABLE(F3)
-
-#define XOP9_MAP_EXTENSION_TABLES \
- EXTENSION_TABLE(01) \
- EXTENSION_TABLE(02)
+ enum {
+ PS = 1, PD = 2, XS = 3, XD = 4
+ };
-using namespace X86Disassembler;
+ enum {
+ VEX = 1, XOP = 2, EVEX = 3
+ };
-/// needsModRMForDecode - Indicates whether a particular instruction requires a
-/// ModR/M byte for the instruction to be properly decoded. For example, a
-/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to
-/// 0b11.
-///
-/// @param form - The form of the instruction.
-/// @return - true if the form implies that a ModR/M byte is required, false
-/// otherwise.
-static bool needsModRMForDecode(uint8_t form) {
- if (form == X86Local::MRMDestReg ||
- form == X86Local::MRMDestMem ||
- form == X86Local::MRMSrcReg ||
- form == X86Local::MRMSrcMem ||
- (form >= X86Local::MRM0r && form <= X86Local::MRM7r) ||
- (form >= X86Local::MRM0m && form <= X86Local::MRM7m))
- return true;
- else
- return false;
+ enum {
+ OpSize16 = 1, OpSize32 = 2
+ };
}
+using namespace X86Disassembler;
+
/// isRegFormat - Indicates whether a particular form requires the Mod field of
/// the ModR/M byte to be 0b11.
///
@@ -168,12 +128,10 @@ static bool needsModRMForDecode(uint8_t form) {
/// @return - true if the form implies that Mod must be 0b11, false
/// otherwise.
static bool isRegFormat(uint8_t form) {
- if (form == X86Local::MRMDestReg ||
- form == X86Local::MRMSrcReg ||
- (form >= X86Local::MRM0r && form <= X86Local::MRM7r))
- return true;
- else
- return false;
+ return (form == X86Local::MRMDestReg ||
+ form == X86Local::MRMSrcReg ||
+ form == X86Local::MRMXr ||
+ (form >= X86Local::MRM0r && form <= X86Local::MRM7r));
}
/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
@@ -227,36 +185,32 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
return;
}
- Prefix = byteFromRec(Rec, "Prefix");
+ OpPrefix = byteFromRec(Rec, "OpPrefixBits");
+ OpMap = byteFromRec(Rec, "OpMapBits");
Opcode = byteFromRec(Rec, "Opcode");
Form = byteFromRec(Rec, "FormBits");
- SegOvr = byteFromRec(Rec, "SegOvrBits");
+ Encoding = byteFromRec(Rec, "OpEncBits");
- HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix");
+ OpSize = byteFromRec(Rec, "OpSizeBits");
HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix");
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
- HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix");
- HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix");
- HasVEX_4VOp3Prefix = Rec->getValueAsBit("hasVEX_4VOp3Prefix");
+ HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
+ HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3");
HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix");
HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix");
IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L");
- HasEVEXPrefix = Rec->getValueAsBit("hasEVEXPrefix");
HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");
HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z");
HasEVEX_B = Rec->getValueAsBit("hasEVEX_B");
- HasLockPrefix = Rec->getValueAsBit("hasLockPrefix");
IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly");
+ ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");
Name = Rec->getName();
AsmString = Rec->getValueAsString("AsmString");
Operands = &insn.Operands.OperandList;
- IsSSE = (HasOpSizePrefix && (Name.find("16") == Name.npos)) ||
- (Name.find("CRC32") != Name.npos);
- HasFROperands = hasFROperands();
HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L");
// Check for 64-bit inst which does not require REX
@@ -265,26 +219,27 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
// FIXME: Is there some better way to check for In64BitMode?
std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
- if (Predicates[i]->getName().find("32Bit") != Name.npos) {
+ if (Predicates[i]->getName().find("Not64Bit") != Name.npos ||
+ Predicates[i]->getName().find("In32Bit") != Name.npos) {
Is32Bit = true;
break;
}
- if (Predicates[i]->getName().find("64Bit") != Name.npos) {
+ if (Predicates[i]->getName().find("In64Bit") != Name.npos) {
Is64Bit = true;
break;
}
}
- // FIXME: These instructions aren't marked as 64-bit in any way
- Is64Bit |= Rec->getName() == "JMP64pcrel32" ||
- Rec->getName() == "MASKMOVDQU64" ||
- Rec->getName() == "POPFS64" ||
- Rec->getName() == "POPGS64" ||
- Rec->getName() == "PUSHFS64" ||
- Rec->getName() == "PUSHGS64" ||
- Rec->getName() == "REX64_PREFIX" ||
- Rec->getName().find("MOV64") != Name.npos ||
- Rec->getName().find("PUSH64") != Name.npos ||
- Rec->getName().find("POP64") != Name.npos;
+
+ if (Form == X86Local::Pseudo || (IsCodeGenOnly && !ForceDisassemble)) {
+ ShouldBeEmitted = false;
+ return;
+ }
+
+ // Special case since there is no attribute class for 64-bit and VEX
+ if (Name == "VMASKMOVDQU64") {
+ ShouldBeEmitted = false;
+ return;
+ }
ShouldBeEmitted = true;
}
@@ -299,10 +254,10 @@ void RecognizableInstr::processInstr(DisassemblerTables &tables,
RecognizableInstr recogInstr(tables, insn, uid);
- recogInstr.emitInstructionSpecifier(tables);
-
- if (recogInstr.shouldBeEmitted())
+ if (recogInstr.shouldBeEmitted()) {
+ recogInstr.emitInstructionSpecifier();
recogInstr.emitDecodePath(tables);
+ }
}
#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \
@@ -313,169 +268,171 @@ void RecognizableInstr::processInstr(DisassemblerTables &tables,
InstructionContext RecognizableInstr::insnContext() const {
InstructionContext insnContext;
- if (HasEVEXPrefix) {
+ if (Encoding == X86Local::EVEX) {
if (HasVEX_LPrefix && HasEVEX_L2Prefix) {
errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";
llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
}
// VEX_L & VEX_W
if (HasVEX_LPrefix && HasVEX_WPrefix) {
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_L_W_XS);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_L_W_XD);
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = EVEX_KB(IC_EVEX_L_W);
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
} else if (HasVEX_LPrefix) {
// VEX_L
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_L_XS);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_L_XD);
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = EVEX_KB(IC_EVEX_L);
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
}
else if (HasEVEX_L2Prefix && HasVEX_WPrefix) {
// EVEX_L2 & VEX_W
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_L2_W_XS);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_L2_W_XD);
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = EVEX_KB(IC_EVEX_L2_W);
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
} else if (HasEVEX_L2Prefix) {
// EVEX_L2
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_L2_XD);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_L2_XS);
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = EVEX_KB(IC_EVEX_L2);
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
}
else if (HasVEX_WPrefix) {
// VEX_W
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_W_XS);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_W_XD);
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = EVEX_KB(IC_EVEX_W);
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
}
// No L, no W
- else if (HasOpSizePrefix)
+ else if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_OPSIZE);
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = EVEX_KB(IC_EVEX_XD);
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = EVEX_KB(IC_EVEX_XS);
else
insnContext = EVEX_KB(IC_EVEX);
/// eof EVEX
- } else if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix|| HasVEXPrefix) {
+ } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
if (HasVEX_LPrefix && HasVEX_WPrefix) {
- if (HasOpSizePrefix)
+ if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_L_W_OPSIZE;
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = IC_VEX_L_W_XS;
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = IC_VEX_L_W_XD;
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = IC_VEX_L_W;
- } else if (HasOpSizePrefix && HasVEX_LPrefix)
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
+ } else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
insnContext = IC_VEX_L_OPSIZE;
- else if (HasOpSizePrefix && HasVEX_WPrefix)
+ else if (OpPrefix == X86Local::PD && HasVEX_WPrefix)
insnContext = IC_VEX_W_OPSIZE;
- else if (HasOpSizePrefix)
+ else if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_OPSIZE;
- else if (HasVEX_LPrefix &&
- (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
+ else if (HasVEX_LPrefix && OpPrefix == X86Local::XS)
insnContext = IC_VEX_L_XS;
- else if (HasVEX_LPrefix && (Prefix == X86Local::XD ||
- Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD))
+ else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
insnContext = IC_VEX_L_XD;
- else if (HasVEX_WPrefix &&
- (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
+ else if (HasVEX_WPrefix && OpPrefix == X86Local::XS)
insnContext = IC_VEX_W_XS;
- else if (HasVEX_WPrefix && (Prefix == X86Local::XD ||
- Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD))
+ else if (HasVEX_WPrefix && OpPrefix == X86Local::XD)
insnContext = IC_VEX_W_XD;
- else if (HasVEX_WPrefix)
+ else if (HasVEX_WPrefix && OpPrefix == X86Local::PS)
insnContext = IC_VEX_W;
- else if (HasVEX_LPrefix)
+ else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
insnContext = IC_VEX_L;
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = IC_VEX_XD;
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = IC_VEX_XS;
- else
+ else if (OpPrefix == X86Local::PS)
insnContext = IC_VEX;
+ else {
+ errs() << "Instruction does not use a prefix: " << Name << "\n";
+ llvm_unreachable("Invalid prefix");
+ }
} else if (Is64Bit || HasREX_WPrefix) {
- if (HasREX_WPrefix && HasOpSizePrefix)
+ if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
insnContext = IC_64BIT_REXW_OPSIZE;
- else if (HasOpSizePrefix && (Prefix == X86Local::XD ||
- Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD))
+ else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
insnContext = IC_64BIT_XD_OPSIZE;
- else if (HasOpSizePrefix &&
- (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
+ else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
insnContext = IC_64BIT_XS_OPSIZE;
- else if (HasOpSizePrefix)
+ else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
insnContext = IC_64BIT_OPSIZE;
else if (HasAdSizePrefix)
insnContext = IC_64BIT_ADSIZE;
- else if (HasREX_WPrefix &&
- (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
+ else if (HasREX_WPrefix && OpPrefix == X86Local::XS)
insnContext = IC_64BIT_REXW_XS;
- else if (HasREX_WPrefix && (Prefix == X86Local::XD ||
- Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD))
+ else if (HasREX_WPrefix && OpPrefix == X86Local::XD)
insnContext = IC_64BIT_REXW_XD;
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = IC_64BIT_XD;
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
+ else if (OpPrefix == X86Local::XS)
insnContext = IC_64BIT_XS;
else if (HasREX_WPrefix)
insnContext = IC_64BIT_REXW;
else
insnContext = IC_64BIT;
} else {
- if (HasOpSizePrefix && (Prefix == X86Local::XD ||
- Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD))
+ if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
insnContext = IC_XD_OPSIZE;
- else if (HasOpSizePrefix &&
- (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
+ else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
insnContext = IC_XS_OPSIZE;
- else if (HasOpSizePrefix)
+ else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
insnContext = IC_OPSIZE;
else if (HasAdSizePrefix)
insnContext = IC_ADSIZE;
- else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
- Prefix == X86Local::TAXD)
+ else if (OpPrefix == X86Local::XD)
insnContext = IC_XD;
- else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS ||
- Prefix == X86Local::REP)
+ else if (OpPrefix == X86Local::XS)
insnContext = IC_XS;
else
insnContext = IC;
@@ -484,89 +441,13 @@ InstructionContext RecognizableInstr::insnContext() const {
return insnContext;
}
-RecognizableInstr::filter_ret RecognizableInstr::filter() const {
- ///////////////////
- // FILTER_STRONG
- //
-
- // Filter out intrinsics
-
- assert(Rec->isSubClassOf("X86Inst") && "Can only filter X86 instructions");
-
- if (Form == X86Local::Pseudo ||
- (IsCodeGenOnly && Name.find("_REV") == Name.npos &&
- Name.find("INC32") == Name.npos && Name.find("DEC32") == Name.npos))
- return FILTER_STRONG;
-
-
- // Filter out artificial instructions but leave in the LOCK_PREFIX so it is
- // printed as a separate "instruction".
-
- if (Name.find("_Int") != Name.npos ||
- Name.find("Int_") != Name.npos)
- return FILTER_STRONG;
-
- // Filter out instructions with segment override prefixes.
- // They're too messy to handle now and we'll special case them if needed.
-
- if (SegOvr)
- return FILTER_STRONG;
-
-
- /////////////////
- // FILTER_WEAK
- //
-
-
- // Filter out instructions with a LOCK prefix;
- // prefer forms that do not have the prefix
- if (HasLockPrefix)
- return FILTER_WEAK;
-
- // Filter out alternate forms of AVX instructions
- if (Name.find("_alt") != Name.npos ||
- (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos && Name.find("r64r8") == Name.npos) ||
- Name.find("_64mr") != Name.npos ||
- Name.find("rr64") != Name.npos)
- return FILTER_WEAK;
-
- // Special cases.
-
- if (Name == "PUSH64i16" ||
- Name == "MOVPQI2QImr" ||
- Name == "VMOVPQI2QImr" ||
- Name == "VMASKMOVDQU64")
- return FILTER_WEAK;
-
- // XACQUIRE and XRELEASE reuse REPNE and REP respectively.
- // For now, just prefer the REP versions.
- if (Name == "XACQUIRE_PREFIX" ||
- Name == "XRELEASE_PREFIX")
- return FILTER_WEAK;
-
- return FILTER_NORMAL;
-}
-
-bool RecognizableInstr::hasFROperands() const {
- const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
- unsigned numOperands = OperandList.size();
-
- for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
- const std::string &recName = OperandList[operandIndex].Rec->getName();
-
- if (recName.find("FR") != recName.npos)
- return true;
- }
- return false;
-}
-
void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
unsigned &physicalOperandIndex,
unsigned &numPhysicalOperands,
const unsigned *operandMapping,
OperandEncoding (*encodingFromString)
(const std::string&,
- bool hasOpSizePrefix)) {
+ uint8_t OpSize)) {
if (optional) {
if (physicalOperandIndex >= numPhysicalOperands)
return;
@@ -584,33 +465,17 @@ void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
Spec->operands[operandIndex].encoding = encodingFromString(typeName,
- HasOpSizePrefix);
+ OpSize);
Spec->operands[operandIndex].type = typeFromString(typeName,
- IsSSE,
- HasREX_WPrefix,
- HasOpSizePrefix);
+ HasREX_WPrefix, OpSize);
++operandIndex;
++physicalOperandIndex;
}
-void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
+void RecognizableInstr::emitInstructionSpecifier() {
Spec->name = Name;
- if (!ShouldBeEmitted)
- return;
-
- switch (filter()) {
- case FILTER_WEAK:
- Spec->filtered = true;
- break;
- case FILTER_STRONG:
- ShouldBeEmitted = false;
- return;
- case FILTER_NORMAL:
- break;
- }
-
Spec->insnContext = insnContext();
const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
@@ -662,6 +527,17 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
unsigned physicalOperandIndex = 0;
switch (Form) {
+ default: llvm_unreachable("Unhandled form");
+ case X86Local::RawFrmSrc:
+ HANDLE_OPERAND(relocation);
+ return;
+ case X86Local::RawFrmDst:
+ HANDLE_OPERAND(relocation);
+ return;
+ case X86Local::RawFrmDstSrc:
+ HANDLE_OPERAND(relocation);
+ HANDLE_OPERAND(relocation);
+ return;
case X86Local::RawFrm:
// Operand 1 (optional) is an address or immediate.
// Operand 2 (optional) is an immediate.
@@ -670,6 +546,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPTIONAL(relocation)
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::RawFrmMemOffs:
+ // Operand 1 is an address.
+ HANDLE_OPERAND(relocation);
+ break;
case X86Local::AddRegFrm:
// Operand 1 is added to the opcode.
// Operand 2 (optional) is an address.
@@ -683,7 +563,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// Operand 2 is a register operand in the Reg/Opcode field.
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
"Unexpected number of operands for MRMDestRegFrm with VEX_4V");
else
@@ -692,7 +572,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPERAND(rmRegister)
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
@@ -705,7 +585,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// Operand 2 is a register operand in the Reg/Opcode field.
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
"Unexpected number of operands for MRMDestMemFrm with VEX_4V");
else
@@ -716,7 +596,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
if (HasEVEX_K)
HANDLE_OPERAND(writemaskRegister)
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
@@ -731,7 +611,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// Operand 3 (optional) is an immediate.
// Operand 4 (optional) is an immediate.
- if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix)
+ if (HasVEX_4V || HasVEX_4VOp3)
assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
"Unexpected number of operands for MRMSrcRegFrm with VEX_4V");
else
@@ -743,7 +623,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
if (HasEVEX_K)
HANDLE_OPERAND(writemaskRegister)
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
@@ -753,7 +633,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPERAND(rmRegister)
- if (HasVEX_4VOp3Prefix)
+ if (HasVEX_4VOp3)
HANDLE_OPERAND(vvvvRegister)
if (!HasMemOp4Prefix)
@@ -767,7 +647,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix)
+ if (HasVEX_4V || HasVEX_4VOp3)
assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
"Unexpected number of operands for MRMSrcMemFrm with VEX_4V");
else
@@ -779,7 +659,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
if (HasEVEX_K)
HANDLE_OPERAND(writemaskRegister)
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
// FIXME: In AVX, the register below becomes the one encoded
// in ModRMVEX and the one above the one in the VEX.VVVV field
HANDLE_OPERAND(vvvvRegister)
@@ -789,13 +669,14 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPERAND(memory)
- if (HasVEX_4VOp3Prefix)
+ if (HasVEX_4VOp3)
HANDLE_OPERAND(vvvvRegister)
if (!HasMemOp4Prefix)
HANDLE_OPTIONAL(immediate)
HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
break;
+ case X86Local::MRMXr:
case X86Local::MRM0r:
case X86Local::MRM1r:
case X86Local::MRM2r:
@@ -809,11 +690,11 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// Operand 2 (optional) is an immediate or relocation.
// Operand 3 (optional) is an immediate.
unsigned kOp = (HasEVEX_K) ? 1:0;
- unsigned Op4v = (HasVEX_4VPrefix) ? 1:0;
+ unsigned Op4v = (HasVEX_4V) ? 1:0;
if (numPhysicalOperands > 3 + kOp + Op4v)
llvm_unreachable("Unexpected number of operands for MRMnr");
}
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
HANDLE_OPERAND(vvvvRegister)
if (HasEVEX_K)
@@ -822,6 +703,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPTIONAL(relocation)
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::MRMXm:
case X86Local::MRM0m:
case X86Local::MRM1m:
case X86Local::MRM2m:
@@ -834,12 +716,12 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
// Operand 1 is a memory operand (possibly SIB-extended)
// Operand 2 (optional) is an immediate or relocation.
unsigned kOp = (HasEVEX_K) ? 1:0;
- unsigned Op4v = (HasVEX_4VPrefix) ? 1:0;
+ unsigned Op4v = (HasVEX_4V) ? 1:0;
if (numPhysicalOperands < 1 + kOp + Op4v ||
numPhysicalOperands > 2 + kOp + Op4v)
llvm_unreachable("Unexpected number of operands for MRMnm");
}
- if (HasVEX_4VPrefix)
+ if (HasVEX_4V)
HANDLE_OPERAND(vvvvRegister)
if (HasEVEX_K)
HANDLE_OPERAND(writemaskRegister)
@@ -871,7 +753,23 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPERAND(relocation)
}
break;
- case X86Local::MRMInitReg:
+ case X86Local::MRM_C0: case X86Local::MRM_C1: case X86Local::MRM_C2:
+ case X86Local::MRM_C3: case X86Local::MRM_C4: case X86Local::MRM_C8:
+ case X86Local::MRM_C9: case X86Local::MRM_CA: case X86Local::MRM_CB:
+ case X86Local::MRM_D0: case X86Local::MRM_D1: case X86Local::MRM_D4:
+ case X86Local::MRM_D5: case X86Local::MRM_D6: case X86Local::MRM_D8:
+ case X86Local::MRM_D9: case X86Local::MRM_DA: case X86Local::MRM_DB:
+ case X86Local::MRM_DC: case X86Local::MRM_DD: case X86Local::MRM_DE:
+ case X86Local::MRM_DF: case X86Local::MRM_E0: case X86Local::MRM_E1:
+ case X86Local::MRM_E2: case X86Local::MRM_E3: case X86Local::MRM_E4:
+ case X86Local::MRM_E5: case X86Local::MRM_E8: case X86Local::MRM_E9:
+ case X86Local::MRM_EA: case X86Local::MRM_EB: case X86Local::MRM_EC:
+ case X86Local::MRM_ED: case X86Local::MRM_EE: case X86Local::MRM_F0:
+ case X86Local::MRM_F1: case X86Local::MRM_F2: case X86Local::MRM_F3:
+ case X86Local::MRM_F4: case X86Local::MRM_F5: case X86Local::MRM_F6:
+ case X86Local::MRM_F7: case X86Local::MRM_F9: case X86Local::MRM_FA:
+ case X86Local::MRM_FB: case X86Local::MRM_FC: case X86Local::MRM_FD:
+ case X86Local::MRM_FE: case X86Local::MRM_FF:
// Ignored.
break;
}
@@ -893,290 +791,78 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
ModRMFilter* filter = NULL;
uint8_t opcodeToSet = 0;
- switch (Prefix) {
- default: llvm_unreachable("Invalid prefix!");
- // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
- case X86Local::XD:
- case X86Local::XS:
+ switch (OpMap) {
+ default: llvm_unreachable("Invalid map!");
+ case X86Local::OB:
case X86Local::TB:
- opcodeType = TWOBYTE;
-
- switch (Opcode) {
- default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- break;
-#define EXTENSION_TABLE(n) case 0x##n:
- TWO_BYTE_EXTENSION_TABLES
-#undef EXTENSION_TABLE
- switch (Form) {
- default:
- llvm_unreachable("Unhandled two-byte extended opcode");
- case X86Local::MRM0r:
- case X86Local::MRM1r:
- case X86Local::MRM2r:
- case X86Local::MRM3r:
- case X86Local::MRM4r:
- case X86Local::MRM5r:
- case X86Local::MRM6r:
- case X86Local::MRM7r:
- filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
- break;
- case X86Local::MRM0m:
- case X86Local::MRM1m:
- case X86Local::MRM2m:
- case X86Local::MRM3m:
- case X86Local::MRM4m:
- case X86Local::MRM5m:
- case X86Local::MRM6m:
- case X86Local::MRM7m:
- filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
- break;
- MRM_MAPPING
- } // switch (Form)
- break;
- } // switch (Opcode)
- opcodeToSet = Opcode;
- break;
case X86Local::T8:
- case X86Local::T8XD:
- case X86Local::T8XS:
- opcodeType = THREEBYTE_38;
- switch (Opcode) {
- default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- break;
-#define EXTENSION_TABLE(n) case 0x##n:
- THREE_BYTE_38_EXTENSION_TABLES
-#undef EXTENSION_TABLE
- switch (Form) {
- default:
- llvm_unreachable("Unhandled two-byte extended opcode");
- case X86Local::MRM0r:
- case X86Local::MRM1r:
- case X86Local::MRM2r:
- case X86Local::MRM3r:
- case X86Local::MRM4r:
- case X86Local::MRM5r:
- case X86Local::MRM6r:
- case X86Local::MRM7r:
- filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
- break;
- case X86Local::MRM0m:
- case X86Local::MRM1m:
- case X86Local::MRM2m:
- case X86Local::MRM3m:
- case X86Local::MRM4m:
- case X86Local::MRM5m:
- case X86Local::MRM6m:
- case X86Local::MRM7m:
- filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
- break;
- MRM_MAPPING
- } // switch (Form)
- break;
- } // switch (Opcode)
- opcodeToSet = Opcode;
- break;
- case X86Local::P_TA:
- case X86Local::TAXD:
- opcodeType = THREEBYTE_3A;
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- opcodeToSet = Opcode;
- break;
- case X86Local::A6:
- opcodeType = THREEBYTE_A6;
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- opcodeToSet = Opcode;
- break;
- case X86Local::A7:
- opcodeType = THREEBYTE_A7;
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- opcodeToSet = Opcode;
- break;
+ case X86Local::TA:
case X86Local::XOP8:
- opcodeType = XOP8_MAP;
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- opcodeToSet = Opcode;
- break;
case X86Local::XOP9:
- opcodeType = XOP9_MAP;
- switch (Opcode) {
+ case X86Local::XOPA:
+ switch (OpMap) {
+ default: llvm_unreachable("Unexpected map!");
+ case X86Local::OB: opcodeType = ONEBYTE; break;
+ case X86Local::TB: opcodeType = TWOBYTE; break;
+ case X86Local::T8: opcodeType = THREEBYTE_38; break;
+ case X86Local::TA: opcodeType = THREEBYTE_3A; break;
+ case X86Local::XOP8: opcodeType = XOP8_MAP; break;
+ case X86Local::XOP9: opcodeType = XOP9_MAP; break;
+ case X86Local::XOPA: opcodeType = XOPA_MAP; break;
+ }
+
+ switch (Form) {
default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- break;
-#define EXTENSION_TABLE(n) case 0x##n:
- XOP9_MAP_EXTENSION_TABLES
-#undef EXTENSION_TABLE
- switch (Form) {
- default:
- llvm_unreachable("Unhandled XOP9 extended opcode");
- case X86Local::MRM0r:
- case X86Local::MRM1r:
- case X86Local::MRM2r:
- case X86Local::MRM3r:
- case X86Local::MRM4r:
- case X86Local::MRM5r:
- case X86Local::MRM6r:
- case X86Local::MRM7r:
- filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
- break;
- case X86Local::MRM0m:
- case X86Local::MRM1m:
- case X86Local::MRM2m:
- case X86Local::MRM3m:
- case X86Local::MRM4m:
- case X86Local::MRM5m:
- case X86Local::MRM6m:
- case X86Local::MRM7m:
- filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
- break;
- MRM_MAPPING
- } // switch (Form)
+ filter = new DumbFilter();
break;
- } // switch (Opcode)
- opcodeToSet = Opcode;
- break;
- case X86Local::XOPA:
- opcodeType = XOPA_MAP;
- if (needsModRMForDecode(Form))
+ case X86Local::MRMDestReg: case X86Local::MRMDestMem:
+ case X86Local::MRMSrcReg: case X86Local::MRMSrcMem:
+ case X86Local::MRMXr: case X86Local::MRMXm:
filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
- opcodeToSet = Opcode;
- break;
- case X86Local::D8:
- case X86Local::D9:
- case X86Local::DA:
- case X86Local::DB:
- case X86Local::DC:
- case X86Local::DD:
- case X86Local::DE:
- case X86Local::DF:
- assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
- opcodeType = ONEBYTE;
- if (Form == X86Local::AddRegFrm) {
- Spec->modifierType = MODIFIER_MODRM;
- Spec->modifierBase = Opcode;
- filter = new AddRegEscapeFilter(Opcode);
- } else {
- filter = new EscapeFilter(true, Opcode);
- }
- opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
- break;
- case X86Local::REP:
- case 0:
- opcodeType = ONEBYTE;
- switch (Opcode) {
-#define EXTENSION_TABLE(n) case 0x##n:
- ONE_BYTE_EXTENSION_TABLES
-#undef EXTENSION_TABLE
- switch (Form) {
- default:
- llvm_unreachable("Fell through the cracks of a single-byte "
- "extended opcode");
- case X86Local::MRM0r:
- case X86Local::MRM1r:
- case X86Local::MRM2r:
- case X86Local::MRM3r:
- case X86Local::MRM4r:
- case X86Local::MRM5r:
- case X86Local::MRM6r:
- case X86Local::MRM7r:
- filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
- break;
- case X86Local::MRM0m:
- case X86Local::MRM1m:
- case X86Local::MRM2m:
- case X86Local::MRM3m:
- case X86Local::MRM4m:
- case X86Local::MRM5m:
- case X86Local::MRM6m:
- case X86Local::MRM7m:
- filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
- break;
- MRM_MAPPING
- } // switch (Form)
break;
- case 0xd8:
- case 0xd9:
- case 0xda:
- case 0xdb:
- case 0xdc:
- case 0xdd:
- case 0xde:
- case 0xdf:
- filter = new EscapeFilter(false, Form - X86Local::MRM0m);
+ case X86Local::MRM0r: case X86Local::MRM1r:
+ case X86Local::MRM2r: case X86Local::MRM3r:
+ case X86Local::MRM4r: case X86Local::MRM5r:
+ case X86Local::MRM6r: case X86Local::MRM7r:
+ filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
break;
- default:
- if (needsModRMForDecode(Form))
- filter = new ModFilter(isRegFormat(Form));
- else
- filter = new DumbFilter();
+ case X86Local::MRM0m: case X86Local::MRM1m:
+ case X86Local::MRM2m: case X86Local::MRM3m:
+ case X86Local::MRM4m: case X86Local::MRM5m:
+ case X86Local::MRM6m: case X86Local::MRM7m:
+ filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
break;
- } // switch (Opcode)
+ MRM_MAPPING
+ } // switch (Form)
+
opcodeToSet = Opcode;
- } // switch (Prefix)
+ break;
+ } // switch (OpMap)
assert(opcodeType != (OpcodeType)-1 &&
"Opcode type not set");
assert(filter && "Filter not set");
if (Form == X86Local::AddRegFrm) {
- if(Spec->modifierType != MODIFIER_MODRM) {
- assert(opcodeToSet < 0xf9 &&
- "Not enough room for all ADDREG_FRM operands");
-
- uint8_t currentOpcode;
-
- for (currentOpcode = opcodeToSet;
- currentOpcode < opcodeToSet + 8;
- ++currentOpcode)
- tables.setTableFields(opcodeType,
- insnContext(),
- currentOpcode,
- *filter,
- UID, Is32Bit, IgnoresVEX_L);
-
- Spec->modifierType = MODIFIER_OPCODE;
- Spec->modifierBase = opcodeToSet;
- } else {
- // modifierBase was set where MODIFIER_MODRM was set
+ assert(((opcodeToSet & 7) == 0) &&
+ "ADDREG_FRM opcode not aligned");
+
+ uint8_t currentOpcode;
+
+ for (currentOpcode = opcodeToSet;
+ currentOpcode < opcodeToSet + 8;
+ ++currentOpcode)
tables.setTableFields(opcodeType,
insnContext(),
- opcodeToSet,
+ currentOpcode,
*filter,
UID, Is32Bit, IgnoresVEX_L);
- }
} else {
tables.setTableFields(opcodeType,
insnContext(),
opcodeToSet,
*filter,
UID, Is32Bit, IgnoresVEX_L);
-
- Spec->modifierType = MODIFIER_NONE;
- Spec->modifierBase = opcodeToSet;
}
delete filter;
@@ -1186,36 +872,32 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
#define TYPE(str, type) if (s == str) return type;
OperandType RecognizableInstr::typeFromString(const std::string &s,
- bool isSSE,
bool hasREX_WPrefix,
- bool hasOpSizePrefix) {
- if (isSSE) {
- // For SSE instructions, we ignore the OpSize prefix and force operand
- // sizes.
- TYPE("GR16", TYPE_R16)
- TYPE("GR32", TYPE_R32)
- TYPE("GR64", TYPE_R64)
- }
+ uint8_t OpSize) {
if(hasREX_WPrefix) {
// For instructions with a REX_W prefix, a declared 32-bit register encoding
// is special.
TYPE("GR32", TYPE_R32)
}
- if(!hasOpSizePrefix) {
- // For instructions without an OpSize prefix, a declared 16-bit register or
+ if(OpSize == X86Local::OpSize16) {
+ // For OpSize16 instructions, a declared 16-bit register or
+ // immediate encoding is special.
+ TYPE("GR16", TYPE_Rv)
+ TYPE("i16imm", TYPE_IMMv)
+ } else if(OpSize == X86Local::OpSize32) {
+ // For OpSize32 instructions, a declared 32-bit register or
// immediate encoding is special.
- TYPE("GR16", TYPE_R16)
- TYPE("i16imm", TYPE_IMM16)
+ TYPE("GR32", TYPE_Rv)
}
TYPE("i16mem", TYPE_Mv)
- TYPE("i16imm", TYPE_IMMv)
+ TYPE("i16imm", TYPE_IMM16)
TYPE("i16i8imm", TYPE_IMMv)
- TYPE("GR16", TYPE_Rv)
+ TYPE("GR16", TYPE_R16)
TYPE("i32mem", TYPE_Mv)
TYPE("i32imm", TYPE_IMMv)
TYPE("i32i8imm", TYPE_IMM32)
TYPE("u32u8imm", TYPE_IMM32)
- TYPE("GR32", TYPE_Rv)
+ TYPE("GR32", TYPE_R32)
TYPE("GR32orGR64", TYPE_R32)
TYPE("i64mem", TYPE_Mv)
TYPE("i64i32imm", TYPE_IMM64)
@@ -1246,6 +928,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("i32imm_pcrel", TYPE_REL32)
TYPE("SSECC", TYPE_IMM3)
TYPE("AVXCC", TYPE_IMM5)
+ TYPE("AVX512RC", TYPE_IMM32)
TYPE("brtarget", TYPE_RELv)
TYPE("uncondbrtarget", TYPE_RELv)
TYPE("brtarget8", TYPE_REL8)
@@ -1262,6 +945,14 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("SEGMENT_REG", TYPE_SEGMENTREG)
TYPE("DEBUG_REG", TYPE_DEBUGREG)
TYPE("CONTROL_REG", TYPE_CONTROLREG)
+ TYPE("srcidx8", TYPE_SRCIDX8)
+ TYPE("srcidx16", TYPE_SRCIDX16)
+ TYPE("srcidx32", TYPE_SRCIDX32)
+ TYPE("srcidx64", TYPE_SRCIDX64)
+ TYPE("dstidx8", TYPE_DSTIDX8)
+ TYPE("dstidx16", TYPE_DSTIDX16)
+ TYPE("dstidx32", TYPE_DSTIDX32)
+ TYPE("dstidx64", TYPE_DSTIDX64)
TYPE("offset8", TYPE_MOFFS8)
TYPE("offset16", TYPE_MOFFS16)
TYPE("offset32", TYPE_MOFFS32)
@@ -1269,6 +960,8 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("VR256", TYPE_XMM256)
TYPE("VR256X", TYPE_XMM256)
TYPE("VR512", TYPE_XMM512)
+ TYPE("VK1", TYPE_VK1)
+ TYPE("VK1WM", TYPE_VK1)
TYPE("VK8", TYPE_VK8)
TYPE("VK8WM", TYPE_VK8)
TYPE("VK16", TYPE_VK16)
@@ -1289,10 +982,10 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
#undef TYPE
#define ENCODING(str, encoding) if (s == str) return encoding;
-OperandEncoding RecognizableInstr::immediateEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
- if(!hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::immediateEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
+ if(OpSize != X86Local::OpSize16) {
// For instructions without an OpSize prefix, a declared 16-bit register or
// immediate encoding is special.
ENCODING("i16imm", ENCODING_IW)
@@ -1301,6 +994,7 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
ENCODING("u32u8imm", ENCODING_IB)
ENCODING("SSECC", ENCODING_IB)
ENCODING("AVXCC", ENCODING_IB)
+ ENCODING("AVX512RC", ENCODING_IB)
ENCODING("i16imm", ENCODING_Iv)
ENCODING("i16i8imm", ENCODING_IB)
ENCODING("i32imm", ENCODING_Iv)
@@ -1322,9 +1016,10 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
llvm_unreachable("Unhandled immediate encoding");
}
-OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
+ ENCODING("RST", ENCODING_FP)
ENCODING("GR16", ENCODING_RM)
ENCODING("GR32", ENCODING_RM)
ENCODING("GR32orGR64", ENCODING_RM)
@@ -1340,15 +1035,16 @@ OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
ENCODING("VR256", ENCODING_RM)
ENCODING("VR256X", ENCODING_RM)
ENCODING("VR512", ENCODING_RM)
+ ENCODING("VK1", ENCODING_RM)
ENCODING("VK8", ENCODING_RM)
ENCODING("VK16", ENCODING_RM)
errs() << "Unhandled R/M register encoding " << s << "\n";
llvm_unreachable("Unhandled R/M register encoding");
}
-OperandEncoding RecognizableInstr::roRegisterEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::roRegisterEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
ENCODING("GR16", ENCODING_REG)
ENCODING("GR32", ENCODING_REG)
ENCODING("GR32orGR64", ENCODING_REG)
@@ -1367,17 +1063,19 @@ OperandEncoding RecognizableInstr::roRegisterEncodingFromString
ENCODING("FR64X", ENCODING_REG)
ENCODING("FR32X", ENCODING_REG)
ENCODING("VR512", ENCODING_REG)
+ ENCODING("VK1", ENCODING_REG)
ENCODING("VK8", ENCODING_REG)
ENCODING("VK16", ENCODING_REG)
+ ENCODING("VK1WM", ENCODING_REG)
ENCODING("VK8WM", ENCODING_REG)
ENCODING("VK16WM", ENCODING_REG)
errs() << "Unhandled reg/opcode register encoding " << s << "\n";
llvm_unreachable("Unhandled reg/opcode register encoding");
}
-OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
ENCODING("GR32", ENCODING_VVVV)
ENCODING("GR64", ENCODING_VVVV)
ENCODING("FR32", ENCODING_VVVV)
@@ -1389,24 +1087,26 @@ OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString
ENCODING("VR128X", ENCODING_VVVV)
ENCODING("VR256X", ENCODING_VVVV)
ENCODING("VR512", ENCODING_VVVV)
+ ENCODING("VK1", ENCODING_VVVV)
ENCODING("VK8", ENCODING_VVVV)
ENCODING("VK16", ENCODING_VVVV)
errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
llvm_unreachable("Unhandled VEX.vvvv register encoding");
}
-OperandEncoding RecognizableInstr::writemaskRegisterEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
+ ENCODING("VK1WM", ENCODING_WRITEMASK)
ENCODING("VK8WM", ENCODING_WRITEMASK)
ENCODING("VK16WM", ENCODING_WRITEMASK)
errs() << "Unhandled mask register encoding " << s << "\n";
llvm_unreachable("Unhandled mask register encoding");
}
-OperandEncoding RecognizableInstr::memoryEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::memoryEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
ENCODING("i16mem", ENCODING_RM)
ENCODING("i32mem", ENCODING_RM)
ENCODING("i64mem", ENCODING_RM)
@@ -1440,10 +1140,10 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
llvm_unreachable("Unhandled memory encoding");
}
-OperandEncoding RecognizableInstr::relocationEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
- if(!hasOpSizePrefix) {
+OperandEncoding
+RecognizableInstr::relocationEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
+ if(OpSize != X86Local::OpSize16) {
// For instructions without an OpSize prefix, a declared 16-bit register or
// immediate encoding is special.
ENCODING("i16imm", ENCODING_IW)
@@ -1465,14 +1165,21 @@ OperandEncoding RecognizableInstr::relocationEncodingFromString
ENCODING("offset16", ENCODING_Ia)
ENCODING("offset32", ENCODING_Ia)
ENCODING("offset64", ENCODING_Ia)
+ ENCODING("srcidx8", ENCODING_SI)
+ ENCODING("srcidx16", ENCODING_SI)
+ ENCODING("srcidx32", ENCODING_SI)
+ ENCODING("srcidx64", ENCODING_SI)
+ ENCODING("dstidx8", ENCODING_DI)
+ ENCODING("dstidx16", ENCODING_DI)
+ ENCODING("dstidx32", ENCODING_DI)
+ ENCODING("dstidx64", ENCODING_DI)
errs() << "Unhandled relocation encoding " << s << "\n";
llvm_unreachable("Unhandled relocation encoding");
}
-OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
- (const std::string &s,
- bool hasOpSizePrefix) {
- ENCODING("RST", ENCODING_I)
+OperandEncoding
+RecognizableInstr::opcodeModifierEncodingFromString(const std::string &s,
+ uint8_t OpSize) {
ENCODING("GR32", ENCODING_Rv)
ENCODING("GR64", ENCODING_RO)
ENCODING("GR16", ENCODING_Rv)
diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h
index 4d4686e..77286bc 100644
--- a/utils/TableGen/X86RecognizableInstr.h
+++ b/utils/TableGen/X86RecognizableInstr.h
@@ -37,27 +37,27 @@ private:
InstrUID UID;
/// The record from the .td files corresponding to this instruction
const Record* Rec;
- /// The prefix field from the record
- uint8_t Prefix;
+ /// The OpPrefix field from the record
+ uint8_t OpPrefix;
+ /// The OpMap field from the record
+ uint8_t OpMap;
/// The opcode field from the record; this is the opcode used in the Intel
/// encoding and therefore distinct from the UID
uint8_t Opcode;
/// The form field from the record
uint8_t Form;
- /// The segment override field from the record
- uint8_t SegOvr;
- /// The hasOpSizePrefix field from the record
- bool HasOpSizePrefix;
+ // The encoding field from the record
+ uint8_t Encoding;
+ /// The OpSize field from the record
+ uint8_t OpSize;
/// The hasAdSizePrefix field from the record
bool HasAdSizePrefix;
/// The hasREX_WPrefix field from the record
bool HasREX_WPrefix;
- /// The hasVEXPrefix field from the record
- bool HasVEXPrefix;
- /// The hasVEX_4VPrefix field from the record
- bool HasVEX_4VPrefix;
- /// The hasVEX_4VOp3Prefix field from the record
- bool HasVEX_4VOp3Prefix;
+ /// The hasVEX_4V field from the record
+ bool HasVEX_4V;
+ /// The hasVEX_4VOp3 field from the record
+ bool HasVEX_4VOp3;
/// The hasVEX_WPrefix field from the record
bool HasVEX_WPrefix;
/// Inferred from the operands; indicates whether the L bit in the VEX prefix is set
@@ -66,8 +66,6 @@ private:
bool HasMemOp4Prefix;
/// The ignoreVEX_L field from the record
bool IgnoresVEX_L;
- /// The hasEVEXPrefix field from the record
- bool HasEVEXPrefix;
/// The hasEVEX_L2Prefix field from the record
bool HasEVEX_L2Prefix;
/// The hasEVEX_K field from the record
@@ -76,10 +74,10 @@ private:
bool HasEVEX_KZ;
/// The hasEVEX_B field from the record
bool HasEVEX_B;
- /// The hasLockPrefix field from the record
- bool HasLockPrefix;
- /// The isCodeGenOnly filed from the record
+ /// The isCodeGenOnly field from the record
bool IsCodeGenOnly;
+ /// The ForceDisassemble field from the record
+ bool ForceDisassemble;
// Whether the instruction has the predicate "In64BitMode"
bool Is64Bit;
// Whether the instruction has the predicate "In32BitMode"
@@ -89,12 +87,7 @@ private:
std::string Name;
/// The AT&T AsmString for the instruction
std::string AsmString;
-
- /// Indicates whether the instruction is SSE
- bool IsSSE;
- /// Indicates whether the instruction has FR operands - MOVs with FR operands
- /// are typically ignored
- bool HasFROperands;
+
/// Indicates whether the instruction should be emitted into the decode
/// tables; regardless, it will be emitted into the instruction info table
bool ShouldBeEmitted;
@@ -113,82 +106,53 @@ private:
///
/// @return - The context in which the instruction is valid.
InstructionContext insnContext() const;
-
- enum filter_ret {
- FILTER_STRONG, // instruction has no place in the instruction tables
- FILTER_WEAK, // instruction may conflict, and should be eliminated if
- // it does
- FILTER_NORMAL // instruction should have high priority and generate an
- // error if it conflcits with any other FILTER_NORMAL
- // instruction
- };
-
- /// filter - Determines whether the instruction should be decodable. Some
- /// instructions are pure intrinsics and use unencodable operands; many
- /// synthetic instructions are duplicates of other instructions; other
- /// instructions only differ in the logical way in which they are used, and
- /// have the same decoding. Because these would cause decode conflicts,
- /// they must be filtered out.
- ///
- /// @return - The degree of filtering to be applied (see filter_ret).
- filter_ret filter() const;
-
- /// hasFROperands - Returns true if any operand is a FR operand.
- bool hasFROperands() const;
/// typeFromString - Translates an operand type from the string provided in
/// the LLVM tables to an OperandType for use in the operand specifier.
///
/// @param s - The string, as extracted by calling Rec->getName()
/// on a CodeGenInstruction::OperandInfo.
- /// @param isSSE - Indicates whether the instruction is an SSE
- /// instruction. For SSE instructions, immediates are
- /// fixed-size rather than being affected by the
- /// mandatory OpSize prefix.
/// @param hasREX_WPrefix - Indicates whether the instruction has a REX.W
/// prefix. If it does, 32-bit register operands stay
/// 32-bit regardless of the operand size.
- /// @param hasOpSizePrefix Indicates whether the instruction has an OpSize
- /// prefix. If it does not, then 16-bit register
- /// operands stay 16-bit.
+ /// @param OpSize Indicates the operand size of the instruction.
+ /// If register size does not match OpSize, then
+ /// register sizes keep their size.
/// @return - The operand's type.
- static OperandType typeFromString(const std::string& s,
- bool isSSE,
- bool hasREX_WPrefix,
- bool hasOpSizePrefix);
-
+ static OperandType typeFromString(const std::string& s,
+ bool hasREX_WPrefix, uint8_t OpSize);
+
/// immediateEncodingFromString - Translates an immediate encoding from the
/// string provided in the LLVM tables to an OperandEncoding for use in
/// the operand specifier.
///
- /// @param s - See typeFromString().
- /// @param hasOpSizePrefix - Indicates whether the instruction has an OpSize
- /// prefix. If it does not, then 16-bit immediate
- /// operands stay 16-bit.
- /// @return - The operand's encoding.
+ /// @param s - See typeFromString().
+ /// @param OpSize - Indicates whether this is an OpSize16 instruction.
+ /// If it is not, then 16-bit immediate operands stay 16-bit.
+ /// @return - The operand's encoding.
static OperandEncoding immediateEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
-
+ uint8_t OpSize);
+
/// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
/// handles operands that are in the REG field of the ModR/M byte.
static OperandEncoding rmRegisterEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
-
+ uint8_t OpSize);
+
/// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
/// handles operands that are in the REG field of the ModR/M byte.
static OperandEncoding roRegisterEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
+ uint8_t OpSize);
static OperandEncoding memoryEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
+ uint8_t OpSize);
static OperandEncoding relocationEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
+ uint8_t OpSize);
static OperandEncoding opcodeModifierEncodingFromString(const std::string &s,
- bool hasOpSizePrefix);
+ uint8_t OpSize);
static OperandEncoding vvvvRegisterEncodingFromString(const std::string &s,
- bool HasOpSizePrefix);
+ uint8_t OpSize);
static OperandEncoding writemaskRegisterEncodingFromString(const std::string &s,
- bool HasOpSizePrefix);
-
+ uint8_t OpSize);
+
/// handleOperand - Converts a single operand from the LLVM table format to
/// the emitted table format, handling any duplicate operands it encounters
/// and then one non-duplicate.
@@ -214,8 +178,8 @@ private:
const unsigned *operandMapping,
OperandEncoding (*encodingFromString)
(const std::string&,
- bool hasOpSizePrefix));
-
+ uint8_t OpSize));
+
/// shouldBeEmitted - Returns the shouldBeEmitted field. Although filter()
/// filters out many instructions, at various points in decoding we
/// determine that the instruction should not actually be decodable. In
@@ -232,9 +196,7 @@ private:
/// emitInstructionSpecifier - Loads the instruction specifier for the current
/// instruction into a DisassemblerTables.
///
- /// \param tables The DisassemblerTables to populate with the specifier for
- /// the current instruction.
- void emitInstructionSpecifier(DisassemblerTables &tables);
+ void emitInstructionSpecifier();
/// emitDecodePath - Populates the proper fields in the decode tables
/// corresponding to the decode paths for this instruction.
diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm
index 9e93216..bc609e9 100755
--- a/utils/buildit/build_llvm
+++ b/utils/buildit/build_llvm
@@ -89,6 +89,8 @@ else
LLVM_VERSION="$LLVM_SUBMIT_VERSION-$LLVM_SUBMIT_SUBVERSION"
fi
+SDKROOT_PATH=`xcodebuild -version -sdk $SDKROOT Path`
+
# Figure out how many make processes to run.
SYSCTL=`sysctl -n hw.activecpu`
# sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot.
@@ -109,7 +111,7 @@ COMMON_CONFIGURE_OPTS="\
COMMON_MAKEFLAGS="\
UNIVERSAL=1 \
- UNIVERSAL_SDK_PATH=$SDKROOT \
+ UNIVERSAL_SDK_PATH=$SDKROOT_PATH \
NO_RUNTIME_LIBS=1 \
DISABLE_EDIS=1 \
REQUIRES_RTTI=1 \
@@ -141,7 +143,7 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then
T=`xcrun -sdk $SDKROOT -find ${prog}`
ln -s $T $DIR/bin/$prog
echo '#!/bin/sh' > $P || exit 1
- echo 'exec '$T' -arch armv7 -isysroot '${SDKROOT}' "$@"' >> $P || exit 1
+ echo 'exec '$T' -arch armv7 -isysroot '${SDKROOT_PATH}' "$@"' >> $P || exit 1
chmod a+x $P || exit 1
done
@@ -149,7 +151,7 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then
unset SDKROOT && \
$SRC_DIR/configure $COMMON_CONFIGURE_OPTS \
- --enable-targets=arm \
+ --enable-targets=arm,arm64 \
--host=arm-apple-darwin10 \
--target=arm-apple-darwin10 \
--build=i686-apple-darwin10 \
@@ -171,10 +173,10 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then
else
# not $ARM_HOSTED_BUILD
- export CC=`xcrun -find clang`
- export CXX=`xcrun -find clang++`
-
if [ "$IOS_SIM_BUILD" = yes ]; then
+ export CC=`xcrun -sdk iphonesimulator -find clang`
+ export CXX=`xcrun -sdk iphonesimulator -find clang++`
+
# Use a non-standard "darwin_sim" host triple to trigger a cross-build.
configure_opts="--enable-targets=x86 --host=i686-apple-darwin_sim \
--build=i686-apple-darwin10"
@@ -183,15 +185,18 @@ else
DEPLOYMENT_TARGET=-mios-simulator-version-min=$IPHONEOS_DEPLOYMENT_TARGET"
fi
else
- configure_opts="--enable-targets=arm,x86"
+ export CC=`xcrun -sdk macosx -find clang`
+ export CXX=`xcrun -sdk macosx -find clang++`
+
+ configure_opts="--enable-targets=arm,arm64,x86"
if [ -n "$MACOSX_DEPLOYMENT_TARGET" ]; then
COMMON_MAKEFLAGS="$COMMON_MAKEFLAGS \
DEPLOYMENT_TARGET=-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET"
fi
fi
- if [ $SDKROOT ]; then
- CPPFLAGS="$CPPFLAGS -isysroot $SDKROOT"
+ if [ $SDKROOT_PATH ]; then
+ CPPFLAGS="$CPPFLAGS -isysroot $SDKROOT_PATH"
fi
for host in $HOSTS; do :; done
CPPFLAGS="$CPPFLAGS -arch $host"
diff --git a/utils/count/Makefile b/utils/count/Makefile
index 8de076a..2a955e6 100644
--- a/utils/count/Makefile
+++ b/utils/count/Makefile
@@ -14,7 +14,7 @@ USEDLIBS =
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-# Don't install this utility
-NO_INSTALL = 1
+# FIXME: Don't install this utility
+#NO_INSTALL = 1
include $(LEVEL)/Makefile.common
diff --git a/utils/kate/llvm.xml b/utils/kate/llvm.xml
index dfacfb5..5ba46ee 100644
--- a/utils/kate/llvm.xml
+++ b/utils/kate/llvm.xml
@@ -39,8 +39,6 @@
</list>
<list name="linkage-types">
<item> private </item>
- <item> linker_private </item>
- <item> linker_private_weak </item>
<item> internal </item>
<item> available_externally </item>
<item> linkonce </item>
diff --git a/utils/lit/MANIFEST.in b/utils/lit/MANIFEST.in
index 6491a02..7a732b3 100644
--- a/utils/lit/MANIFEST.in
+++ b/utils/lit/MANIFEST.in
@@ -1,7 +1,9 @@
include TODO lit.py
recursive-include tests *
+recursive-include examples *
global-exclude *pyc
global-exclude *~
prune tests/Output
prune tests/*/Output
prune tests/*/*/Output
+prune tests/*/*/*/Output
diff --git a/utils/lit/README.txt b/utils/lit/README.txt
new file mode 100644
index 0000000..8cf4840
--- /dev/null
+++ b/utils/lit/README.txt
@@ -0,0 +1,8 @@
+===============================
+ lit - A Software Testing Tool
+===============================
+
+lit is a portable tool for executing LLVM and Clang style test suites,
+summarizing their results, and providing indication of failures. lit is designed
+to be a lightweight testing tool with as simple a user interface as possible.
+
diff --git a/utils/lit/lit/Test.py b/utils/lit/lit/Test.py
index b4988f5..e51bf12 100644
--- a/utils/lit/lit/Test.py
+++ b/utils/lit/lit/Test.py
@@ -128,10 +128,11 @@ class TestSuite:
class Test:
"""Test - Information on a single test instance."""
- def __init__(self, suite, path_in_suite, config):
+ def __init__(self, suite, path_in_suite, config, file_path = None):
self.suite = suite
self.path_in_suite = path_in_suite
self.config = config
+ self.file_path = file_path
# A list of conditions under which this test is expected to fail. These
# can optionally be provided by test format handlers, and will be
# honored when the test result is supplied.
@@ -157,6 +158,11 @@ class Test:
def getFullName(self):
return self.suite.config.name + ' :: ' + '/'.join(self.path_in_suite)
+ def getFilePath(self):
+ if self.file_path:
+ return self.file_path
+ return self.getSourcePath()
+
def getSourcePath(self):
return self.suite.getSourcePath(self.path_in_suite)
diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py
index 4a34b77..eb89067 100644
--- a/utils/lit/lit/TestingConfig.py
+++ b/utils/lit/lit/TestingConfig.py
@@ -1,7 +1,7 @@
import os
import sys
-PY2 = sys.version_info[0] < 3
+OldPy = sys.version_info[0] == 2 and sys.version_info[1] < 7
class TestingConfig:
""""
@@ -38,7 +38,7 @@ class TestingConfig:
# The option to preserve TEMP, TMP, and TMPDIR.
# This is intended to check how many temporary files would be generated
# (and be not cleaned up) in automated builders.
- if os.environ.has_key('LIT_PRESERVES_TMP'):
+ if 'LIT_PRESERVES_TMP' in os.environ:
environment.update({
'TEMP' : os.environ.get('TEMP',''),
'TMP' : os.environ.get('TMP',''),
@@ -74,12 +74,14 @@ class TestingConfig:
"""
# Load the config script data.
- f = open(path)
- try:
- data = f.read()
- except:
- litConfig.fatal('unable to load config file: %r' % (path,))
- f.close()
+ data = None
+ if not OldPy:
+ f = open(path)
+ try:
+ data = f.read()
+ except:
+ litConfig.fatal('unable to load config file: %r' % (path,))
+ f.close()
# Execute the config script to initialize the object.
cfg_globals = dict(globals())
@@ -87,10 +89,10 @@ class TestingConfig:
cfg_globals['lit_config'] = litConfig
cfg_globals['__file__'] = path
try:
- if PY2:
- exec("exec data in cfg_globals")
+ if OldPy:
+ execfile(path, cfg_globals)
else:
- exec(data, cfg_globals)
+ exec(compile(data, path, 'exec'), cfg_globals, None)
if litConfig.debug:
litConfig.note('... loaded config %r' % path)
except SystemExit:
diff --git a/utils/lit/lit/__init__.py b/utils/lit/lit/__init__.py
index 3967fdd..46fa82d 100644
--- a/utils/lit/lit/__init__.py
+++ b/utils/lit/lit/__init__.py
@@ -5,7 +5,7 @@ from .main import main
__author__ = 'Daniel Dunbar'
__email__ = 'daniel@zuster.org'
-__versioninfo__ = (0, 3, 0)
+__versioninfo__ = (0, 4, 0)
__version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev'
__all__ = []
diff --git a/utils/lit/lit/formats/googletest.py b/utils/lit/lit/formats/googletest.py
index b77e184..3d14b729 100644
--- a/utils/lit/lit/formats/googletest.py
+++ b/utils/lit/lit/formats/googletest.py
@@ -66,7 +66,7 @@ class GoogleTest(TestFormat):
# Discover the tests in this executable.
for testname in self.getGTestTests(execpath, litConfig, localConfig):
testPath = path_in_suite + (basename, testname)
- yield lit.Test.Test(testSuite, testPath, localConfig)
+ yield lit.Test.Test(testSuite, testPath, localConfig, file_path=execpath)
def getTestsInDirectory(self, testSuite, path_in_suite,
litConfig, localConfig):
diff --git a/utils/lit/lit/main.py b/utils/lit/lit/main.py
index 6f672a0..c59651a 100755
--- a/utils/lit/lit/main.py
+++ b/utils/lit/lit/main.py
@@ -34,6 +34,10 @@ class TestingProgressDisplay(object):
def update(self, test):
self.completed += 1
+
+ if self.opts.incremental:
+ update_incremental_cache(test)
+
if self.progressBar:
self.progressBar.update(float(self.completed)/self.numTests,
test.getFullName())
@@ -108,6 +112,21 @@ def write_test_results(run, lit_config, testing_time, output_path):
finally:
f.close()
+def update_incremental_cache(test):
+ if not test.result.code.isFailure:
+ return
+ fname = test.getFilePath()
+ os.utime(fname, None)
+
+def sort_by_incremental_cache(run):
+ def sortIndex(test):
+ fname = test.getFilePath()
+ try:
+ return -os.path.getmtime(fname)
+ except:
+ return 0
+ run.tests.sort(key = lambda t: sortIndex(t))
+
def main(builtinParameters = {}):
# Use processes by default on Unix platforms.
isWindows = platform.system() == 'Windows'
@@ -117,6 +136,9 @@ def main(builtinParameters = {}):
from optparse import OptionParser, OptionGroup
parser = OptionParser("usage: %prog [options] {file-or-path}")
+ parser.add_option("", "--version", dest="show_version",
+ help="Show version and exit",
+ action="store_true", default=False)
parser.add_option("-j", "--threads", dest="numThreads", metavar="N",
help="Number of testing threads",
type=int, action="store", default=None)
@@ -179,6 +201,10 @@ def main(builtinParameters = {}):
group.add_option("", "--shuffle", dest="shuffle",
help="Run tests in random order",
action="store_true", default=False)
+ group.add_option("-i", "--incremental", dest="incremental",
+ help="Run modified and failing tests first (updates "
+ "mtimes)",
+ action="store_true", default=False)
group.add_option("", "--filter", dest="filter", metavar="REGEX",
help=("Only run tests with paths matching the given "
"regular expression"),
@@ -205,6 +231,10 @@ def main(builtinParameters = {}):
(opts, args) = parser.parse_args()
+ if opts.show_version:
+ print("lit %s" % (lit.__version__,))
+ return
+
if not args:
parser.error('No inputs specified')
@@ -292,6 +322,8 @@ def main(builtinParameters = {}):
# Then select the order.
if opts.shuffle:
random.shuffle(run.tests)
+ elif opts.incremental:
+ sort_by_incremental_cache(run)
else:
run.tests.sort(key = lambda t: t.getFullName())
diff --git a/utils/lit/utils/check-sdist b/utils/lit/utils/check-sdist
index 6186446..743a971 100755
--- a/utils/lit/utils/check-sdist
+++ b/utils/lit/utils/check-sdist
@@ -12,6 +12,7 @@ find . | \
grep -v '^\./dist' | \
grep -v '^\./utils' | \
grep -v '^\./venv' | \
+ grep -v '^\./notes.txt' | \
grep -v '^\./lit.egg-info' | \
grep -v '^\./lit/ExampleTests' | \
grep -v '/Output' | \
diff --git a/utils/llvm-build/llvmbuild/main.py b/utils/llvm-build/llvmbuild/main.py
index eacefdf..6cb5c12 100644
--- a/utils/llvm-build/llvmbuild/main.py
+++ b/utils/llvm-build/llvmbuild/main.py
@@ -573,6 +573,45 @@ set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
f.close()
+ def write_cmake_exports_fragment(self, output_path):
+ """
+ write_cmake_exports_fragment(output_path) -> None
+
+ Generate a CMake fragment which includes LLVMBuild library
+ dependencies expressed similarly to how CMake would write
+ them via install(EXPORT).
+ """
+
+ dependencies = list(self.get_fragment_dependencies())
+
+ # Write out the CMake exports fragment.
+ make_install_dir(os.path.dirname(output_path))
+ f = open(output_path, 'w')
+
+ f.write("""\
+# Explicit library dependency information.
+#
+# The following property assignments tell CMake about link
+# dependencies of libraries imported from LLVM.
+""")
+ for ci in self.ordered_component_infos:
+ # We only write the information for libraries currently.
+ if ci.type_name != 'Library':
+ continue
+
+ # Skip disabled targets.
+ tg = ci.get_parent_target_group()
+ if tg and not tg.enabled:
+ continue
+
+ f.write("""\
+set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
+ ci.get_prefixed_library_name(), " ".join(sorted(
+ dep.get_prefixed_library_name()
+ for dep in self.get_required_libraries_for_component(ci)))))
+
+ f.close()
+
def write_make_fragment(self, output_path):
"""
write_make_fragment(output_path) -> None
@@ -780,6 +819,10 @@ def main():
dest="write_cmake_fragment", metavar="PATH",
help="Write the CMake project information to PATH",
action="store", default=None)
+ group.add_option("", "--write-cmake-exports-fragment",
+ dest="write_cmake_exports_fragment", metavar="PATH",
+ help="Write the CMake exports information to PATH",
+ action="store", default=None)
group.add_option("", "--write-make-fragment",
dest="write_make_fragment", metavar="PATH",
help="Write the Makefile project information to PATH",
@@ -861,6 +904,8 @@ given by --build-root) at the same SUBPATH""",
# Write out the cmake fragment, if requested.
if opts.write_cmake_fragment:
project_info.write_cmake_fragment(opts.write_cmake_fragment)
+ if opts.write_cmake_exports_fragment:
+ project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment)
# Configure target definition files, if requested.
if opts.configure_target_def_files:
diff --git a/utils/llvm-lit/CMakeLists.txt b/utils/llvm-lit/CMakeLists.txt
index b535eae..4b10354 100644
--- a/utils/llvm-lit/CMakeLists.txt
+++ b/utils/llvm-lit/CMakeLists.txt
@@ -1,4 +1,21 @@
-configure_file(
- llvm-lit.in
- ${LLVM_TOOLS_BINARY_DIR}/llvm-lit
- )
+if (WIN32 AND NOT CYGWIN)
+ # llvm-lit needs suffix.py for multiprocess to find a main module.
+ set(suffix .py)
+endif ()
+set(llvm_lit_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-lit${suffix})
+
+if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
+ foreach(BUILD_MODE ${CMAKE_CONFIGURATION_TYPES})
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${BUILD_MODE} bi ${llvm_lit_path})
+ configure_file(
+ llvm-lit.in
+ ${bi}
+ )
+ endforeach()
+else()
+ set(BUILD_MODE .)
+ configure_file(
+ llvm-lit.in
+ ${llvm_lit_path}
+ )
+endif()
diff --git a/utils/llvm-lit/Makefile b/utils/llvm-lit/Makefile
index 77021bb..ce1cac9 100644
--- a/utils/llvm-lit/Makefile
+++ b/utils/llvm-lit/Makefile
@@ -11,9 +11,14 @@ LEVEL = ../..
include $(LEVEL)/Makefile.common
-all:: $(ToolDir)/llvm-lit
+# llvm-lit needs suffix.py for multiprocess to find a main module.
+ifeq ($(HOST_OS),MingW)
+ Suffix := .py
+endif
-$(ToolDir)/llvm-lit: llvm-lit.in Makefile $(ToolDir)/.dir
+all:: $(ToolDir)/llvm-lit$(Suffix)
+
+$(ToolDir)/llvm-lit$(Suffix): llvm-lit.in Makefile $(ToolDir)/.dir
$(Echo) "Creating 'llvm-lit' script..."
$(Verb)$(ECHOPATH) s=@LLVM_SOURCE_DIR@=$(LLVM_SRC_ROOT)=g > lit.tmp
$(Verb)$(ECHOPATH) s=@LLVM_BINARY_DIR@=$(LLVM_OBJ_ROOT)=g >> lit.tmp
diff --git a/utils/llvm-lit/llvm-lit.in b/utils/llvm-lit/llvm-lit.in
index 87878d5..a82cbf0 100755
--- a/utils/llvm-lit/llvm-lit.in
+++ b/utils/llvm-lit/llvm-lit.in
@@ -13,8 +13,10 @@ sys.path.insert(0, os.path.join(llvm_source_root, 'utils', 'lit'))
# Set up some builtin parameters, so that by default the LLVM test suite
# configuration file knows how to find the object tree.
builtin_parameters = {
- 'build_mode' : "@CMAKE_CFG_INTDIR@",
- 'llvm_site_config' : os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
+ 'build_mode' : "@BUILD_MODE@",
+ 'llvm_site_config' : os.path.join(llvm_obj_root, 'test', 'lit.site.cfg'),
+ 'llvm_unit_site_config' : os.path.join(llvm_obj_root, 'test', 'Unit',
+ 'lit.site.cfg')
}
clang_obj_root = os.path.join(llvm_obj_root, 'tools', 'clang')
@@ -27,6 +29,16 @@ if os.path.exists(clang_obj_root):
builtin_parameters['clang_tools_extra_site_config'] = \
os.path.join(clang_tools_extra_obj_root, 'test', 'lit.site.cfg')
+lld_obj_root = os.path.join(llvm_obj_root, 'projects', 'lld')
+if os.path.exists(lld_obj_root):
+ builtin_parameters['lld_site_config'] = \
+ os.path.join(lld_obj_root, 'test', 'lit.site.cfg')
+
+compilerrt_obj_root = os.path.join(llvm_obj_root, 'projects', 'compiler-rt')
+if os.path.exists(compilerrt_obj_root):
+ builtin_parameters['compilerrt_site_basedir'] = \
+ os.path.join(compilerrt_obj_root, 'test')
+
if __name__=='__main__':
import lit
lit.main(builtin_parameters)
diff --git a/utils/llvm-native-gcc b/utils/llvm-native-gcc
deleted file mode 100755
index 91a557c..0000000
--- a/utils/llvm-native-gcc
+++ /dev/null
@@ -1,249 +0,0 @@
-#!/usr/bin/perl
-# Wrapper around LLVM tools to generate a native .o from llvm-gcc using an
-# LLVM back-end (CBE by default).
-
-# set up defaults.
-$Verbose = 0;
-$SaveTemps = 1;
-$PreprocessOnly = 0;
-$CompileDontLink = 0;
-$Backend = 'cbe';
-chomp ($ProgramName = `basename $0`);
-
-sub boldprint {
- print "", @_, "";
-}
-
-# process command-line options.
-# most of these are passed on to llvm-gcc.
-$GCCOptions = "";
-for ($i = 0; $i <= $#ARGV; ++$i) {
- if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) {
- $Backend = $1;
- if ($ProgramName =~ /llvm-native-gcc/) {
- splice (@ARGV, $i, 1);
- --$i;
- }
- } elsif ($ARGV[$i] eq "-E") {
- $PreprocessOnly = 1;
- } elsif ($ARGV[$i] eq "-c") {
- $GCCOptions .= " " . $ARGV[$i];
- $CompileDontLink = 1;
- } elsif ($ARGV[$i] eq "-v") {
- $GCCOptions .= " " . $ARGV[$i];
- $Verbose = 1;
- } elsif ($ARGV[$i] eq "-o") {
- $OutputFile = $ARGV[$i + 1];
- } elsif ($ARGV[$i] eq "-save-temps") {
- $GCCOptions .= " " . $ARGV[$i];
- $SaveTemps = 1;
- } elsif ($ARGV[$i] =~ /\.bc$/) {
- push (@BytecodeFiles, $ARGV[$i]);
- } elsif ($ARGV[$i] =~ /^-L/) {
- $GCCOptions .= " " . $ARGV[$i];
- push (@LibDirs, $ARGV[$i]);
- } elsif ($ARGV[$i] =~ /^-l/) {
- $GCCOptions .= " " . $ARGV[$i];
- push (@Libs, $ARGV[$i]);
- } elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) {
- $LastCFile = $ARGV[$i];
- }
-}
-
-sub GetDefaultOutputFileName {
- my $DefaultOutputFileBase;
-
- if ($ProgramName =~ /llvm-native-gcc/) {
- $DefaultOutputFileBase = $LastCFile;
- } elsif ($ProgramName =~ /native-build/) {
- $DefaultOutputFileBase = $BytecodeFiles[0];
- }
-
- my $def = $DefaultOutputFileBase;
-
- die "Can't figure out name of output file.\n"
- unless $DefaultOutputFileBase
- && (($ProgramName !~ /native-build/)
- || $#BytecodeFiles == 0);
-
- print "Warning: defaulting output file name ",
- "based on '$DefaultOutputFileBase'\n" if $Verbose;
-
- if ($ProgramName =~ /llvm-native-gcc/) {
- $def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/;
- } elsif ($ProgramName =~ /native-build/) {
- $def =~ s/\.bc$/.$Backend/;
- if ($CompileDontLink) {
- $def .= ".o";
- }
- }
-
- return $def;
-}
-
-# run a command, optionally echoing, and quitting if it fails:
-sub run {
- my $command = join(" ", @_);
- print "$command\n" if $Verbose;
- $command =~ s/\"/\\\"/g;
- system $command and die "$0: $command failed";
-}
-
-sub LinkBytecodeFilesIntoTemporary {
- my $FinalOutputFileName = shift @_;
- my @BytecodeFiles = @_;
-
- my $BCFiles = join (" ", @BytecodeFiles);
- my $LinkedBCFile;
- if ($SaveTemps) {
- $LinkedBCFile = "${FinalOutputFileName}.llvm.bc";
- } else {
- $LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc";
- }
- run "llvm-link -o $LinkedBCFile $BCFiles";
- return $LinkedBCFile;
-}
-
-sub CompileBytecodeToNative {
- my ($BCFile, $Backend, $OutputFile) = @_;
-
- my $GeneratedCode;
- if ($Backend eq 'cbe') {
- if ($SaveTemps) {
- $GeneratedCode = "${OutputFile}.c";
- } else {
- $GeneratedCode = "/tmp/nativebuild-$$.c";
- }
- run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile";
- } elsif ($Backend eq 'llc') {
- if ($SaveTemps) {
- $GeneratedCode = "${OutputFile}.s";
- } else {
- $GeneratedCode = "/tmp/nativebuild-$$.s";
- }
- run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile";
- }
- my $LibDirs = join (" ", @LibDirs);
- my $Libs = join (" ", @Libs);
- run "gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs";
- run "rm $BCFile $GeneratedCode"
- unless $SaveTemps;
-}
-
-sub CompileCToNative {
- my ($LLVMGCCCommand, $Backend, $OutputFile) = @_;
- run $LLVMGCCCommand;
- if ($PreprocessOnly) {
- return;
- }
- my $BCFile = "${OutputFile}.llvm.bc";
- if ($CompileDontLink) {
- run "mv ${OutputFile} $BCFile";
- } else { # gccld messes with the output file name
- run "mv ${OutputFile}.bc $BCFile";
- }
- my $GeneratedCode;
- if ($Backend eq 'cbe') {
- $GeneratedCode = "${OutputFile}.cbe.c";
- run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile";
- } elsif ($Backend eq 'llc') {
- $GeneratedCode = "${OutputFile}.llc.s";
- run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile";
- }
- my $NativeGCCOptions = "";
- if ($CompileDontLink) {
- $NativeGCCOptions = "-c";
- }
- run "gcc $NativeGCCOptions $GeneratedCode -o $OutputFile";
- run "rm ${OutputFile}.llvm.bc $GeneratedCode"
- unless $SaveTemps;
-}
-
-# guess the name of the output file, if -o was not specified.
-$OutputFile = GetDefaultOutputFileName () unless $OutputFile;
-print "Output file is $OutputFile\n" if $Verbose;
-# do all the dirty work:
-if ($ProgramName eq /native-build/) {
- my $LinkedBCFile = LinkBytecodeFilesIntoTemporary (@BytecodeFiles);
- CompileBytecodeToNative ($LinkedBCFile, $Backend, $OutputFile);
-} elsif ($ProgramName =~ /llvm-native-gcc/) {
- # build the llvm-gcc command line.
- $LLVMGCCCommand = join (" ", ("llvm-gcc", @ARGV));
- CompileCToNative ($LLVMGCCCommand, $Backend, $OutputFile);
-}
-
-# we're done.
-exit 0;
-
-__END__
-
-=pod
-
-=head1 NAME
-
-llvm-native-gcc
-
-=head1 SYNOPSIS
-
-llvm-native-gcc [OPTIONS...] FILE
-
-native-build [OPTIONS...] FILE
-
-=head1 DESCRIPTION
-
-llvm-native-gcc is a wrapper around the LLVM command-line tools which generates
-a native object (.o) file by compiling FILE with llvm-gcc, and then running
-an LLVM back-end (CBE by default) over the resulting bitcode, and then
-compiling the resulting code to a native object file.
-
-If called as "native-build", it compiles bitcode to native code, and takes
-different options.
-
-=head1 OPTIONS
-
-llvm-native-gcc takes the same options as llvm-gcc. All options
-except -mllvm-backend=... are passed on to llvm-gcc.
-
-=over 4
-
-=item -mllvm-backend=BACKEND
-
-Use BACKEND for native code generation.
-
-=item -v
-
-Print command lines that llvm-native-gcc runs.
-
-=item -o FILE
-
-llvm-native-gcc tries to guess the name of the llvm-gcc output file by looking
-for this option in the command line. If it can't find it, it finds the last C
-or C++ source file named on the command line, and turns its suffix into .o. See
-BUGS.
-
-=item -save-temps
-
-Save temporary files used by llvm-native-gcc (and llvm-gcc, and gcc).
-
-=back
-
-=head1 BUGS
-
-llvm-native-gcc only handles the case where llvm-gcc compiles a single
-file per invocation. llvm-native-gcc has weak command-line argument
-parsing and is a poor substitute for making gcc/gcc.c do this stuff.
-
-This manual page does not adequately document native-build mode.
-
-llvm-native-gcc is pretty gross because it represents the blind merging of two
-other scripts that predated it. It could use some code clean-up.
-
-=head1 SEE ALSO
-
-gcc(1)
-
-=head1 AUTHOR
-
-Brian R. Gaeke
-
-=cut
diff --git a/utils/llvm.grm b/utils/llvm.grm
index d65f075..92a4053 100644
--- a/utils/llvm.grm
+++ b/utils/llvm.grm
@@ -92,8 +92,6 @@ GVInternalLinkage
| dllexport
| common
| private
- | "linker_private"
- | "linker_private_weak"
;
GVExternalLinkage
diff --git a/utils/llvm.natvis b/utils/llvm.natvis
index 6b4ef83..9874ce5 100644
--- a/utils/llvm.natvis
+++ b/utils/llvm.natvis
@@ -6,22 +6,10 @@ Put this file into "%USERPROFILE%\Documents\Visual Studio 2012\Visualizers"
or create a symbolic link so it updates automatically.
-->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
- <Type Name="llvm::SmallVector&lt;*,*&gt;">
- <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) == 0">empty</DisplayString>
- <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) != 0">{{ size={($T1*)EndX - ($T1*)BeginX} }}</DisplayString>
- <Expand>
- <Item Name="[size]">($T1*)EndX - ($T1*)BeginX</Item>
- <Item Name="[capacity]">($T1*)CapacityX - ($T1*)BeginX</Item>
- <ArrayItems>
- <Size>($T1*)EndX - ($T1*)BeginX</Size>
- <ValuePointer>($T1*)BeginX</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
<Type Name="llvm::SmallVectorImpl&lt;*&gt;">
<DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) == 0">empty</DisplayString>
- <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) != 0">[{($T1*)EndX - ($T1*)BeginX}]</DisplayString>
+ <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) != 0">{{ size={($T1*)EndX - ($T1*)BeginX} }}</DisplayString>
<Expand>
<Item Name="[size]">($T1*)EndX - ($T1*)BeginX</Item>
<Item Name="[capacity]">($T1*)CapacityX - ($T1*)BeginX</Item>
@@ -46,10 +34,10 @@ or create a symbolic link so it updates automatically.
</Type>
<Type Name="llvm::StringRef">
- <DisplayString>[{Length}] {Data,s}</DisplayString>
- <StringView>Data,s</StringView>
+ <DisplayString>{Data,[Length]s}</DisplayString>
+ <StringView>Data,[Length]s</StringView>
<Expand>
- <Item Name="[length]">Length</Item>
+ <Item Name="[size]">Length</Item>
<ArrayItems>
<Size>Length</Size>
<ValuePointer>Data</ValuePointer>
@@ -58,43 +46,43 @@ or create a symbolic link so it updates automatically.
</Type>
<Type Name="llvm::PointerIntPair&lt;*,*,*,*&gt;">
- <DisplayString>{Value &amp; PointerBitMask} [{(Value &gt;&gt; IntShift) &amp; IntMask}]</DisplayString>
+ <DisplayString>{(void*)(Value &amp; PointerBitMask)} [{($T3)((Value &gt;&gt; IntShift) &amp; IntMask)}]</DisplayString>
<Expand>
- <Item Name="[ptr]">Value &amp; PointerBitMask</Item>
- <Item Name="[int]">(Value &gt;&gt; IntShift) &amp; IntMask</Item>
+ <Item Name="[ptr]">($T1*)(Value &amp; PointerBitMask)</Item>
+ <Item Name="[int]">($T3)((Value &gt;&gt; IntShift) &amp; IntMask)</Item>
</Expand>
</Type>
<Type Name="llvm::PointerUnion&lt;*,*&gt;">
- <DisplayString Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) == 0">[P1] {($T1)(Val.Value &amp; Val.PointerBitMask)}</DisplayString>
- <DisplayString Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) != 0">[P2] {($T2)(Val.Value &amp; Val.PointerBitMask)}</DisplayString>
+ <DisplayString Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) == 0">{"$T1", s8b} {(void*)(Val.Value &amp; Val.PointerBitMask)}</DisplayString>
+ <DisplayString Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) != 0">{"$T2", s8b} {(void*)(Val.Value &amp; Val.PointerBitMask)}</DisplayString>
<Expand>
- <Item Name="[ptr]" Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) == 0">($T1)(Val.Value &amp; Val.PointerBitMask)</Item>
- <Item Name="[ptr]" Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) != 0">($T2)(Val.Value &amp; Val.PointerBitMask)</Item>
+ <ExpandedItem Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) == 0">($T1)(Val.Value &amp; Val.PointerBitMask)</ExpandedItem>
+ <ExpandedItem Condition="((Val.Value &gt;&gt; Val.IntShift) &amp; Val.IntMask) != 0">($T2)(Val.Value &amp; Val.PointerBitMask)</ExpandedItem>
</Expand>
</Type>
<Type Name="llvm::PointerUnion3&lt;*,*,*&gt;">
- <DisplayString Condition="(Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">[P1] {($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
- <DisplayString Condition="(Val.Val.Value &amp; 2) == 2">[P2] {($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
- <DisplayString Condition="(Val.Val.Value &amp; 1) == 1">[P3] {($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">{"$T1", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 2) == 2">{"$T2", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 1) == 1">{"$T3", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
<Expand>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 2) == 2">($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 1) == 1">($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 2) == 2">($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 1) == 1">($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
</Expand>
</Type>
<Type Name="llvm::PointerUnion4&lt;*,*,*,*&gt;">
- <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">[P1] {($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
- <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) == 2">[P2] {($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
- <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 1) == 1">[P3] {($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
- <DisplayString Condition="(Val.Val.Value &amp; 3) == 3">[P4] {($T4)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">{"$T1", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) == 2">{"$T2", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 1) == 1">{"$T3", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value &amp; 3) == 3">{"$T4", s8b} {(void*)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)}</DisplayString>
<Expand>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) == 2">($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 1) == 1">($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
- <Item Name="[ptr]" Condition="(Val.Val.Value &amp; 3) == 3">($T4)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</Item>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) != 2 &amp;&amp; (Val.Val.Value &amp; 1) != 1">($T1)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 2) == 2">($T2)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 3) != 3 &amp;&amp; (Val.Val.Value &amp; 1) == 1">($T3)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
+ <ExpandedItem Condition="(Val.Val.Value &amp; 3) == 3">($T4)((Val.Val.Value &gt;&gt; 2) &lt;&lt; 2)</ExpandedItem>
</Expand>
</Type>
@@ -116,7 +104,7 @@ or create a symbolic link so it updates automatically.
<DisplayString Condition="(Obj != 0) &amp;&amp; (Obj-&gt;ref_cnt != 1)">RefPtr [{Obj-&gt;ref_cnt} refs] {*Obj}</DisplayString>
<Expand>
<Item Condition="Obj != 0" Name="[refs]">Obj-&gt;ref_cnt</Item>
- <Item Condition="Obj != 0" Name="[ptr]">Obj</Item>
+ <ExpandedItem Condition="Obj != 0">Obj</ExpandedItem>
</Expand>
</Type>
@@ -124,29 +112,29 @@ or create a symbolic link so it updates automatically.
<DisplayString Condition="Ptr == 0">empty</DisplayString>
<DisplayString Condition="Ptr != 0">OwningPtr {*Ptr}</DisplayString>
<Expand>
- <Item Condition="Ptr != 0" Name="[ptr]">Ptr</Item>
+ <ExpandedItem Condition="Ptr != 0">Ptr</ExpandedItem>
</Expand>
</Type>
<Type Name="llvm::SmallPtrSet&lt;*,*&gt;">
- <DisplayString Condition="CurArray == SmallArray">{{ [Small Mode] elements={NumElements}, arraySize={CurArraySize} }}</DisplayString>
- <DisplayString Condition="CurArray != SmallArray">{{ [Big Mode] elements={NumElements}, arraySize={CurArraySize} }}</DisplayString>
+ <DisplayString Condition="CurArray == SmallArray">{{ [Small Mode] size={NumElements}, capacity={CurArraySize} }}</DisplayString>
+ <DisplayString Condition="CurArray != SmallArray">{{ [Big Mode] size={NumElements}, capacity={CurArraySize} }}</DisplayString>
<Expand>
- <Item Name="[NumElements]">NumElements</Item>
- <Item Name="[CurArraySize]">CurArraySize</Item>
- <IndexListItems>
- <Size>CurArraySize + 1</Size>
- <ValueNode>($T1*)&amp;CurArray[$i]</ValueNode>
- </IndexListItems>
+ <Item Name="[size]">NumElements</Item>
+ <Item Name="[capacity]">CurArraySize</Item>
+ <ArrayItems>
+ <Size>CurArraySize</Size>
+ <ValuePointer>($T1*)CurArray</ValuePointer>
+ </ArrayItems>
</Expand>
</Type>
<Type Name="llvm::DenseMap&lt;*,*,*&gt;">
<DisplayString Condition="NumEntries == 0">empty</DisplayString>
- <DisplayString Condition="NumEntries != 0">{{ entries={NumEntries}, buckets={NumBuckets} }}</DisplayString>
+ <DisplayString Condition="NumEntries != 0">{{ size={NumEntries}, buckets={NumBuckets} }}</DisplayString>
<Expand>
- <Item Name="[NumEntries]">NumEntries</Item>
- <Item Name="[NumBuckets]">NumBuckets</Item>
+ <Item Name="[size]">NumEntries</Item>
+ <Item Name="[buckets]">NumBuckets</Item>
<ArrayItems>
<Size>NumBuckets</Size>
<ValuePointer>Buckets</ValuePointer>
@@ -155,22 +143,22 @@ or create a symbolic link so it updates automatically.
</Type>
<Type Name="llvm::StringMap&lt;*,*&gt;">
- <DisplayString>{{ NumBuckets={NumBuckets}, ItemSize={ItemSize} }}</DisplayString>
+ <DisplayString>{{ size={ItemSize}, buckets={NumBuckets} }}</DisplayString>
<Expand>
- <Item Name="[NumBuckets]">NumBuckets</Item>
- <Item Name="[ItemSize]">ItemSize</Item>
- <IndexListItems>
+ <Item Name="[size]">ItemSize</Item>
+ <Item Name="[buckets]">NumBuckets</Item>
+ <ArrayItems>
<Size>NumBuckets</Size>
- <ValueNode>(llvm::StringMapEntry&lt;$T1&gt;*)TheTable[$i]</ValueNode>
- </IndexListItems>
+ <ValuePointer>(MapEntryTy**)TheTable</ValuePointer>
+ </ArrayItems>
</Expand>
</Type>
<Type Name="llvm::StringMapEntry&lt;*&gt;">
<DisplayString Condition="StrLen == 0">empty</DisplayString>
- <DisplayString Condition="StrLen != 0">({((llvm::StringMapEntry&lt;$T1&gt;*)this)+1,s}, {second})</DisplayString>
+ <DisplayString Condition="StrLen != 0">({this+1,s}, {second})</DisplayString>
<Expand>
- <Item Name="[key]">((llvm::StringMapEntry&lt;$T1&gt;*)this)+1,s</Item>
+ <Item Name="[key]">this+1,s</Item>
<Item Name="[value]" Condition="StrLen != 0">second</Item>
</Expand>
</Type>
@@ -178,4 +166,12 @@ or create a symbolic link so it updates automatically.
<Type Name="llvm::Triple">
<DisplayString>{Data}</DisplayString>
</Type>
+
+ <Type Name="llvm::Optional&lt;*&gt;">
+ <DisplayString Condition="!hasVal">empty</DisplayString>
+ <DisplayString Condition="hasVal">{*(($T1 *)(unsigned char *)storage.buffer)}</DisplayString>
+ <Expand>
+ <Item Name="[underlying]" Condition="hasVal">*(($T1 *)(unsigned char *)storage.buffer)</Item>
+ </Expand>
+ </Type>
</AutoVisualizer>
diff --git a/utils/not/CMakeLists.txt b/utils/not/CMakeLists.txt
index 5ff14d6..4a92348 100644
--- a/utils/not/CMakeLists.txt
+++ b/utils/not/CMakeLists.txt
@@ -3,9 +3,3 @@ add_llvm_utility(not
)
target_link_libraries(not LLVMSupport)
-if( MINGW )
- target_link_libraries(not imagehlp psapi shell32)
-endif( MINGW )
-if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
- target_link_libraries(not pthread)
-endif()
diff --git a/utils/not/Makefile b/utils/not/Makefile
index f37f166..26b7450 100644
--- a/utils/not/Makefile
+++ b/utils/not/Makefile
@@ -14,8 +14,8 @@ USEDLIBS = LLVMSupport.a
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-# Don't install this utility
-NO_INSTALL = 1
+# FIXME: Don't install this utility
+#NO_INSTALL = 1
include $(LEVEL)/Makefile.common
diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh
index 91dac4c..f10b822 100755
--- a/utils/release/test-release.sh
+++ b/utils/release/test-release.sh
@@ -234,7 +234,7 @@ function export_sources() {
check_valid_urls
for proj in $projects ; do
- echo "# Exporting $proj $Release-RC$RC sources"
+ echo "# Exporting $proj $Release-$RC sources"
if ! svn export -q $Base_url/$proj/tags/RELEASE_$Release_no_dot/$RC $proj.src ; then
echo "error: failed to export $proj project"
exit 1
diff --git a/utils/test_debuginfo.pl b/utils/test_debuginfo.pl
index a6b6137..aaf90d9 100755
--- a/utils/test_debuginfo.pl
+++ b/utils/test_debuginfo.pl
@@ -71,6 +71,8 @@ system("$my_debugger $debugger_options $debugger_script_file $executable_file >
# validate output.
system("FileCheck", "-input-file", "$output_file", "$testcase_file");
if ($?>>8 == 1) {
+ print "Debugger output was:\n";
+ system("cat", "$output_file");
exit 1;
}
else {
diff --git a/utils/unittest/CMakeLists.txt b/utils/unittest/CMakeLists.txt
index fd1a048..b6d2d6d 100644
--- a/utils/unittest/CMakeLists.txt
+++ b/utils/unittest/CMakeLists.txt
@@ -40,8 +40,9 @@ endif ()
add_llvm_library(gtest
googletest/src/gtest-all.cc
- )
-add_llvm_library(gtest_main
- UnitTestMain/TestMain.cpp
+ LINK_LIBS
+ LLVMSupport # Depends on llvm::raw_ostream
)
+
+add_subdirectory(UnitTestMain)
diff --git a/utils/unittest/UnitTestMain/CMakeLists.txt b/utils/unittest/UnitTestMain/CMakeLists.txt
new file mode 100644
index 0000000..65ef97b
--- /dev/null
+++ b/utils/unittest/UnitTestMain/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_llvm_library(gtest_main
+ TestMain.cpp
+
+ LINK_LIBS
+ gtest
+ LLVMSupport # Depends on llvm::cl
+ )
diff --git a/utils/unittest/googletest/README.LLVM b/utils/unittest/googletest/README.LLVM
index 1a6f0f5..16bfffd 100644
--- a/utils/unittest/googletest/README.LLVM
+++ b/utils/unittest/googletest/README.LLVM
@@ -16,6 +16,7 @@ $ rm -f src/gtest_main.cc
$ mv COPYING LICENSE.TXT
Modified as follows:
+* Added support for FreeBSD.
* To GTestStreamToHelper in include/gtest/internal/gtest-internal.h,
added the ability to stream with raw_os_ostream.
* To refresh Haiku support in include/gtest/internal/gtest-port.h,
diff --git a/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/utils/unittest/googletest/include/gtest/gtest-typed-test.h
index fe1e83b..6ded1b1 100644
--- a/utils/unittest/googletest/include/gtest/gtest-typed-test.h
+++ b/utils/unittest/googletest/include/gtest/gtest-typed-test.h
@@ -236,6 +236,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
template <typename gtest_TypeParam_> \
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+// Silencing C99 build warnings
+#if 0
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
@@ -243,6 +245,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
+#endif
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/utils/unittest/googletest/include/gtest/internal/gtest-port.h
index 32fd9c6..f5bfd4e 100644
--- a/utils/unittest/googletest/include/gtest/internal/gtest-port.h
+++ b/utils/unittest/googletest/include/gtest/internal/gtest-port.h
@@ -86,6 +86,7 @@
// the given platform; otherwise undefined):
// GTEST_OS_AIX - IBM AIX
// GTEST_OS_CYGWIN - Cygwin
+// GTEST_OS_FREEBSD - FreeBSD
// GTEST_OS_HAIKU - Haiku
// GTEST_OS_HPUX - HP-UX
// GTEST_OS_LINUX - Linux
@@ -228,6 +229,8 @@
# endif // _WIN32_WCE
#elif defined __APPLE__
# define GTEST_OS_MAC 1
+#elif defined __FreeBSD__
+# define GTEST_OS_FREEBSD 1
#elif defined __linux__
# define GTEST_OS_LINUX 1
# if defined(ANDROID) || defined(__ANDROID__)
@@ -421,7 +424,8 @@
//
// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
// to your compiler flags.
-# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX)
+# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || \
+ GTEST_OS_HPUX || GTEST_OS_FREEBSD)
#endif // GTEST_HAS_PTHREAD
#if GTEST_HAS_PTHREAD
@@ -545,7 +549,8 @@
// pops up a dialog window that cannot be suppressed programmatically.
#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
- GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX)
+ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || \
+ GTEST_OS_HPUX || GTEST_OS_FREEBSD)
# define GTEST_HAS_DEATH_TEST 1
# include <vector> // NOLINT
#endif
diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim
index c2ec57c..2b91823 100644
--- a/utils/vim/llvm.vim
+++ b/utils/vim/llvm.vim
@@ -43,8 +43,7 @@ syn keyword llvmKeyword blockaddress byval c catch cc ccc cleanup coldcc common
syn keyword llvmKeyword constant datalayout declare default define deplibs
syn keyword llvmKeyword dllexport dllimport except extern_weak external fastcc
syn keyword llvmKeyword filter gc global hidden initialexec inlinehint inreg
-syn keyword llvmKeyword intel_ocl_bicc inteldialect internal linker_private
-syn keyword llvmKeyword linker_private_weak
+syn keyword llvmKeyword intel_ocl_bicc inteldialect internal
syn keyword llvmKeyword linkonce linkonce_odr
syn keyword llvmKeyword localdynamic localexec minsize module monotonic
syn keyword llvmKeyword msp430_intrcc naked nest noalias nocapture
diff --git a/utils/wciia.py b/utils/wciia.py
index c838819..eaa232f 100755
--- a/utils/wciia.py
+++ b/utils/wciia.py
@@ -110,7 +110,7 @@ if not os.path.exists(path):
owners_name = find_owners(path)
-# be gramatically correct
+# be grammatically correct
print "The owner(s) of the (" + path + ") is(are) : " + str(owners_name)
exit(0)
diff --git a/utils/yaml-bench/YAMLBench.cpp b/utils/yaml-bench/YAMLBench.cpp
index f335605..3e80f23 100644
--- a/utils/yaml-bench/YAMLBench.cpp
+++ b/utils/yaml-bench/YAMLBench.cpp
@@ -69,7 +69,7 @@ static std::string prettyTag(yaml::Node *N) {
if (StringRef(Tag).startswith("tag:yaml.org,2002:")) {
std::string Ret = "!!";
Ret += StringRef(Tag).substr(18);
- return llvm_move(Ret);
+ return std::move(Ret);
}
std::string Ret = "!<";
Ret += Tag;
@@ -188,7 +188,7 @@ static std::string createJSONText(size_t MemoryMB, unsigned ValueSize) {
int main(int argc, char **argv) {
llvm::cl::ParseCommandLineOptions(argc, argv);
if (Input.getNumOccurrences()) {
- OwningPtr<MemoryBuffer> Buf;
+ std::unique_ptr<MemoryBuffer> Buf;
if (MemoryBuffer::getFileOrSTDIN(Input, Buf))
return 1;